Skip to content

Commit 6d93d1f

Browse files
committed
feat: add general internal boilerplate/stubs
1 parent 0bde4a8 commit 6d93d1f

File tree

21 files changed

+473
-25
lines changed

21 files changed

+473
-25
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,6 @@ __marimo__/
214214

215215
# Streamlit
216216
.streamlit/secrets.toml
217+
218+
# uv
219+
uv.lock

pyproject.toml

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@ classifiers = [
1717
"Operating System :: OS Independent",
1818
]
1919
dependencies = [
20+
"ga4gh.va_spec",
21+
"biocommons.anyvar@git+https://github.com/biocommons/anyvar.git@storage-refactor-epic",
2022
"fastapi>=0.95.0",
2123
"python-multipart", # required for fastapi file uploads
2224
"uvicorn",
23-
"python-dotenv",
25+
"click",
2426
"anyio",
27+
"python-dotenv",
28+
"pydantic-settings",
2529
]
2630
dynamic = ["version"]
2731

@@ -37,6 +41,7 @@ dev = [
3741
"ruff==0.12.8",
3842
"pre-commit>=4.2.0",
3943
"ipykernel",
44+
"fastapi[standard]",
4045
]
4146

4247
[project.urls]
@@ -46,6 +51,9 @@ Changelog = "https://github.com/genomicmedlab/vlm_in_a_box/releases"
4651
Source = "https://github.com/genomicmedlab/vlm_in_a_box/"
4752
"Bug Tracker" = "https://github.com/genomicmedlab/vlm_in_a_box/issues"
4853

54+
[project.scripts]
55+
vlm = "vlm.cli:_cli"
56+
4957

5058
[build-system]
5159
requires = [
@@ -57,33 +65,10 @@ build-backend = "setuptools.build_meta"
5765
[tool.setuptools_scm]
5866

5967
[tool.pytest.ini_options]
60-
addopts = "--cov=anyvar --cov-report term-missing"
68+
addopts = "--cov=vlm --cov-report term-missing"
6169
testpaths = ["tests"]
6270
pythonpath = ["src"]
6371

64-
[tool.coverage.run]
65-
branch = true
66-
source = ["biocommons.example"]
67-
omit = ["*_test.py", "*/test/*", "*/tests/*"]
68-
69-
[tool.coverage.report]
70-
show_missing = true
71-
exclude_lines = [
72-
# Have to re-enable the standard pragma
73-
"pragma: no cover",
74-
75-
# Don't complain about missing debug-only code:
76-
"def __repr__",
77-
"if self.debug",
78-
79-
# Don't complain if tests don't hit defensive assertion code:
80-
"raise AssertionError",
81-
"raise NotImplementedError",
82-
83-
# Don't complain if non-runnable code isn't run:
84-
"if __name__ == .__main__.:",
85-
]
86-
8772
[tool.ruff]
8873
src = ["src"]
8974
include = ["src/**/*.py", "tests/**/*.py"]

src/vlm/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
11
"""Off-the-shelf solution for adding local aggregate-level variant information to a VLM network"""
2+
3+
from importlib.metadata import PackageNotFoundError, version
4+
5+
try:
6+
__version__ = version("vlm")
7+
except PackageNotFoundError:
8+
__version__ = "unknown"
9+
finally:
10+
del version, PackageNotFoundError

src/vlm/anyvar/__init__.py

Whitespace-only changes.

src/vlm/anyvar/base_client.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""Provide abstraction for a VLM-to-AnyVar connection."""
2+
3+
import abc
4+
5+
from anyvar.utils.types import VrsObject
6+
7+
from vlm.schemas.domain import AlleleFrequencyAnnotation
8+
9+
10+
class BaseAnyVarClient(abc.ABC):
11+
"""Interface elements for an AnyVar client"""
12+
13+
@abc.abstractmethod
14+
def put_objects(self, objects: list[VrsObject]) -> None:
15+
"""Register objects with AnyVar
16+
17+
:param objects: variation objects to register
18+
"""
19+
20+
@abc.abstractmethod
21+
def put_af_annotation(self, key: str, af: AlleleFrequencyAnnotation) -> None:
22+
"""Add an allele frequency annotation to a variation
23+
24+
25+
:param key: VRS ID for variation being annotated
26+
:param af: frequency data for for annotation
27+
"""
28+
29+
@abc.abstractmethod
30+
def search_by_interval(
31+
self, accession: str, start: int, end: int
32+
) -> list[VrsObject]:
33+
"""Get all variation IDs located within the specified range
34+
35+
:param accession: sequence accession
36+
:param start: start position for genomic region
37+
:param end: end position for genomic region
38+
:return: list of matching variant objects
39+
"""
40+
41+
@abc.abstractmethod
42+
def close(self) -> None:
43+
"""Clean up AnyVar connection."""

src/vlm/cli.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""CLI for interacting with VLM instance"""
2+
3+
import click
4+
5+
import vlm
6+
7+
8+
@click.version_option(vlm.__version__)
9+
@click.group()
10+
def _cli() -> None:
11+
"""Manage VLM data."""
12+
13+
14+
@_cli.command()
15+
def ingest_vcf() -> None:
16+
"""Deposit variants and allele frequencies from VCF into VLM instance"""
17+
raise NotImplementedError

src/vlm/config.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""Define app settings."""
2+
3+
from functools import cache
4+
5+
from pydantic_settings import BaseSettings, SettingsConfigDict
6+
7+
from vlm.schemas.common import ServiceEnvironment
8+
9+
10+
class Settings(BaseSettings):
11+
"""Create app settings
12+
13+
This is not a singleton, so every new call to this class will re-compute
14+
configuration settings, defaults, etc.
15+
"""
16+
17+
model_config = SettingsConfigDict(
18+
env_prefix="vlm_",
19+
env_file=".env",
20+
env_file_encoding="utf-8",
21+
extra="ignore",
22+
)
23+
24+
env: ServiceEnvironment = ServiceEnvironment.LOCAL
25+
26+
27+
@cache
28+
def get_config() -> Settings:
29+
"""Get runtime configuration.
30+
31+
This function is cached, so the config object only gets created/calculated once.
32+
33+
:return: Settings instance
34+
"""
35+
return Settings()

src/vlm/functions/__init__.py

Whitespace-only changes.

src/vlm/functions/get_caf.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""Perform search against variant(s) contained by an AnyVar node, and construct cohort allele frequency model(s)"""
2+
3+
from ga4gh.va_spec.base.core import CohortAlleleFrequencyStudyResult
4+
5+
from vlm.anyvar.base_client import BaseAnyVarClient
6+
7+
8+
def get_caf(
9+
av: BaseAnyVarClient, accession_id: str, start: int, end: int
10+
) -> list[CohortAlleleFrequencyStudyResult]:
11+
"""Retrieve Cohort Allele Frequency data for all known variants matching provided search params
12+
13+
:param av: AnyVar client
14+
:param accession_id: ID for sequence to search upon
15+
:param start: start of range search
16+
:param end: end of range to search
17+
:return: list of CAFs contained in search interval
18+
"""
19+
raise NotImplementedError

src/vlm/functions/ingest_vcf.py

Whitespace-only changes.

0 commit comments

Comments
 (0)