Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add project toml and add uv to build #153

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 10 additions & 31 deletions .github/workflows/build_and_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,13 @@ on:
- created

jobs:
build-n-publish:
name: Build and publish Python distribution to PyPI
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- name: Check out git repository
uses: actions/checkout@v4

- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: 3.13

- name: Install build tools
run: >-
python -m
pip install
wheel
twine
--user

- name: Build a binary wheel and a source tarball
run: >-
python
setup.py
sdist
bdist_wheel

- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
pypi:
name: Build and publish to PyPI
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
- run: uv build
- run: uv publish --trusted-publishing always
24 changes: 24 additions & 0 deletions .github/workflows/check_format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Basic CI setup: Lint format with ruff
name: Format-check

on:
pull_request:
types: [ opened, synchronize, reopened, ready_for_review, labeled, unlabeled ]

jobs:
lint-format:
name: Ruff includes and format
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Ruff check import sorting
uses: astral-sh/ruff-action@v1
with:
args: "check --select I ."

- name: Ruff format diff
uses: astral-sh/ruff-action@v1
with:
args: "format --diff ."

18 changes: 18 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Basic CI setup: Lint with ruff
name: Lint

on:
pull_request:
types: [ opened, synchronize, reopened, ready_for_review, labeled, unlabeled ]

jobs:
lint:
name: Lint
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Ruff lint
uses: astral-sh/ruff-action@v1
with:
args: "check ."
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Try to use the following format:
- Released the constraint on Python 3.8 (collections, pkg_resources to importlib, tests) ([#142](https://github.com/Clinical-Genomics/genmod/pull/142))
- Update annotation examples ([#144](https://github.com/Clinical-Genomics/genmod/pull/144))
- Updated documentation with warning about compounds only being scored within the first family in the VCF ([#151](https://github.com/Clinical-Genomics/genmod/pull/151))
- Use `uv` with `hatchling` to build and publish ([#104](https://github.com/Clinical-Genomics/genmod/issues/143))

## [3.9]
- Fixed wrong models when chromosome X was named `chrX` and not `X` ([#135](https://github.com/Clinical-Genomics/genmod/pull/135))
Expand Down
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
###############################################
# Dockerfile to build GeMod container image
###############################################
FROM ghcr.io/astral-sh/uv:python3.13-alpine

RUN apk update & apk add build-base zlib-dev
# Copy the project into the image
ADD . /app

# Sync the project into a new environment, using the frozen lockfile
WORKDIR /app
RUN uv sync --frozen

ENTRYPOINT ["uv", "run", "genmod"]
19 changes: 5 additions & 14 deletions Dockerfile.pytest
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
# Dockerfile to run genmod pytest suite
FROM python:3.13
FROM ghcr.io/astral-sh/uv:python3.13-bookworm

RUN mkdir -p /genmod
ADD . /app

COPY requirements.txt /genmod/
WORKDIR /app
RUN uv sync --all-extras --dev

RUN pip3 install -r /genmod/requirements.txt

COPY . /genmod

ENV PYTHONPATH=/genmod

WORKDIR /genmod

RUN pip3 install .

ENTRYPOINT ["pytest"]
ENTRYPOINT ["uv", "run", "pytest"]
2 changes: 0 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
include CHANGELOG.md
include LICENSE.txt
include README.md
include requirements.txt

recursive-include examples *.ped *.vcf *.gz *.tbi
recursive-include genmod/annotations *.gz
recursive-include genmod/configs *.ini
recursive-exclude * __pycache__
recursive-exclude * *.py[co]

3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ or

git clone https://github.com/Clinical-Genomics/genmod.git
cd genmod
python setup.py install
uv install genmod
uv run genmod


## Usage
Expand Down
1 change: 0 additions & 1 deletion genmod/__version__.py

This file was deleted.

6 changes: 0 additions & 6 deletions genmod/annotate_models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1 @@
from __future__ import absolute_import

from .make_haploblocks import get_haploblocks
from .genetic_models import check_genetic_models
from .model_score import get_model_score
from .fix_variant import make_print_version
from .variant_annotator import VariantAnnotator
84 changes: 35 additions & 49 deletions genmod/annotate_models/fix_variant.py
Original file line number Diff line number Diff line change
@@ -1,90 +1,76 @@
from . import get_model_score
from .model_score import get_model_score


def make_print_version(variant, families):
"""
Get the variants ready for printing

This function collects the annotations added and merge them in the INFO
dict.

Arguments:
variant (dict): A variant dictionary

"""

variant_id = variant['variant_id']
vcf_info = variant['INFO'].split(';')

feature_list = variant.get('annotation', set())


variant_id = variant["variant_id"]
vcf_info = variant["INFO"].split(";")

# variant[compounds] is a dictionary with family id as keys and a set of compounds as values
compounds = variant.get('compounds', dict())
compounds = variant.get("compounds", dict())
# Here we store the compound strings that should be added to the variant:
family_compound_strings = []

genetic_models = variant.get('inheritance_models', {})
genetic_models = variant.get("inheritance_models", {})

# We need to check if compounds have already been annotated.
if 'Compounds' not in variant['info_dict']:

if "Compounds" not in variant["info_dict"]:
for family_id in compounds:
if (genetic_models[family_id].get('AR_comp') or genetic_models[family_id].get('AR_comp_dn')):
compound_string = ''
if genetic_models[family_id].get("AR_comp") or genetic_models[family_id].get(
"AR_comp_dn"
):
compound_string = ""
compound_set = compounds[family_id]
#We do not want reference to itself as a compound:
# We do not want reference to itself as a compound:
compound_set.discard(variant_id)
# If there are any compounds for the family:
if compounds[family_id]:
compound_string = '|'.join(compound_set)
family_compound_strings.append(':'.join([family_id, compound_string]))
compound_string = "|".join(compound_set)
family_compound_strings.append(":".join([family_id, compound_string]))

if len(family_compound_strings) > 0:
vcf_info.append('Compounds=' + ','.join(family_compound_strings))
vcf_info.append("Compounds=" + ",".join(family_compound_strings))

# Check if any genetic models are followed
if 'GeneticModels' not in variant['info_dict']:
if "GeneticModels" not in variant["info_dict"]:
# Here we store the compound strings that should be added to the variant:
family_model_strings = []
model_scores = {}
for family_id in genetic_models:
model_string = ''
model_string = ""
model_list = []
for model in genetic_models[family_id]:
if genetic_models[family_id][model]:
model_list.append(model)
model_string = '|'.join(model_list)
model_string = "|".join(model_list)
if len(model_list) > 0:
family_model_strings.append(':'.join(
[family_id, model_string]))

family_model_strings.append(":".join([family_id, model_string]))

model_scores[family_id] = str(
get_model_score(families[family_id].individuals, variant))

get_model_score(families[family_id].individuals, variant)
)

if len(family_model_strings) > 0:
vcf_info.append(
'GeneticModels={0}'.format(
','.join(family_model_strings)))
vcf_info.append("GeneticModels={0}".format(",".join(family_model_strings)))

model_score_list = []
for family_id in model_scores:
if model_scores[family_id]:
if float(model_scores[family_id]) > 0:
model_score_list.append(
':'.join(
[
family_id,
model_scores[family_id]
]
)
)
model_score_list.append(":".join([family_id, model_scores[family_id]]))
if len(model_score_list) > 0:
vcf_info.append(
'ModelScore=' +
','.join(model_score_list)
)



variant['INFO'] = ';'.join(vcf_info)
vcf_info.append("ModelScore=" + ",".join(model_score_list))

variant["INFO"] = ";".join(vcf_info)

return variant
Loading
Loading