aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzsloan2019-06-04 11:24:46 -0500
committerzsloan2019-06-04 11:24:46 -0500
commit95a5e0e07fa9b4cd574beac5e4d9138a0b16bb60 (patch)
treee88780b0d1c33ef7511712d58eb5d682931be1c4
parent25eae5f41f5c821459f99bd0f3d777035a284564 (diff)
parent34d962fe1e0dd5e30f067e7a30fcbd8931f2aacb (diff)
downloadgenenetwork2-95a5e0e07fa9b4cd574beac5e4d9138a0b16bb60.tar.gz
Merge branch 'api' of github.com:zsloan/genenetwork2 into testing
-rw-r--r--doc/API_readme.md22
-rw-r--r--wqflask/base/webqtlConfig.py2
-rw-r--r--wqflask/wqflask/api/router.py132
-rw-r--r--wqflask/wqflask/show_trait/show_trait.py11
-rw-r--r--wqflask/wqflask/templates/collections/view.html4
-rw-r--r--wqflask/wqflask/templates/search_result_page.html6
-rw-r--r--wqflask/wqflask/templates/show_trait_details.html6
7 files changed, 157 insertions, 26 deletions
diff --git a/doc/API_readme.md b/doc/API_readme.md
index 96e8b246..6c88d413 100644
--- a/doc/API_readme.md
+++ b/doc/API_readme.md
@@ -51,13 +51,6 @@ curl http://gn2-zach.genenetwork.org/api/v_pre1/datasets/mouse/bxd
```
(I added the option to specify species just in case we end up with the same group name across multiple species at some point, though it's currently unnecessary)
-## Fetch Sample Data for Dataset ##
-```
-curl http://gn2-zach.genenetwork.org/api/v_pre1/sample_data/HSNIH-PalmerPublish.csv
-```
-
-Returns a CSV file with sample/strain names as the columns and trait IDs as rows
-
## Fetch Individual Dataset Info ##
### For mRNA Assay/"ProbeSet" ###
@@ -78,12 +71,27 @@ curl http://gn2-zach.genenetwork.org/api/v_pre1/dataset/bxd/10001
{ "dataset_type": "phenotype", "description": "Central nervous system, morphology: Cerebellum weight, whole, bilateral in adults of both sexes [mg]", "id": 10001, "name": "CBLWT2", "pubmed_id": 11438585, "title": "Genetic control of the mouse cerebellum: identification of quantitative trait loci modulating size and architecture", "year": "2001" }
```
+## Fetch Sample Data for Dataset ##
+```
+curl http://gn2-zach.genenetwork.org/api/v_pre1/sample_data/HSNIH-PalmerPublish.csv
+```
+
+Returns a CSV file with sample/strain names as the columns and trait IDs as rows
+
## Fetch Sample Data for Single Trait ##
```
curl http://gn2-zach.genenetwork.org/api/v_pre1/sample_data/HC_M2_0606_P/1436869_at
[ { "data_id": 23415463, "sample_name": "129S1/SvImJ", "sample_name_2": "129S1/SvImJ", "se": 0.123, "value": 8.201 }, { "data_id": 23415463, "sample_name": "A/J", "sample_name_2": "A/J", "se": 0.046, "value": 8.413 }, { "data_id": 23415463, "sample_name": "AKR/J", "sample_name_2": "AKR/J", "se": 0.134, "value": 8.856 }, ... ]
```
+## Fetch Trait List for Dataset ##
+```
+curl http://gn2-zach.genenetwork.org/api/v_pre1/traits/HXBBXHPublish.json
+[ { "Additive": 0.0499967532467532, "Id": 10001, "LRS": 16.2831307029479, "Locus": "rs106114574", "PhenotypeId": 1449, "PublicationId": 319, "Sequence": 1 }, ... ]
+```
+
+Both JSON and CSV formats can be specified, with JSON as default. There is also an optional "ids_only" and "names_only" parameter that will only return a list of trait IDs or names, respectively.
+
## Fetch Trait Info (Name, Description, Location, etc) ##
### For mRNA Expression/"ProbeSet" ###
```
diff --git a/wqflask/base/webqtlConfig.py b/wqflask/base/webqtlConfig.py
index b14cc4b0..a08acb0a 100644
--- a/wqflask/base/webqtlConfig.py
+++ b/wqflask/base/webqtlConfig.py
@@ -43,6 +43,7 @@ HOMOLOGENE_ID = "http://www.ncbi.nlm.nih.gov/homologene/?term=%s"
GENOTATION_URL = "http://www.genotation.org/Getd2g.pl?gene_list=%s"
GTEX_URL = "https://www.gtexportal.org/home/gene/%s"
GENEBRIDGE_URL = "https://www.systems-genetics.org/modules_by_gene/%s?organism=%s"
+GENEMANIA_URL = "https://genemania.org/search/%s/%s"
UCSC_REFSEQ = "http://genome.cse.ucsc.edu/cgi-bin/hgTracks?db=%s&hgg_gene=%s&hgg_chrom=chr%s&hgg_start=%s&hgg_end=%s"
BIOGPS_URL = "http://biogps.org/?org=%s#goto=genereport&id=%s"
STRING_URL = "http://string-db.org/newstring_cgi/show_network_section.pl?identifier=%s"
@@ -87,4 +88,3 @@ if not valid_path(JSON_GENODIR):
PORTADDR = "http://50.16.251.170"
INFOPAGEHREF = '/dbdoc/%s.html'
CGIDIR = '/webqtl/' #XZ: The variable name 'CGIDIR' should be changed to 'PYTHONDIR'
-SCRIPTFILE = 'main.py'
diff --git a/wqflask/wqflask/api/router.py b/wqflask/wqflask/api/router.py
index 845873a0..707e4e65 100644
--- a/wqflask/wqflask/api/router.py
+++ b/wqflask/wqflask/api/router.py
@@ -290,6 +290,120 @@ def get_dataset_info(dataset_name, group_name = None, file_format="json"):
else:
return return_error(code=204, source=request.url_rule.rule, title="No Results", details="")
+@app.route("/api/v_{}/traits/<path:dataset_name>".format(version), methods=('GET',))
+@app.route("/api/v_{}/traits/<path:dataset_name>.<path:file_format>".format(version), methods=('GET',))
+def fetch_traits(dataset_name, file_format = "json"):
+ trait_ids, trait_names, data_type, dataset_id = get_dataset_trait_ids(dataset_name)
+ if ('ids_only' in request.args) and (len(trait_ids) > 0):
+ if file_format == "json":
+ filename = dataset_name + "_trait_ids.json"
+ return flask.jsonify(trait_ids)
+ else:
+ filename = dataset_name + "_trait_ids.csv"
+
+ si = StringIO.StringIO()
+ csv_writer = csv.writer(si)
+ csv_writer.writerows([[trait_id] for trait_id in trait_ids])
+ output = make_response(si.getvalue())
+ output.headers["Content-Disposition"] = "attachment; filename=" + filename
+ output.headers["Content-type"] = "text/csv"
+ return output
+ elif ('names_only' in request.args) and (len(trait_ids) > 0):
+ if file_format == "json":
+ filename = dataset_name + "_trait_names.json"
+ return flask.jsonify(trait_names)
+ else:
+ filename = dataset_name + "_trait_names.csv"
+
+ si = StringIO.StringIO()
+ csv_writer = csv.writer(si)
+ csv_writer.writerows([[trait_name] for trait_name in trait_names])
+ output = make_response(si.getvalue())
+ output.headers["Content-Disposition"] = "attachment; filename=" + filename
+ output.headers["Content-type"] = "text/csv"
+ return output
+ else:
+ if len(trait_ids) > 0:
+ if data_type == "ProbeSet":
+ query = """
+ SELECT
+ ProbeSet.Id, ProbeSet.Name, ProbeSet.Symbol, ProbeSet.description, ProbeSet.Chr, ProbeSet.Mb, ProbeSet.alias,
+ ProbeSetXRef.mean, ProbeSetXRef.se, ProbeSetXRef.Locus, ProbeSetXRef.LRS, ProbeSetXRef.pValue, ProbeSetXRef.additive, ProbeSetXRef.h2
+ FROM
+ ProbeSet, ProbeSetXRef
+ WHERE
+ ProbeSetXRef.ProbeSetFreezeId = '{0}' AND
+ ProbeSetXRef.ProbeSetId = ProbeSet.Id
+ ORDER BY
+ ProbeSet.Id
+ """
+
+ field_list = ["Id", "Name", "Symbol", "Description", "Chr", "Mb", "Aliases", "Mean", "SE", "Locus", "LRS", "P-Value", "Additive", "h2"]
+ elif data_type == "Geno":
+ query = """
+ SELECT
+ Geno.Id, Geno.Name, Geno.Marker_Name, Geno.Chr, Geno.Mb, Geno.Sequence, Geno.Source
+ FROM
+ Geno, GenoXRef
+ WHERE
+ GenoXRef.GenoFreezeId = '{0}' AND
+ GenoXRef.GenoId = Geno.Id
+ ORDER BY
+ Geno.Id
+ """
+
+ field_list = ["Id", "Name", "Marker_Name", "Chr", "Mb", "Sequence", "Source"]
+ else:
+ query = """
+ SELECT
+ PublishXRef.Id, PublishXRef.PhenotypeId, PublishXRef.PublicationId, PublishXRef.Locus, PublishXRef.LRS, PublishXRef.additive, PublishXRef.Sequence
+ FROM
+ PublishXRef
+ WHERE
+ PublishXRef.InbredSetId = {0}
+ ORDER BY
+ PublishXRef.Id
+ """
+
+ field_list = ["Id", "PhenotypeId", "PublicationId", "Locus", "LRS", "Additive", "Sequence"]
+
+ if file_format == "json":
+ filename = dataset_name + "_traits.json"
+
+ final_query = query.format(dataset_id)
+
+ result_list = []
+ for result in g.db.execute(final_query).fetchall():
+ trait_dict = {}
+ for i, field in enumerate(field_list):
+ if result[i]:
+ trait_dict[field] = result[i]
+ result_list.append(trait_dict)
+
+ return flask.jsonify(result_list)
+ elif file_format == "csv":
+ filename = dataset_name + "_traits.csv"
+
+ results_list = []
+ header_list = []
+ header_list += field_list
+ results_list.append(header_list)
+
+ final_query = query.format(dataset_id)
+ for result in g.db.execute(final_query).fetchall():
+ results_list.append(result)
+
+ si = StringIO.StringIO()
+ csv_writer = csv.writer(si)
+ csv_writer.writerows(results_list)
+ output = make_response(si.getvalue())
+ output.headers["Content-Disposition"] = "attachment; filename=" + filename
+ output.headers["Content-type"] = "text/csv"
+ return output
+ else:
+ return return_error(code=400, source=request.url_rule.rule, title="Invalid Output Format", details="Current formats available are JSON and CSV, with CSV as default")
+ else:
+ return return_error(code=204, source=request.url_rule.rule, title="No Results", details="")
@app.route("/api/v_{}/sample_data/<path:dataset_name>".format(version))
@app.route("/api/v_{}/sample_data/<path:dataset_name>.<path:file_format>".format(version))
@@ -434,7 +548,7 @@ def trait_sample_data(dataset_name, trait_name, file_format = "json"):
dataset_or_group = dataset_name
pheno_query = """
- SELECT
+ SELECT DISTINCT
Strain.Name, Strain.Name2, PublishData.value, PublishData.Id, PublishSE.error, NStrain.count
FROM
(PublishData, Strain, PublishXRef, PublishFreeze)
@@ -528,8 +642,6 @@ def get_trait_info(dataset_name, trait_name, file_format = "json"):
PublishXRef.Id = '{0}' AND
PublishXRef.InbredSetId = '{1}'
""".format(trait_name, group_id)
-
- logger.debug("QUERY:", pheno_query)
pheno_results = g.db.execute(pheno_query)
@@ -612,13 +724,6 @@ def get_genotypes(group_name, file_format="csv"):
return output
-@app.route("/api/v_{}/traits/<path:dataset_name>".format(version), methods=('GET',))
-@app.route("/api/v_{}/traits/<path:dataset_name>.<path:file_format>".format(version), methods=('GET',))
-def get_traits(dataset_name, file_format = "json"):
- #ZS: Need to check about the "start" and "stop" stuff since it seems to just limit the number of results to stop - start + 1 in Pjotr's elixir code
-
- NotImplemented
-
def return_error(code, source, title, details):
json_ob = {"errors": [
{
@@ -652,7 +757,7 @@ def get_dataset_trait_ids(dataset_name):
dataset_id = results[0][2]
return trait_ids, trait_names, data_type, dataset_id
- elif "Publish" in dataset_name:
+ elif "Publish" in dataset_name or get_group_id(dataset_name):
data_type = "Publish"
dataset_name = dataset_name.replace("Publish", "")
dataset_id = get_group_id(dataset_name)
@@ -743,7 +848,10 @@ def get_group_id_from_dataset(dataset_name):
result = g.db.execute(query).fetchone()
- return result[0]
+ if len(result) > 0:
+ return result[0]
+ else:
+ return None
def get_group_id(group_name):
query = """
diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py
index 66d3a448..e10b31c0 100644
--- a/wqflask/wqflask/show_trait/show_trait.py
+++ b/wqflask/wqflask/show_trait/show_trait.py
@@ -257,7 +257,7 @@ class ShowTrait(object):
self.genbank_link = webqtlConfig.GENBANK_ID % genbank_id
self.genotation_link = self.gtex_link = self.genebridge_link = self.ucsc_blat_link = self.biogps_link = None
- self.string_link = self.panther_link = self.aba_link = self.ebi_gwas_link = self.wiki_pi_link = None
+ self.string_link = self.panther_link = self.aba_link = self.ebi_gwas_link = self.wiki_pi_link = self.genemania_link = None
if self.this_trait.symbol:
self.genotation_link = webqtlConfig.GENOTATION_URL % self.this_trait.symbol
self.gtex_link = webqtlConfig.GTEX_URL % self.this_trait.symbol
@@ -266,7 +266,10 @@ class ShowTrait(object):
self.ebi_gwas_link = webqtlConfig.EBIGWAS_URL % self.this_trait.symbol
if self.dataset.group.species == "mouse" or self.dataset.group.species == "human":
- self.genebridge_link = webqtlConfig.GENEBRIDGE_URL % (self.this_trait.symbol, self.dataset.group.species)
+ if self.dataset.group.species == "mouse":
+ self.genemania_link = webqtlConfig.GENEMANIA_URL % ("mus-musculus", self.this_trait.symbol)
+ else:
+ self.genemania_link = webqtlConfig.GENEMANIA_URL % ("homo-sapiens", self.this_trait.symbol)
if self.dataset.group.species == "mouse":
self.aba_link = webqtlConfig.ABA_URL % self.this_trait.symbol
@@ -282,8 +285,10 @@ class ShowTrait(object):
self.ucsc_blat_link = webqtlConfig.UCSC_REFSEQ % ('mm10', self.this_trait.refseq_transcriptid, chr, transcript_start, transcript_end)
if self.dataset.group.species == "rat":
+ self.genemania_link = webqtlConfig.GENEMANIA_URL % ("rattus-norvegicus", self.this_trait.symbol)
+
query = """SELECT kgID, chromosome, txStart, txEnd
- FROM GeneLink_rn33
+ FROM GeneList_rn33
WHERE geneSymbol = '{}'""".format(self.this_trait.symbol)
kgId, chr, transcript_start, transcript_end = g.db.execute(query).fetchall()[0] if len(g.db.execute(query).fetchall()) > 0 else None
diff --git a/wqflask/wqflask/templates/collections/view.html b/wqflask/wqflask/templates/collections/view.html
index 8d22b2a8..7e1001fc 100644
--- a/wqflask/wqflask/templates/collections/view.html
+++ b/wqflask/wqflask/templates/collections/view.html
@@ -84,8 +84,8 @@
<button class="btn btn-default" id="select_all"><span class="glyphicon glyphicon-ok"></span> Select All</button>
<button class="btn btn-default" id="deselect_all"><span class="glyphicon glyphicon-remove"></span> Deselect All</button>
<button class="btn btn-default" id="invert"><span class="glyphicon glyphicon-resize-vertical"></span> Invert</button>
- <button class="btn btn-danger" id="remove" disabled="disabled"><i class="icon-minus-sign"></i> Delete From Collection</button>
- <button class="btn" id="add" disabled="disabled"><i class="icon-plus-sign"></i> Copy Record to Other Collection</button>
+ <button class="btn btn-danger" id="remove" disabled="disabled"><i class="icon-minus-sign"></i> Delete Rows</button>
+ <button class="btn" id="add" disabled="disabled"><i class="icon-plus-sign"></i> Copy to Other Collection</button>
<br />
<br />
<form id="export_form" method="POST" action="/export_traits_csv">
diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html
index e20ea2d3..bf434452 100644
--- a/wqflask/wqflask/templates/search_result_page.html
+++ b/wqflask/wqflask/templates/search_result_page.html
@@ -324,7 +324,11 @@
'width': "500px",
'data': null,
'render': function(data, type, row, meta) {
- return decodeURIComponent(escape(data.description))
+ try {
+ return decodeURIComponent(escape(data.description))
+ } catch {
+ return escape(data.description)
+ }
}
},
{
diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html
index 09f36021..43efa314 100644
--- a/wqflask/wqflask/templates/show_trait_details.html
+++ b/wqflask/wqflask/templates/show_trait_details.html
@@ -88,6 +88,12 @@
</a>
&nbsp;&nbsp;
{% endif %}
+ {% if genemania_link %}
+ <a href="{{ genemania_link }}" title="GeneMANIA">
+ GeneMANIA
+ </a>
+ &nbsp;&nbsp;
+ {% endif %}
{% if unigene_link %}
<a href="{{ unigene_link }}" title="NCBI UniGene">
UniGene