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

Update package manager to uv, gh-workflow and bugfix #39

Merged
merged 6 commits into from
Dec 16, 2024
Merged
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
37 changes: 20 additions & 17 deletions .github/workflows/openvariant_tester.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,30 @@ jobs:
build:

runs-on: ubuntu-latest
env:
UV_LINK_MODE: copy
RUFF_FORMAT: github

steps:
- uses: actions/checkout@v3
- name: Set up the latest Python
uses: actions/setup-python@v3
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 pytest pytest-cov
pip install -e .
- name: Lint with flake8
python-version-file: "pyproject.toml"

- uses: astral-sh/setup-uv@v4

- name: Lint with Ruff
run: |
# stop the build if there are Python syntax errors or undefined names
# flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
uv sync --extra linting --frozen
uv run ruff check openvariant

- name: Test
run: |
pytest --cov .
uv sync --extra tests --frozen
uv run pytest --cov .

- name: Upload coverage reports to Codecov with GitHub Action
uses: codecov/codecov-action@v3

15 changes: 8 additions & 7 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ version: 2
build:
os: "ubuntu-22.04"
tools:
python: "3.12"
python: "3.10"
apt_packages:
- build-essential
- libzmq3-dev
- gcc
- g++
- python3-dev
commands:
- asdf plugin add uv
- asdf install uv latest
- asdf global uv latest
- uv sync --extra docs --frozen
- uv run -m sphinx -T -b html -d docs/_build/doctrees -D language=en docs $READTHEDOCS_OUTPUT/html

sphinx:
configuration: docs/conf.py

python:
install:
- requirements: requirements-docs.txt
configuration: docs/conf.py
72 changes: 36 additions & 36 deletions openvariant/tasks/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,49 +31,49 @@ def _add_action(name: str) -> None:
init_file.write(f"import .{name} from {context_name}\n")
init_file.close()
with open(f"{path}/{name}/{name}.py", 'w') as plugin_file:
plugin_file.write(f"from openvariant.plugins.context import Context\n")
plugin_file.write(f"from openvariant.plugins.plugin import Plugin\n\n\n")
plugin_file.write("from openvariant.plugins.context import Context\n")
plugin_file.write("from openvariant.plugins.plugin import Plugin\n\n\n")
plugin_file.write(f"class {context_name}(Context):\n")
plugin_file.write(f"\t\"\"\"\n")
plugin_file.write("\t\"\"\"\n")
plugin_file.write(f"\t{context_name} class generated by OpenVariant\n\n")
plugin_file.write(f"\tAttributes\n")
plugin_file.write(f"\t-------\n")
plugin_file.write(f"\trow : dict\n")
plugin_file.write(f"\t\tMain method to execute data transformation in each row.\n")
plugin_file.write(f"\tfield_name : str\n")
plugin_file.write(f"\t\tName of the corresponding column that was described on the annotation schema.\n")
plugin_file.write(f"\tfile_path : str\n")
plugin_file.write(f"\t\tPath of the Input file that is being parsed.\n")
plugin_file.write(f"\t\"\"\"\n\n")
plugin_file.write(f"\tdef __init__(self, row: dict, field_name: str, file_path: str) -> None:\n")
plugin_file.write(f"\t\tsuper().__init__(row, field_name, file_path)\n")
plugin_file.write(f"\n\n")
plugin_file.write("\tAttributes\n")
plugin_file.write("\t-------\n")
plugin_file.write("\trow : dict\n")
plugin_file.write("\t\tMain method to execute data transformation in each row.\n")
plugin_file.write("\tfield_name : str\n")
plugin_file.write("\t\tName of the corresponding column that was described on the annotation schema.\n")
plugin_file.write("\tfile_path : str\n")
plugin_file.write("\t\tPath of the Input file that is being parsed.\n")
plugin_file.write("\t\"\"\"\n\n")
plugin_file.write("\tdef __init__(self, row: dict, field_name: str, file_path: str) -> None:\n")
plugin_file.write("\t\tsuper().__init__(row, field_name, file_path)\n")
plugin_file.write("\n\n")
plugin_file.write(f"class {plugin_name}(Plugin):\n")
plugin_file.write(f"\t\"\"\"\n")
plugin_file.write("\t\"\"\"\n")
plugin_file.write(f"\t{plugin_name} class generated by OpenVariant\n\n")
plugin_file.write(f"\tMethods\n")
plugin_file.write(f"\t-------\n")
plugin_file.write("\tMethods\n")
plugin_file.write("\t-------\n")
plugin_file.write(f"\trun(context: {context_name})\n")
plugin_file.write(f"\t\tMain method to execute data transformation in each row.\n")
plugin_file.write(f"\t\"\"\"\n\n")
plugin_file.write("\t\tMain method to execute data transformation in each row.\n")
plugin_file.write("\t\"\"\"\n\n")
plugin_file.write(f"\tdef run(self, context: {context_name}) -> dict:\n")
plugin_file.write(f"\t\t\"\"\"\n")
plugin_file.write(f"\t\tData transformation of a single row\n\n")
plugin_file.write(f"\t\tParameters\n")
plugin_file.write(f"\t\t-------\n")
plugin_file.write("\t\t\"\"\"\n")
plugin_file.write("\t\tData transformation of a single row\n\n")
plugin_file.write("\t\tParameters\n")
plugin_file.write("\t\t-------\n")
plugin_file.write(f"\t\tcontext : {context_name}\n")
plugin_file.write(f"\t\t\tRepresentation of the row to be parsed.\n")
plugin_file.write(f"\t\t\n")
plugin_file.write(f"\t\tReturns\n")
plugin_file.write(f"\t\t-------\n")
plugin_file.write(f"\t\tfloat or int or str\n")
plugin_file.write(f"\t\t\tThe value of the field transformed.\n")
plugin_file.write(f"\t\t\"\"\"\n")
plugin_file.write(f"\n")
plugin_file.write(f"\t\t# This is an example code, modify if as you wish\n")
plugin_file.write(f"\t\tcontext.row[context.field_name] = \"Hello world! file:\" + context.file_path\n")
plugin_file.write(f"\n")
plugin_file.write(f"\t\treturn context.row[context.field_name]\n")
plugin_file.write("\t\t\tRepresentation of the row to be parsed.\n")
plugin_file.write("\t\t\n")
plugin_file.write("\t\tReturns\n")
plugin_file.write("\t\t-------\n")
plugin_file.write("\t\tfloat or int or str\n")
plugin_file.write("\t\t\tThe value of the field transformed.\n")
plugin_file.write("\t\t\"\"\"\n")
plugin_file.write("\n")
plugin_file.write("\t\t# This is an example code, modify if as you wish\n")
plugin_file.write("\t\tcontext.row[context.field_name] = \"Hello world! file:\" + context.file_path\n")
plugin_file.write("\n")
plugin_file.write("\t\treturn context.row[context.field_name]\n")


class PluginActions(Enum):
Expand Down
11 changes: 8 additions & 3 deletions openvariant/variant/variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,18 @@ def _extract_header(file_path: str, original_header: list, annotation: Annotatio

for field, ann in mapping_fields:
ann_type = ann[0]
header_schema.update({field: AnnotationTypesProcess[ann_type].value(ann, original_header, file_path,
header_schema)})

class_name = ann_type
module_name = "openvariant.annotation.process"
ClassAnnotation = import_class_from_module(module_name, class_name)
instance = ClassAnnotation()

header_schema.update({field: instance(ann, original_header, file_path, header_schema)})
return header_schema, annotation.columns


@lru_cache(maxsize=256)
def _parse_field(value: float or int or str, func: Callable) -> str:
def _parse_field(value: float | int | str, func: Callable) -> str:
"""Getting the value of a specific annotation field. Cached with LRU policy"""
result = func(value)
return result if result is not None else str(float('nan'))
Expand Down
4 changes: 2 additions & 2 deletions openvariant/variant/where.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ def _parse_where(where: str or None) -> List:
WhereAttributesKeys.FIELD.value: wh[0],
WhereAttributesKeys.VALUE.value: wh[2]}
except KeyError:
raise ValueError(f"Unknown \"where\" syntax.")
raise ValueError("Unknown \"where\" syntax.")
else:
raise ValueError(f"Unknown where syntax.")
raise ValueError("Unknown where syntax.")
return [stmt]


Expand Down
142 changes: 142 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
[build-system]
requires = ["hatchling", "setuptools"]
build-backend = "hatchling.build"

[project]
name = "open-variant"
version = "1.0.1"
description = "OpenVariant provides different functionalities to read, parse and operate different multiple input file formats, being able to customize the output."
authors = [
{ name = "BBGLab (Barcelona Biomedical Genomics Lab)", email = "[email protected]" }
]
dependencies = [
"pyyaml==6.0.1",
"tqdm==4.66.3",
"click==8.1.3",
"pyliftover==0.4.1",
"appdirs==1.4.4",
]
readme = "README.md"
requires-python = ">=3.10"
license = { file = "LICENSE" }
keywords = ["bioinformatics", "openvariant", "openvar", "bbglab"]


[project.urls]
Homepage = "https://github.com/bbglab/openvariant"
Documentation = "https://openvariant.readthedocs.io/"
Repository = "https://github.com/bbglab/openvariant"
Issues = "https://github.com/bbglab/openvariant/issues"


[project.scripts]
"openvar" = "openvariant.commands.openvar:openvar"

[project.optional-dependencies]
docs = [
"alabaster==0.7.12",
"asttokens==2.0.5",
"attrs==22.1.0",
"babel==2.10.3",
"backcall==0.2.0",
"beautifulsoup4==4.11.1",
"bleach==5.0.1",
"charset-normalizer==2.1.0",
"click==8.1.3",
"decorator==5.1.1",
"defusedxml==0.7.1",
"docutils==0.17.1",
"entrypoints==0.4",
"executing==0.9.1",
"fastjsonschema==2.16.1",
"idna==3.7",
"imagesize==1.4.1",
"jedi==0.18.1",
"jinja2==3.1.4",
"jsonschema==4.8.0",
"jupyter-client==7.3.4",
"jupyter-core==4.11.2",
"jupyterlab-pygments==0.2.2",
"markupsafe==2.1.1",
"matplotlib-inline==0.1.3",
"nbclient==0.6.6",
"nbformat==5.4.0",
"nbsphinx==0.8.9",
"nest-asyncio==1.5.5",
"open-variant==1.0.0",
"packaging==21.3",
"pandocfilters==1.5.0",
"parso==0.8.3",
"pexpect==4.8.0",
"pickleshare==0.7.5",
"prompt-toolkit==3.0.30",
"ptyprocess==0.7.0",
"pure-eval==0.2.2",
"pydata-sphinx-theme==0.8.1",
"pygments==2.15.0",
"pyparsing==3.0.9",
"pyrsistent==0.18.1",
"python-dateutil==2.8.2",
"pytz==2022.1",
"pyyaml==6.0.1",
"pyzmq==26.2.0",
"requests==2.32.2",
"ruamel-yaml==0.16.13",
"six==1.16.0",
"snowballstemmer==2.2.0",
"soupsieve==2.3.2.post1",
"sphinx-copybutton==0.5.0",
"sphinx==4.5.0",
"sphinx-gallery==0.10.1",
"sphinx-panels==0.6.0",
"sphinxcontrib-applehelp==1.0.2",
"sphinxcontrib-autoyaml==1.0.0",
"sphinxcontrib-devhelp==1.0.2",
"sphinxcontrib-htmlhelp==2.0.0",
"sphinxcontrib-jsmath==1.0.1",
"sphinxcontrib-qthelp==1.0.3",
"sphinxcontrib-serializinghtml==1.1.5",
"stack-data==0.3.0",
"tinycss2==1.1.1",
"tornado==6.4.2",
"tqdm==4.66.3",
"traitlets==5.3.0",
"urllib3==1.26.19",
"wcwidth==0.2.5",
"webencodings==0.5.1",
"ipython>=8.18.0",
"nbconvert==7.0.0rc0",
"mistune==2.0.3",
"sphinxcontrib-bibtex==2.6.3",
"setuptools>=58.2.0",
]
linting = [
"flake8>=7.1.1",
"ruff>=0.8.3",
]
tests = [
"coverage>=7.6.9",
"pytest-cov>=6.0.0",
"pytest>=8.3.4",
]

[tool.hatch.metadata]
allow-direct-references = true

[tool.hatch.build.targets.wheel]
packages = ["openvariant"]

[tool.uv.sources]
open-variant = { workspace = true }

[tool.ruff.lint]
select = ["F"]
ignore = ["F401"]

[tool.ruff]
line-length = 127

[tool.ruff.format]
quote-style = "single"
indent-style = "space"
docstring-code-format = true
Loading
Loading