variantgrid-api 0.3.0__tar.gz → 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {variantgrid_api-0.3.0 → variantgrid_api-1.0.0}/PKG-INFO +8 -2
- variantgrid_api-1.0.0/README.md +5 -0
- {variantgrid_api-0.3.0 → variantgrid_api-1.0.0}/pyproject.toml +3 -2
- {variantgrid_api-0.3.0 → variantgrid_api-1.0.0}/src/variantgrid_api/api_client.py +56 -6
- {variantgrid_api-0.3.0 → variantgrid_api-1.0.0}/src/variantgrid_api/data_models.py +31 -20
- {variantgrid_api-0.3.0 → variantgrid_api-1.0.0}/src/variantgrid_api.egg-info/PKG-INFO +8 -2
- {variantgrid_api-0.3.0 → variantgrid_api-1.0.0}/src/variantgrid_api.egg-info/requires.txt +1 -0
- variantgrid_api-0.3.0/README.md +0 -1
- {variantgrid_api-0.3.0 → variantgrid_api-1.0.0}/LICENSE +0 -0
- {variantgrid_api-0.3.0 → variantgrid_api-1.0.0}/setup.cfg +0 -0
- {variantgrid_api-0.3.0 → variantgrid_api-1.0.0}/src/variantgrid_api.egg-info/SOURCES.txt +0 -0
- {variantgrid_api-0.3.0 → variantgrid_api-1.0.0}/src/variantgrid_api.egg-info/dependency_links.txt +0 -0
- {variantgrid_api-0.3.0 → variantgrid_api-1.0.0}/src/variantgrid_api.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: variantgrid_api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: A Python API client for VariantGrid
|
|
5
5
|
Author-email: Dave Lawrence <davmlaw@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -35,5 +35,11 @@ Description-Content-Type: text/markdown
|
|
|
35
35
|
License-File: LICENSE
|
|
36
36
|
Requires-Dist: requests
|
|
37
37
|
Requires-Dist: dataclasses-json
|
|
38
|
+
Requires-Dist: samshee
|
|
39
|
+
Dynamic: license-file
|
|
38
40
|
|
|
39
41
|
# variantgrid_api
|
|
42
|
+
|
|
43
|
+
Python API client for [VariantGrid](https://github.com/SACGF/variantgrid) Open source Variant database and analysis platform
|
|
44
|
+
|
|
45
|
+
See [changelog](https://github.com/SACGF/variantgrid_api/blob/main/CHANGELOG.md)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "variantgrid_api"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "1.0.0"
|
|
8
8
|
description = "A Python API client for VariantGrid"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Dave Lawrence", email = "davmlaw@gmail.com" }
|
|
@@ -20,7 +20,8 @@ classifiers = [
|
|
|
20
20
|
]
|
|
21
21
|
dependencies = [
|
|
22
22
|
"requests",
|
|
23
|
-
"dataclasses-json"
|
|
23
|
+
"dataclasses-json",
|
|
24
|
+
"samshee"
|
|
24
25
|
]
|
|
25
26
|
|
|
26
27
|
[project.urls]
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
+
import datetime
|
|
1
2
|
import json
|
|
2
3
|
import logging
|
|
3
4
|
import os
|
|
4
|
-
from typing import List
|
|
5
|
+
from typing import List, Optional
|
|
5
6
|
|
|
6
7
|
import requests
|
|
7
8
|
|
|
8
9
|
from variantgrid_api.data_models import EnrichmentKit, SequencingRun, SampleSheet, SampleSheetCombinedVCFFile, \
|
|
9
10
|
SampleSheetLookup, SequencingFile, QCGeneList, QCExecStats, QCGeneCoverage
|
|
10
11
|
|
|
12
|
+
class DateTimeEncoder(json.JSONEncoder):
|
|
13
|
+
def default(self,o):
|
|
14
|
+
if isinstance(o,(datetime.date, datetime.datetime)):
|
|
15
|
+
return o.isoformat()
|
|
16
|
+
return super().default(o)
|
|
17
|
+
|
|
18
|
+
|
|
11
19
|
|
|
12
20
|
class VariantGridAPI:
|
|
13
21
|
def __init__(self, server, api_token):
|
|
@@ -19,15 +27,23 @@ class VariantGridAPI:
|
|
|
19
27
|
|
|
20
28
|
def _post(self, path, json_data):
|
|
21
29
|
url = self._get_url(path)
|
|
22
|
-
|
|
30
|
+
json_string = json.dumps(json_data, cls=DateTimeEncoder)
|
|
31
|
+
response = requests.post(url,
|
|
32
|
+
headers={**self.headers, "Content-Type": "application/json"},
|
|
33
|
+
data=json_string)
|
|
34
|
+
|
|
35
|
+
extra_error_message = f"{url=}, {json_string=}"
|
|
36
|
+
return self._handle_json_response(response, extra_error_message)
|
|
37
|
+
|
|
38
|
+
def _handle_json_response(self, response, extra_error_message: Optional[str] = None):
|
|
23
39
|
try:
|
|
24
40
|
json_response = response.json()
|
|
25
41
|
except Exception as e:
|
|
26
42
|
json_response = f"Couldn't convert JSON: {e}"
|
|
27
43
|
if not response.ok:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
logging.
|
|
44
|
+
if extra_error_message:
|
|
45
|
+
logging.error(extra_error_message)
|
|
46
|
+
logging.error("Response: %s", json_response)
|
|
31
47
|
response.raise_for_status()
|
|
32
48
|
return json_response
|
|
33
49
|
|
|
@@ -123,4 +139,38 @@ class VariantGridAPI:
|
|
|
123
139
|
"files": {"file": f},
|
|
124
140
|
"params": {"path": filename}
|
|
125
141
|
}
|
|
126
|
-
|
|
142
|
+
response = requests.post(url, headers=self.headers, **kwargs)
|
|
143
|
+
extra_error_message = f"{filename=}"
|
|
144
|
+
return self._handle_json_response(response, extra_error_message)
|
|
145
|
+
|
|
146
|
+
###############
|
|
147
|
+
## Get methods
|
|
148
|
+
|
|
149
|
+
def _get(self, path, params=None):
|
|
150
|
+
url = self._get_url(path)
|
|
151
|
+
response = requests.get(url,
|
|
152
|
+
params,
|
|
153
|
+
headers=self.headers)
|
|
154
|
+
|
|
155
|
+
extra_error_message = f"{url=}, {params=}"
|
|
156
|
+
return self._handle_json_response(response, extra_error_message)
|
|
157
|
+
|
|
158
|
+
def sequencing_run_has_vcf(self, sequencing_run: SequencingRun, path: Optional[str] = None):
|
|
159
|
+
""" Returns whether the SequencingRun has a VCF associated with it. If path is set, VCF must match that path
|
|
160
|
+
otherwise - any VCF present will retur True """
|
|
161
|
+
return self.sequencing_run_name_has_vcf(sequencing_run.name, path)
|
|
162
|
+
|
|
163
|
+
def sequencing_run_name_has_vcf(self, sequencing_run_name: str, path: Optional[str] = None):
|
|
164
|
+
""" Returns whether the SequencingRun has a VCF associated with it. If path is set, VCF must match that path
|
|
165
|
+
otherwise - any VCF present will retur True """
|
|
166
|
+
data = self._get(f"seqauto/api/v1/sequencing_run/{sequencing_run_name}/")
|
|
167
|
+
found_vcf = False
|
|
168
|
+
for vcf in data["vcf_set"]:
|
|
169
|
+
if path is None or path in vcf["path"]:
|
|
170
|
+
found_vcf = True
|
|
171
|
+
break
|
|
172
|
+
return found_vcf
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import re
|
|
1
2
|
from datetime import date, datetime
|
|
2
3
|
from dataclasses import dataclass, field
|
|
3
4
|
from typing import Optional, List
|
|
@@ -22,15 +23,25 @@ class SequencingRun:
|
|
|
22
23
|
experiment: str
|
|
23
24
|
enrichment_kit: EnrichmentKit
|
|
24
25
|
|
|
26
|
+
@staticmethod
|
|
27
|
+
def get_date_from_name(name) -> Optional[datetime.date]:
|
|
28
|
+
date = None
|
|
29
|
+
if m := re.match(r".*_?([12]\d{5})_", name):
|
|
30
|
+
date_str = m.group(1)
|
|
31
|
+
dt = datetime.strptime(date_str, "%y%m%d")
|
|
32
|
+
date = dt.date()
|
|
33
|
+
return date
|
|
34
|
+
|
|
35
|
+
|
|
25
36
|
|
|
26
37
|
@dataclass_json
|
|
27
38
|
@dataclass
|
|
28
39
|
class SequencingSample:
|
|
29
40
|
sample_id: str
|
|
30
|
-
sample_number: int
|
|
31
|
-
lane: int
|
|
41
|
+
sample_number: int # Sample sheet row (to keep in order)
|
|
32
42
|
barcode: str
|
|
33
43
|
enrichment_kit: EnrichmentKit
|
|
44
|
+
lane: Optional[int] = None
|
|
34
45
|
sample_project: Optional[str] = None
|
|
35
46
|
is_control: bool = False
|
|
36
47
|
failed: bool = False
|
|
@@ -42,7 +53,7 @@ class SequencingSample:
|
|
|
42
53
|
class SampleSheet:
|
|
43
54
|
path: str
|
|
44
55
|
sequencing_run: SequencingRun
|
|
45
|
-
file_last_modified:
|
|
56
|
+
file_last_modified: float
|
|
46
57
|
hash: str
|
|
47
58
|
sequencing_samples: List[SequencingSample] = field(metadata=config(field_name="sequencingsample_set"))
|
|
48
59
|
|
|
@@ -144,34 +155,34 @@ class QCExecStats:
|
|
|
144
155
|
modified: datetime
|
|
145
156
|
hash: str
|
|
146
157
|
is_valid: bool
|
|
147
|
-
deduplicated_reads: int
|
|
148
|
-
indels_dbsnp_percent: float
|
|
149
158
|
mean_coverage_across_genes: float
|
|
150
159
|
mean_coverage_across_kit: float
|
|
151
160
|
median_insert: float
|
|
152
|
-
number_indels: int
|
|
153
|
-
number_snps: int
|
|
154
|
-
percent_10x_goi: float
|
|
155
|
-
percent_20x_goi: float
|
|
156
|
-
percent_20x_kit: float
|
|
157
|
-
percent_error_rate: float
|
|
158
|
-
percent_map_to_diff_chr: float
|
|
159
161
|
percent_read_enrichment: float
|
|
160
|
-
percent_reads: float
|
|
161
|
-
percent_softclip: float
|
|
162
162
|
percent_duplication: float
|
|
163
|
-
reads: int
|
|
164
|
-
sample_id_lod: float
|
|
165
|
-
sex_match: str
|
|
166
|
-
snp_dbsnp_percent: float
|
|
167
|
-
ts_to_tv_ratio: float
|
|
168
163
|
uniformity_of_coverage: float
|
|
164
|
+
deduplicated_reads: Optional[int] = None
|
|
165
|
+
indels_dbsnp_percent: Optional[float] = None
|
|
166
|
+
number_indels: Optional[int] = None
|
|
167
|
+
number_snps: Optional[int] = None
|
|
168
|
+
percent_10x_goi: Optional[float] = None
|
|
169
|
+
percent_20x_goi: Optional[float] = None
|
|
170
|
+
percent_20x_kit: Optional[float] = None
|
|
169
171
|
percent_100x_goi: Optional[float] = None
|
|
170
172
|
percent_100x_kit: Optional[float] = None
|
|
171
173
|
percent_250x_goi: Optional[float] = None
|
|
172
174
|
percent_250x_kit: Optional[float] = None
|
|
173
175
|
percent_500x_goi: Optional[float] = None
|
|
174
176
|
percent_500x_kit: Optional[float] = None
|
|
177
|
+
percent_error_rate: Optional[float] = None
|
|
178
|
+
percent_map_to_diff_chr: Optional[float] = None
|
|
179
|
+
percent_reads: Optional[float] = None
|
|
180
|
+
percent_softclip: Optional[float] = None
|
|
181
|
+
reads: Optional[int] = None
|
|
182
|
+
sample_id_lod: Optional[float] = None
|
|
183
|
+
sex_match: Optional[str] = None
|
|
184
|
+
snp_dbsnp_percent: Optional[float] = None
|
|
185
|
+
ts_to_tv_ratio: Optional[float] = None
|
|
175
186
|
|
|
176
187
|
|
|
177
188
|
@dataclass_json
|
|
@@ -180,4 +191,4 @@ class QCGeneCoverage:
|
|
|
180
191
|
""" We send this up to associate coverage file path with sequencing sample
|
|
181
192
|
Then, later we upload the coverage file - and match via path """
|
|
182
193
|
qc: QC
|
|
183
|
-
path: str
|
|
194
|
+
path: str
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: variantgrid_api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: A Python API client for VariantGrid
|
|
5
5
|
Author-email: Dave Lawrence <davmlaw@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -35,5 +35,11 @@ Description-Content-Type: text/markdown
|
|
|
35
35
|
License-File: LICENSE
|
|
36
36
|
Requires-Dist: requests
|
|
37
37
|
Requires-Dist: dataclasses-json
|
|
38
|
+
Requires-Dist: samshee
|
|
39
|
+
Dynamic: license-file
|
|
38
40
|
|
|
39
41
|
# variantgrid_api
|
|
42
|
+
|
|
43
|
+
Python API client for [VariantGrid](https://github.com/SACGF/variantgrid) Open source Variant database and analysis platform
|
|
44
|
+
|
|
45
|
+
See [changelog](https://github.com/SACGF/variantgrid_api/blob/main/CHANGELOG.md)
|
variantgrid_api-0.3.0/README.md
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# variantgrid_api
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{variantgrid_api-0.3.0 → variantgrid_api-1.0.0}/src/variantgrid_api.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|