variantgrid-api 0.0.2__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.0.2/PKG-INFO +10 -0
- variantgrid_api-0.0.2/bin/vg_api +108 -0
- variantgrid_api-0.0.2/setup.cfg +4 -0
- variantgrid_api-0.0.2/setup.py +18 -0
- variantgrid_api-0.0.2/variantgrid_api/__init__.py +3 -0
- variantgrid_api-0.0.2/variantgrid_api/add_classification.py +16 -0
- variantgrid_api-0.0.2/variantgrid_api/annotation.py +18 -0
- variantgrid_api-0.0.2/variantgrid_api/api.py +125 -0
- variantgrid_api-0.0.2/variantgrid_api/classifications.py +120 -0
- variantgrid_api-0.0.2/variantgrid_api/gene_list.py +15 -0
- variantgrid_api-0.0.2/variantgrid_api/variant_classification_vcf.py +25 -0
- variantgrid_api-0.0.2/variantgrid_api/vcf_utils.py +48 -0
- variantgrid_api-0.0.2/variantgrid_api.egg-info/PKG-INFO +10 -0
- variantgrid_api-0.0.2/variantgrid_api.egg-info/SOURCES.txt +16 -0
- variantgrid_api-0.0.2/variantgrid_api.egg-info/dependency_links.txt +1 -0
- variantgrid_api-0.0.2/variantgrid_api.egg-info/not-zip-safe +1 -0
- variantgrid_api-0.0.2/variantgrid_api.egg-info/requires.txt +2 -0
- variantgrid_api-0.0.2/variantgrid_api.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Metadata-Version: 1.0
|
|
2
|
+
Name: variantgrid_api
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: API to connect to VariantGrid
|
|
5
|
+
Home-page: https://bitbucket.org/sacgf/variantgrid_api
|
|
6
|
+
Author: David Lawrence
|
|
7
|
+
Author-email: davmlaw@gmail.com
|
|
8
|
+
License: MIT License
|
|
9
|
+
Description: UNKNOWN
|
|
10
|
+
Platform: UNKNOWN
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
from __future__ import print_function
|
|
4
|
+
|
|
5
|
+
from configargparse import Action, ArgParser
|
|
6
|
+
from requests.exceptions import ConnectionError
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
from variantgrid_api.add_classification import add_classification_handle_args
|
|
10
|
+
from variantgrid_api.annotation import annotation_handle_args
|
|
11
|
+
from variantgrid_api.classifications import classifications_handle_args
|
|
12
|
+
from variantgrid_api.gene_list import gene_list_handle_args
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ClassificationAction(Action):
|
|
16
|
+
VALID_CLASSIFICATIONS = range(1, 6)
|
|
17
|
+
def __call__(self, parser, namespace, values, option_string=None):
|
|
18
|
+
if values not in self.VALID_CLASSIFICATIONS:
|
|
19
|
+
valid_classifications_str = ','.join(map(str, self.VALID_CLASSIFICATIONS))
|
|
20
|
+
raise ValueError("classification must be one of %s" % valid_classifications_str)
|
|
21
|
+
setattr(namespace, self.dest, values)
|
|
22
|
+
|
|
23
|
+
def add_authentication(parser, required):
|
|
24
|
+
parser.add("--login", required=required, env_var='VG_LOGIN')
|
|
25
|
+
parser.add("--password", required=required, env_var='VG_PASSWORD')
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_args():
|
|
29
|
+
CLASSIFICATION_HELP = 'HGNC classifications: 1 - Benign, 2 - Likely benign, 3 - VUS, 4 - Likely Pathogenic, 5 - Pathogenic'
|
|
30
|
+
|
|
31
|
+
parser = ArgParser(default_config_files=['~/.vg_api'])
|
|
32
|
+
parser.add('-c', '--config', is_config_file=True, help='config file path')
|
|
33
|
+
|
|
34
|
+
# Global settings
|
|
35
|
+
parser.add("--host", default='https://variantgrid.com', env_var='VG_HOST', help='Server Address (default=https://variantgrid.com)')
|
|
36
|
+
parser.add("--port", type=int, env_var='VG_PORT', help='Server port')
|
|
37
|
+
parser.add("--verbose", default=False, action='store_true', env_var='VG_VERBOSE', help='Print debugging information')
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
subparsers = parser.add_subparsers(help='sub-command help', dest='command')
|
|
41
|
+
|
|
42
|
+
# Add Classification
|
|
43
|
+
add_classification_parser = subparsers.add_parser('add_classification', help='Add new classification for a variant')
|
|
44
|
+
add_authentication(add_classification_parser, required=True)
|
|
45
|
+
variant_group = add_classification_parser.add_mutually_exclusive_group(required=True)
|
|
46
|
+
variant_group.add_argument('--variant', help='hg19 coordinate eg "1:169519049 T>C"')
|
|
47
|
+
variant_group.add_argument('--dbsnp', help='dbSNP rsId eg "rs6025"')
|
|
48
|
+
variant_group.add_argument('--hgvs', help='HGVS string eg "F5 (NM_000130) p.Gln534Arg/c.1601A>G"')
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
add_classification_parser.add_argument('--classification', type=int, action=ClassificationAction, help=CLASSIFICATION_HELP)
|
|
52
|
+
add_classification_parser.add_argument('--public', action='store_true', default=False, help="Classification is public (default=False)")
|
|
53
|
+
|
|
54
|
+
# Classifications
|
|
55
|
+
classifications_parser = subparsers.add_parser('classifications', help='Get classification from VariantGrid')
|
|
56
|
+
add_authentication(classifications_parser, required=False)
|
|
57
|
+
classifications_parser.add_argument("--classification", type=int, action=ClassificationAction)
|
|
58
|
+
|
|
59
|
+
group = classifications_parser.add_mutually_exclusive_group(required=True)
|
|
60
|
+
group.add_argument("--all", action='store_true')
|
|
61
|
+
group.add_argument("--dbsnp")
|
|
62
|
+
group.add_argument("--gene")
|
|
63
|
+
group.add_argument("--locus")
|
|
64
|
+
group.add_argument("--variant")
|
|
65
|
+
|
|
66
|
+
# Annotation
|
|
67
|
+
annotation_parser = subparsers.add_parser('annotation', help='Get VariantGrid Annotations')
|
|
68
|
+
|
|
69
|
+
group = annotation_parser.add_mutually_exclusive_group(required=True)
|
|
70
|
+
group.add_argument("--gene-id")
|
|
71
|
+
group.add_argument("--gene")
|
|
72
|
+
group.add_argument("--variant")
|
|
73
|
+
# TODO: Annotation Versions??
|
|
74
|
+
|
|
75
|
+
# Gene List
|
|
76
|
+
gene_list_parser = subparsers.add_parser('gene_list', help='Get Gene List')
|
|
77
|
+
add_authentication(gene_list_parser, required=False)
|
|
78
|
+
gene_list_parser.add_argument("--category", default='Uploaded', help="One of 'Diagnostic', 'Uploaded'")
|
|
79
|
+
group = gene_list_parser.add_mutually_exclusive_group(required=True)
|
|
80
|
+
group.add_argument("--pk")
|
|
81
|
+
group.add_argument("--name")
|
|
82
|
+
|
|
83
|
+
return parser.parse_args()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def main(args):
|
|
87
|
+
SUBCOMMAND_HANDLERS = {
|
|
88
|
+
"annotation" : annotation_handle_args,
|
|
89
|
+
"add_classification" : add_classification_handle_args,
|
|
90
|
+
"classifications" : classifications_handle_args,
|
|
91
|
+
"gene_list" : gene_list_handle_args,
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
handler = SUBCOMMAND_HANDLERS[args.command]
|
|
95
|
+
try:
|
|
96
|
+
return handler(args)
|
|
97
|
+
except ConnectionError as nce:
|
|
98
|
+
if args.verbose:
|
|
99
|
+
msg = str(nce)
|
|
100
|
+
else:
|
|
101
|
+
msg = "Could not connect to server."
|
|
102
|
+
print(msg, file=sys.stderr)
|
|
103
|
+
return 1
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
if __name__ == "__main__":
|
|
107
|
+
args = get_args()
|
|
108
|
+
main(args)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import absolute_import
|
|
2
|
+
from setuptools import setup
|
|
3
|
+
from variantgrid_api import __version__
|
|
4
|
+
|
|
5
|
+
setup(name='variantgrid_api',
|
|
6
|
+
version=__version__,
|
|
7
|
+
description='API to connect to VariantGrid',
|
|
8
|
+
url='https://bitbucket.org/sacgf/variantgrid_api',
|
|
9
|
+
author='David Lawrence',
|
|
10
|
+
author_email='davmlaw@gmail.com',
|
|
11
|
+
license='MIT License',
|
|
12
|
+
packages=['variantgrid_api'],
|
|
13
|
+
install_requires=[
|
|
14
|
+
'requests',
|
|
15
|
+
'configargparse',
|
|
16
|
+
],
|
|
17
|
+
scripts=['bin/vg_api',],
|
|
18
|
+
zip_safe=False)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from __future__ import print_function
|
|
2
|
+
|
|
3
|
+
from variantgrid_api.api import VariantGridAPI
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def add_classification_handle_args(args):
|
|
7
|
+
api = VariantGridAPI.from_args(args)
|
|
8
|
+
|
|
9
|
+
classification = None
|
|
10
|
+
if args.dbsnp:
|
|
11
|
+
classification = api.add_classifications_for_dbsnp(args.dbsnp, args.classification, args.public)
|
|
12
|
+
elif args.locus:
|
|
13
|
+
classification = api.add_classifications_for_variant(args.variant, args.classification, args.public)
|
|
14
|
+
|
|
15
|
+
print("created classification: %s" % classification)
|
|
16
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import print_function
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from variantgrid_api.api import VariantGridAPI
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def annotation_handle_args(args):
|
|
8
|
+
api = VariantGridAPI.from_args(args)
|
|
9
|
+
ret = None
|
|
10
|
+
if args.gene_id:
|
|
11
|
+
ret = api.gene_annotation(args.gene_id)
|
|
12
|
+
elif args.gene:
|
|
13
|
+
ret = api.gene_annotations(args.gene)
|
|
14
|
+
elif args.variant:
|
|
15
|
+
ret = api.variant_annotation(args.variant)
|
|
16
|
+
|
|
17
|
+
print(json.dumps(ret, indent=4, sort_keys=True))
|
|
18
|
+
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
import requests
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class VariantGridAPI(object):
|
|
8
|
+
def __init__(self, login=None, password=None, host='https://variantgrid.com', port=None):
|
|
9
|
+
if login and password:
|
|
10
|
+
self.auth = (login, password)
|
|
11
|
+
else:
|
|
12
|
+
self.auth = None
|
|
13
|
+
self.host = host
|
|
14
|
+
self.port = port
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def from_args(args):
|
|
18
|
+
return VariantGridAPI(args.login,
|
|
19
|
+
args.password,
|
|
20
|
+
host=args.host,
|
|
21
|
+
port=args.port)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def url(self):
|
|
26
|
+
u = "%s" % self.host
|
|
27
|
+
if self.port:
|
|
28
|
+
u += ":%d" % self.port
|
|
29
|
+
return u
|
|
30
|
+
|
|
31
|
+
def get(self, path):
|
|
32
|
+
url_path = os.path.join(self.url, path) + ".json"
|
|
33
|
+
r = requests.get(url_path, auth=self.auth)
|
|
34
|
+
r.raise_for_status()
|
|
35
|
+
try:
|
|
36
|
+
return json.loads(r.text)
|
|
37
|
+
except Exception as e:
|
|
38
|
+
logging.error("Couldn't decode: %s" % r.text)
|
|
39
|
+
logging.error(e)
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
def loci_variants(self, variant_string):
|
|
43
|
+
''' returns a list of variant objects for this loci '''
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
def gene_annotation(self, ensembl_gene__id, version=None):
|
|
47
|
+
return self.get('annotation/api/gene_id/%(ensembl_gene__id)s' % {'ensembl_gene__id' : ensembl_gene__id})
|
|
48
|
+
|
|
49
|
+
def gene_annotations(self, gene_symbol, version=None):
|
|
50
|
+
''' This may return multiple annotations for multiple genes '''
|
|
51
|
+
return self.get('annotation/api/gene/%(gene_symbol)s' % {'gene_symbol' : gene_symbol})
|
|
52
|
+
|
|
53
|
+
def variant_annotation(self, variant_string, version=None):
|
|
54
|
+
''' variant_string can be ID, rsId, HGVS '''
|
|
55
|
+
return self.get('annotation/api/variant/%(variant_string)s' % {'variant_string' : variant_string})
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def get_gene_list_genes(self, pk=None, category=None, name=None, version=None):
|
|
59
|
+
''' Use either PK or both (category, name) '''
|
|
60
|
+
too_many = pk and any([category, name])
|
|
61
|
+
too_few = pk is None and not all([category, name])
|
|
62
|
+
if too_many or too_few:
|
|
63
|
+
msg = "You need to supply either 'pk' OR both ('category' AND 'name') arguments"
|
|
64
|
+
raise ValueError(msg)
|
|
65
|
+
|
|
66
|
+
if pk:
|
|
67
|
+
gene_list = self.get('snpdb/gene_list/%s' % pk)
|
|
68
|
+
else:
|
|
69
|
+
gene_list = self.get('snpdb/named_gene_list/%s/%s' % (category, name))
|
|
70
|
+
return gene_list["genelistgene_set"]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _get_classification_json(self, url, classification=None):
|
|
74
|
+
''' so we can modify to stream JSON '''
|
|
75
|
+
|
|
76
|
+
if classification:
|
|
77
|
+
url = os.path.join(url, "classification", str(classification))
|
|
78
|
+
return self.get(url)
|
|
79
|
+
|
|
80
|
+
def variant_classifications_all(self, classification=None):
|
|
81
|
+
return self._get_classification_json('variantclassification/api/classifications/all', classification)
|
|
82
|
+
|
|
83
|
+
def variant_classifications_for_gene(self, gene_symbol, classification=None):
|
|
84
|
+
url = 'variantclassification/api/classifications/gene/%(gene_symbol)s' % {'gene_symbol' : gene_symbol}
|
|
85
|
+
return self._get_classification_json(url, classification)
|
|
86
|
+
|
|
87
|
+
def variant_classifications_for_dbsnp(self, dbsnp, classification=None):
|
|
88
|
+
url = 'variantclassification/api/classifications/dbsnp/%(dbsnp)s' % {'dbsnp' : dbsnp}
|
|
89
|
+
return self._get_classification_json(url, classification)
|
|
90
|
+
|
|
91
|
+
def variant_classifications_for_locus(self, locus_string, classification=None):
|
|
92
|
+
url = 'variantclassification/api/classifications/locus/%(locus_string)s' % {'locus_string' : locus_string}
|
|
93
|
+
return self._get_classification_json(url, classification)
|
|
94
|
+
|
|
95
|
+
def variant_classifications_for_variant(self, variant_string, classification=None):
|
|
96
|
+
url = 'variantclassification/classifications/api/variant/%(variant_string)s' % {'variant_string' : variant_string}
|
|
97
|
+
return self._get_classification_json(url, classification)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _add_classification_json(self, path, classification, public):
|
|
101
|
+
url_path = os.path.join(self.url, path) + ".json"
|
|
102
|
+
data = {"classification" : classification,
|
|
103
|
+
"public" : public}
|
|
104
|
+
|
|
105
|
+
r = requests.post(url_path, auth=self.auth, json=data)
|
|
106
|
+
r.raise_for_status()
|
|
107
|
+
return r.text
|
|
108
|
+
|
|
109
|
+
def add_classifications_for_dbsnp(self, dbsnp, classification, public=False):
|
|
110
|
+
params = {'dbsnp' : dbsnp}
|
|
111
|
+
url = 'variantclassification/api/add_classification/dbsnp/%(dbsnp)s' % params
|
|
112
|
+
return self._add_classification_json(url, classification, public)
|
|
113
|
+
|
|
114
|
+
def add_classifications_for_variant(self, variant_string, classification, public=False):
|
|
115
|
+
params = {'variant_string' : variant_string,}
|
|
116
|
+
url = 'variantclassification/api/add_classification/variant/%(variant_string)s' % params
|
|
117
|
+
return self._add_classification_json(url, classification, public)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def create_variant_classification(self, variant_string, classification):
|
|
122
|
+
# Check whether the variant string is correct - get back
|
|
123
|
+
# Send up classification
|
|
124
|
+
# Get back ID and return it
|
|
125
|
+
pass
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
from __future__ import print_function
|
|
2
|
+
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
import variantgrid_api
|
|
6
|
+
from variantgrid_api.api import VariantGridAPI
|
|
7
|
+
|
|
8
|
+
from variantgrid_api.variant_classification_vcf import VARIANTCLASSIFICATION_ID, \
|
|
9
|
+
VARIANTCLASSIFICATION_ZYGOSITY, VARIANTCLASSIFICATION_GROUP, CLASSIFICATION, \
|
|
10
|
+
VARIANT_GRID_INFO_DICT, INFO_SEPARATOR
|
|
11
|
+
from variantgrid_api.vcf_utils import get_vcf_header_lines, get_info
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def write_variant(classifications_for_variant):
|
|
15
|
+
# All loci should be the same
|
|
16
|
+
variant = classifications_for_variant[0]["variant"]
|
|
17
|
+
locus = variant["locus"]
|
|
18
|
+
|
|
19
|
+
columns = [locus["chrom"],
|
|
20
|
+
locus["position"],
|
|
21
|
+
'.', # ID
|
|
22
|
+
locus["ref"],
|
|
23
|
+
variant["alt"],
|
|
24
|
+
'.', # qual
|
|
25
|
+
'.', ] # filter
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
MERGE_COLUMNS = {"id" : VARIANTCLASSIFICATION_ID,
|
|
29
|
+
"zygosity" : VARIANTCLASSIFICATION_ZYGOSITY,
|
|
30
|
+
"classification_group" : VARIANTCLASSIFICATION_GROUP,
|
|
31
|
+
"classification_id" : CLASSIFICATION}
|
|
32
|
+
merged_columns = defaultdict(list)
|
|
33
|
+
for c in classifications_for_variant:
|
|
34
|
+
for k, info_col in MERGE_COLUMNS.items():
|
|
35
|
+
merged_columns[info_col].append(c.get(k))
|
|
36
|
+
|
|
37
|
+
info_dict = {} # "VARIANT_GRID_ID" : variant["id"]}
|
|
38
|
+
for (k, values_list) in merged_columns.items():
|
|
39
|
+
if any(values_list):
|
|
40
|
+
strings_list = map(str, [i or '' for i in values_list])
|
|
41
|
+
info_dict[k] = INFO_SEPARATOR.join(strings_list)
|
|
42
|
+
columns.append(get_info(info_dict))
|
|
43
|
+
print(*columns, sep='\t')
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def get_classifications(args):
|
|
48
|
+
api = VariantGridAPI.from_args(args)
|
|
49
|
+
|
|
50
|
+
classifications = []
|
|
51
|
+
if args.all:
|
|
52
|
+
classifications = api.variant_classifications_all(args.classification)
|
|
53
|
+
elif args.gene:
|
|
54
|
+
classifications = api.variant_classifications_for_gene(args.gene, args.classification)
|
|
55
|
+
elif args.dbsnp:
|
|
56
|
+
classifications = api.variant_classifications_for_dbsnp(args.dbsnp, args.classification)
|
|
57
|
+
elif args.locus:
|
|
58
|
+
classifications = api.variant_classifications_for_locus(args.locus, args.classification)
|
|
59
|
+
elif args.variant:
|
|
60
|
+
classifications = api.variant_classifications_for_variant(args.variant, args.classification)
|
|
61
|
+
return classifications
|
|
62
|
+
|
|
63
|
+
def get_private_command_line(args):
|
|
64
|
+
''' private means don't show password '''
|
|
65
|
+
|
|
66
|
+
SECRET_PARAMS = ["password", "command"]
|
|
67
|
+
GLOBAL_PARAMS = ["host", "port", "login"]
|
|
68
|
+
|
|
69
|
+
global_options_list = []
|
|
70
|
+
for p in GLOBAL_PARAMS:
|
|
71
|
+
v = getattr(args, p)
|
|
72
|
+
if v:
|
|
73
|
+
global_options_list.append("--%s=%s" % (p, v))
|
|
74
|
+
|
|
75
|
+
params = set(vars(args)) - set(SECRET_PARAMS + GLOBAL_PARAMS)
|
|
76
|
+
options_list = []
|
|
77
|
+
for p in params:
|
|
78
|
+
v = getattr(args, p)
|
|
79
|
+
if v:
|
|
80
|
+
options_list.append("--%s=%s" % (p, v))
|
|
81
|
+
|
|
82
|
+
params = {"global_options" : ' '.join(global_options_list),
|
|
83
|
+
"command" : args.command,
|
|
84
|
+
"options" : ' '.join(options_list)}
|
|
85
|
+
return "vg_api %(global_options)s %(command)s %(options)s" % params
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def write_vcf(top_lines, classifications):
|
|
89
|
+
info_dict = VARIANT_GRID_INFO_DICT.copy()
|
|
90
|
+
|
|
91
|
+
header_lines = get_vcf_header_lines(top_lines=top_lines, info_dict=info_dict)
|
|
92
|
+
print('\n'.join(header_lines))
|
|
93
|
+
|
|
94
|
+
# Group by variant_id
|
|
95
|
+
classifications_for_variant = []
|
|
96
|
+
last_variant_id = None
|
|
97
|
+
for classification in classifications:
|
|
98
|
+
variant_id = classification["variant"]["id"]
|
|
99
|
+
if last_variant_id and last_variant_id != variant_id: # Different
|
|
100
|
+
write_variant(classifications_for_variant)
|
|
101
|
+
classifications_for_variant = []
|
|
102
|
+
|
|
103
|
+
classifications_for_variant.append(classification)
|
|
104
|
+
last_variant_id = variant_id
|
|
105
|
+
|
|
106
|
+
if classifications_for_variant: # leftovers
|
|
107
|
+
write_variant(classifications_for_variant)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def classifications_handle_args(args):
|
|
113
|
+
classifications = get_classifications(args)
|
|
114
|
+
vg_api_str = "##generated_by=%s by vg_api v%s" % (datetime.now(), variantgrid_api.__version__)
|
|
115
|
+
command_line = "##command_line=%s" % get_private_command_line(args)
|
|
116
|
+
top_lines = [vg_api_str, command_line]
|
|
117
|
+
|
|
118
|
+
write_vcf(top_lines, classifications)
|
|
119
|
+
|
|
120
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from __future__ import print_function
|
|
2
|
+
|
|
3
|
+
from variantgrid_api.api import VariantGridAPI
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def gene_list_handle_args(args):
|
|
7
|
+
api = VariantGridAPI.from_args(args)
|
|
8
|
+
|
|
9
|
+
if args.pk:
|
|
10
|
+
genes = api.get_gene_list_genes(pk=args.pk)
|
|
11
|
+
elif args.name:
|
|
12
|
+
genes = api.get_gene_list_genes(category=args.category, name=args.name)
|
|
13
|
+
|
|
14
|
+
for gene in genes:
|
|
15
|
+
print(gene)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
INFO_SEPARATOR = '|'
|
|
2
|
+
|
|
3
|
+
VARIANT_GRID_ID = 'VARIANT_GRID_ID'
|
|
4
|
+
VARIANTCLASSIFICATION_ID = "VARIANTCLASSIFICATION_ID"
|
|
5
|
+
VARIANTCLASSIFICATION_ZYGOSITY = "VARIANTCLASSIFICATION_ZYGOSITY"
|
|
6
|
+
VARIANTCLASSIFICATION_GROUP = "VARIANTCLASSIFICATION_GROUP"
|
|
7
|
+
CLASSIFICATION = "CLASSIFICATION"
|
|
8
|
+
|
|
9
|
+
MULTIPLES = " multiple values joined with a %s" % INFO_SEPARATOR
|
|
10
|
+
|
|
11
|
+
VARIANT_GRID_INFO_DICT = {VARIANT_GRID_ID : {'number' : 1,
|
|
12
|
+
'type' : 'Integer',
|
|
13
|
+
'description' : 'VariantGrid primary column',},
|
|
14
|
+
VARIANTCLASSIFICATION_ID : {'number' : 1,
|
|
15
|
+
'type' : 'String',
|
|
16
|
+
'description' : 'Unique Classification ID' + MULTIPLES,},
|
|
17
|
+
VARIANTCLASSIFICATION_ZYGOSITY : {'number' : 1,
|
|
18
|
+
'type' : 'String',
|
|
19
|
+
'description' : 'Sample Zygosity of classification (E=HET, O=HOM)' + MULTIPLES,},
|
|
20
|
+
VARIANTCLASSIFICATION_GROUP : {'number' : 1,
|
|
21
|
+
'type' : 'String',
|
|
22
|
+
'description' : 'Group performing classification' + MULTIPLES,},
|
|
23
|
+
CLASSIFICATION : {'number' : 1,
|
|
24
|
+
'type' : 'String',
|
|
25
|
+
'description' : 'Pathogenicity according to ACMG guidelines. 1-Benign, 2-Likely Benign, 3-VUS, 4-Likely Pathogenic, 5-Pathogenic' + MULTIPLES,},}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Created on 13Feb.,2018
|
|
3
|
+
|
|
4
|
+
@author: dlawrence
|
|
5
|
+
'''
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_vcf_header_lines(top_lines=[], info_dict={}, formats=[], contigs=[], samples=[]):
|
|
9
|
+
''' info_dict - values of ('number', 'type', 'description')
|
|
10
|
+
contigs - tuples of (contig, length, assembly)
|
|
11
|
+
'''
|
|
12
|
+
|
|
13
|
+
header_lines = ['##fileformat=VCFv4.1']
|
|
14
|
+
header_lines.extend(top_lines)
|
|
15
|
+
for (info_id, data) in info_dict.items():
|
|
16
|
+
data['id'] = info_id
|
|
17
|
+
line_template = '##INFO=<ID=%(id)s,Number=%(number)s,Type=%(type)s,Description="%(description)s">'
|
|
18
|
+
line = line_template % data
|
|
19
|
+
header_lines.append(line)
|
|
20
|
+
|
|
21
|
+
use_format = samples and formats
|
|
22
|
+
if use_format:
|
|
23
|
+
header_lines.extend(formats)
|
|
24
|
+
|
|
25
|
+
for (contig, length, assembly) in contigs:
|
|
26
|
+
line = '##contig=<ID=%s,length=%d,assembly=%s>' % (contig, length, assembly)
|
|
27
|
+
header_lines.append(line)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
colnames = ['CHROM', 'POS', 'ID', 'REF', 'ALT', 'QUAL', 'FILTER', 'INFO']
|
|
31
|
+
if use_format:
|
|
32
|
+
colnames += ['FORMAT'] + samples
|
|
33
|
+
|
|
34
|
+
header_lines.append('#' + '\t'.join(colnames))
|
|
35
|
+
|
|
36
|
+
return header_lines
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_info(info_dict):
|
|
40
|
+
if info_dict:
|
|
41
|
+
infos_list = []
|
|
42
|
+
for info_name, info_data in info_dict.items():
|
|
43
|
+
infos_list.append('%s=%s' % (info_name, info_data))
|
|
44
|
+
info = ';'.join(infos_list)
|
|
45
|
+
else:
|
|
46
|
+
info = '.'
|
|
47
|
+
|
|
48
|
+
return info
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Metadata-Version: 1.0
|
|
2
|
+
Name: variantgrid-api
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: API to connect to VariantGrid
|
|
5
|
+
Home-page: https://bitbucket.org/sacgf/variantgrid_api
|
|
6
|
+
Author: David Lawrence
|
|
7
|
+
Author-email: davmlaw@gmail.com
|
|
8
|
+
License: MIT License
|
|
9
|
+
Description: UNKNOWN
|
|
10
|
+
Platform: UNKNOWN
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
setup.py
|
|
2
|
+
bin/vg_api
|
|
3
|
+
variantgrid_api/__init__.py
|
|
4
|
+
variantgrid_api/add_classification.py
|
|
5
|
+
variantgrid_api/annotation.py
|
|
6
|
+
variantgrid_api/api.py
|
|
7
|
+
variantgrid_api/classifications.py
|
|
8
|
+
variantgrid_api/gene_list.py
|
|
9
|
+
variantgrid_api/variant_classification_vcf.py
|
|
10
|
+
variantgrid_api/vcf_utils.py
|
|
11
|
+
variantgrid_api.egg-info/PKG-INFO
|
|
12
|
+
variantgrid_api.egg-info/SOURCES.txt
|
|
13
|
+
variantgrid_api.egg-info/dependency_links.txt
|
|
14
|
+
variantgrid_api.egg-info/not-zip-safe
|
|
15
|
+
variantgrid_api.egg-info/requires.txt
|
|
16
|
+
variantgrid_api.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
variantgrid_api
|