Skip to content

Commit 8ca54f1

Browse files
committed
add python api
1 parent d85af2c commit 8ca54f1

14 files changed

+1627
-23
lines changed

src/anyvlm/anyvar/base_client.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ class AnyVarClientError(Exception):
99
"""Generic client-related exception."""
1010

1111

12-
class AnyVarConnectionError(AnyVarClientError):
13-
"""Raise for network/communication failures when making calls to AnyVar instance"""
14-
15-
1612
class BaseAnyVarClient(abc.ABC):
1713
"""Interface elements for an AnyVar client"""
1814

@@ -22,7 +18,7 @@ def put_objects(self, objects: list[VrsVariation]) -> list[VrsVariation]:
2218
2319
:param objects: variation objects to register
2420
:return: completed VRS objects
25-
:raise AnyVarConnectionError: if connection is unsuccessful during registration request
21+
:raise AnyVarClientError: for errors relating to specifics of client interface
2622
"""
2723

2824
@abc.abstractmethod
@@ -35,7 +31,7 @@ def search_by_interval(
3531
:param start: start position for genomic region
3632
:param end: end position for genomic region
3733
:return: list of matching variant objects
38-
:raise AnyVarConnectionError: if connection is unsuccessful during search query
34+
:raise AnyVarClientError: if connection is unsuccessful during search query
3935
"""
4036

4137
@abc.abstractmethod

src/anyvlm/anyvar/http_client.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from anyvar.utils.types import VrsVariation
55
from ga4gh.vrs import models
66

7-
from anyvlm.anyvar.base_client import AnyVarConnectionError, BaseAnyVarClient
7+
from anyvlm.anyvar.base_client import AnyVarClientError, BaseAnyVarClient
88

99

1010
class HttpAnyVarClient(BaseAnyVarClient):
@@ -30,20 +30,19 @@ def put_objects(self, objects: list[VrsVariation]) -> list[VrsVariation]:
3030
3131
:param objects: variation objects to register
3232
:return: completed VRS objects
33-
:raise AnyVarConnectionError: if connection is unsuccessful during registration request
33+
:raise AnyVarClientError: if connection is unsuccessful during registration request
3434
"""
3535
results = []
36-
url = f"{self.hostname}/vrs_variation"
3736
for vrs_object in objects:
3837
response = requests.put(
39-
url,
38+
f"{self.hostname}/vrs_variation",
4039
json=vrs_object.model_dump(exclude_none=True, mode="json"),
4140
timeout=self.request_timeout,
4241
)
4342
try:
4443
response.raise_for_status()
4544
except requests.HTTPError as e:
46-
raise AnyVarConnectionError from e
45+
raise AnyVarClientError from e
4746
result_object = response.json()["object"]
4847
if result_object.get("type") == "Allele":
4948
results.append(models.Allele(**result_object))
@@ -62,7 +61,7 @@ def search_by_interval(
6261
:param start: start position for genomic region
6362
:param end: end position for genomic region
6463
:return: list of matching variant objects
65-
:raise AnyVarConnectionError: if connection is unsuccessful during search query
64+
:raise AnyVarClientError: if connection is unsuccessful during search query
6665
"""
6766
response = requests.get(
6867
f"{self.hostname}/search?accession={accession}&start={start}&end={end}",
@@ -71,7 +70,11 @@ def search_by_interval(
7170
try:
7271
response.raise_for_status()
7372
except requests.HTTPError as e:
74-
raise AnyVarConnectionError from e
73+
if response.json() == {
74+
"detail": "Unable to dereference provided accession ID"
75+
}:
76+
return []
77+
raise AnyVarClientError from e
7578
return [models.Allele(**v) for v in response.json()["variations"]]
7679

7780
def close(self) -> None:

src/anyvlm/anyvar/python_client.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"""Implement AnyVar client interface for direct Python-based access."""
2+
3+
from anyvar import AnyVar
4+
from anyvar.storage.base_storage import IncompleteVrsObjectError, Storage
5+
from anyvar.translate.translate import Translator
6+
from anyvar.utils.types import VrsVariation, recursive_identify
7+
8+
from anyvlm.anyvar.base_client import BaseAnyVarClient
9+
10+
11+
class PythonAnyVarClient(BaseAnyVarClient):
12+
"""A Python-based AnyVar client."""
13+
14+
def __init__(self, translator: Translator, storage: Storage) -> None: # noqa: D107
15+
self.av = AnyVar(translator, storage)
16+
17+
def put_objects(self, objects: list[VrsVariation]) -> list[VrsVariation]:
18+
"""Register objects with AnyVar
19+
20+
:param objects: variation objects to register
21+
:return: completed VRS objects
22+
"""
23+
complete_variations = []
24+
for variation in objects:
25+
try:
26+
self.av.put_objects([variation])
27+
except IncompleteVrsObjectError:
28+
variation = recursive_identify(variation) # noqa: PLW2901
29+
self.av.put_objects([variation])
30+
complete_variations.append(variation)
31+
return complete_variations
32+
33+
def search_by_interval(
34+
self, accession: str, start: int, end: int
35+
) -> list[VrsVariation]:
36+
"""Get all variation IDs located within the specified range
37+
38+
:param accession: sequence accession
39+
:param start: start position for genomic region
40+
:param end: end position for genomic region
41+
:return: list of matching variant objects
42+
"""
43+
try:
44+
if accession.startswith("ga4gh:"):
45+
ga4gh_id = accession
46+
else:
47+
ga4gh_id = self.av.translator.get_sequence_id(accession)
48+
except KeyError:
49+
return []
50+
51+
alleles = []
52+
if ga4gh_id:
53+
refget_accession = ga4gh_id.split("ga4gh:")[-1]
54+
alleles = self.av.object_store.search_alleles(refget_accession, start, end)
55+
56+
return alleles # type: ignore[reportReturnType]
57+
58+
def close(self) -> None:
59+
"""Clean up AnyVar instance."""
60+
self.av.object_store.close()

0 commit comments

Comments
 (0)