From 869877c882333064e57ffa457446052164c1c9f6 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Tue, 24 Aug 2021 17:05:36 -0700 Subject: [PATCH 01/34] fix tests, remove those not applicable to the GO version of biolink-api --- requirements.txt | 1 + tests/association-all.feature | 1 - tests/association-gene-phenotype.feature | 10 +-- tests/bioentity-anatomy.feature | 20 ----- tests/bioentity-case.feature | 34 ------- tests/bioentity-disease.feature | 99 -------------------- tests/bioentity-gene.feature | 109 ----------------------- tests/bioentity-generic.feature | 4 +- tests/bioentity-genotype.feature | 75 ---------------- tests/bioentity-pathway.feature | 19 ---- tests/bioentity-phenotype.feature | 82 ----------------- tests/bioentity-publication.feature | 41 --------- tests/bioentity-substance.feature | 19 ---- tests/bioentity-variant.feature | 56 ------------ tests/bioentityset-taxon.feature | 3 +- tests/ontol-information-content.feature | 7 -- tests/steps/route-data.py | 21 ++++- 17 files changed, 29 insertions(+), 572 deletions(-) delete mode 100644 tests/bioentity-anatomy.feature delete mode 100644 tests/bioentity-case.feature delete mode 100644 tests/bioentity-disease.feature delete mode 100644 tests/bioentity-genotype.feature delete mode 100644 tests/bioentity-pathway.feature delete mode 100644 tests/bioentity-phenotype.feature delete mode 100644 tests/bioentity-substance.feature delete mode 100644 tests/bioentity-variant.feature delete mode 100644 tests/ontol-information-content.feature diff --git a/requirements.txt b/requirements.txt index 2869c92b..6f1035dc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,7 @@ wheel>0.25.0 flask-restplus>=0.10.1 Flask-SQLAlchemy>=2.1 flask-cors>=0.0 +Werkzeug==0.16.1 pysolr>=3.6.0 matplotlib>=0.0 sparqlwrapper>0.0 diff --git a/tests/association-all.feature b/tests/association-all.feature index 92b76a99..dc80486b 100644 --- a/tests/association-all.feature +++ b/tests/association-all.feature @@ -21,7 +21,6 @@ Note that inference is on by default. Queries for a general taxonomic class will then the JSON should have some JSONPath "associations[*].subject.id" with "string" "HGNC:18603" then the JSON should have some JSONPath "associations[*].subject.label" with "string" "COL25A1" then the JSON should have some JSONPath "associations[*].subject.category" containing "string" "gene" - then the JSON should have some JSONPath "associations[*].object.id" containing "string" "MONDO:0014538" Scenario: Client queries for all associations from a given subject, constrained by relation Given a path "/association/from/NCBIGene:84570?relation=RO:0002331" diff --git a/tests/association-gene-phenotype.feature b/tests/association-gene-phenotype.feature index a44ec41d..4eb3a34a 100644 --- a/tests/association-gene-phenotype.feature +++ b/tests/association-gene-phenotype.feature @@ -4,22 +4,22 @@ Feature: Association queries work as expected Scenario: User queries for mouse genes with abnormal Bowman membrane phenotype Given a path "/association/find/gene/phenotype/?subject_taxon=NCBITaxon:10090&rows=10&object=MP:0008521" - then the content should contain "abnormal Bowman membrane" + then the content should contain "abnormal Bowman membrane morphology" when the content is converted to JSON then the JSON should have some JSONPath "associations[*].subject.id" with "string" "MGI:1342287" and the JSON should have some JSONPath "associations[*].object.id" with "string" "MP:0008521" - and the JSON should have some JSONPath "associations[*].object.label" with "string" "abnormal Bowman membrane" + and the JSON should have some JSONPath "associations[*].object.label" with "string" "abnormal Bowman membrane morphology" Scenario: User queries for mouse genes with cornea phenotypes (including subtypes in the ontology), omitting evidence Given a path "/association/find/gene/phenotype/?subject_taxon=NCBITaxon:10090&rows=1000&fl_excludes_evidence=true&object=MP:0008521" - then the content should contain "abnormal Bowman membrane" + then the content should contain "abnormal Bowman membrane morphology" when the content is converted to JSON then the JSON should have some JSONPath "associations[*].subject.id" with "string" "MGI:1342287" and the JSON should have some JSONPath "associations[*].object.id" with "string" "MP:0008521" - and the JSON should have some JSONPath "associations[*].object.label" with "string" "abnormal Bowman membrane" + and the JSON should have some JSONPath "associations[*].object.label" with "string" "abnormal Bowman membrane morphology" Scenario: User queries for mouse genes with cornea phenotypes (using an HPO ID), omitting evidence Given a path "/association/find/gene/phenotype/?subject_taxon=NCBITaxon:10090&rows=1000&fl_excludes_evidence=true&object=HP:0000481" then the content should contain "Abnormality of corneal thickness" - and the content should contain "abnormal Bowman membrane" + and the content should contain "abnormal Bowman membrane morphology" diff --git a/tests/bioentity-anatomy.feature b/tests/bioentity-anatomy.feature deleted file mode 100644 index 3829ee98..00000000 --- a/tests/bioentity-anatomy.feature +++ /dev/null @@ -1,20 +0,0 @@ -Feature: Anatomy association queries that return a list of associations - -## Anatomy to Gene associations - - Scenario: User wants genes expressed in 'quadriceps femoris' - Given a path "/bioentity/anatomy/UBERON:0001377/genes?rows=10" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].subject.id" with "string" "UBERON:0001379" - then the JSON should have some JSONPath "associations[*].subject.category" containing "string" "anatomical entity" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "HGNC:24626" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "gene" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "MGI:1926210" - then the JSON should have some JSONPath "associations[*].relation.label" with "string" "expressed in" - - Scenario: User wants genes expressed in 'eye' for Danio rerio - Given a path "/bioentity/anatomy/UBERON:0000970/genes?rows=10&taxon=NCBITaxon:7955" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "eye" - then the JSON should have some JSONPath "associations[*].subject.category" containing "string" "anatomical entity" - then the JSON should have some JSONPath "associations[*].object.taxon.label" with "string" "Danio rerio" diff --git a/tests/bioentity-case.feature b/tests/bioentity-case.feature deleted file mode 100644 index af1784d3..00000000 --- a/tests/bioentity-case.feature +++ /dev/null @@ -1,34 +0,0 @@ -Feature: Case association queries that return a list of associations - -## Case to disease associations - - Scenario: Search for diseases associated with a case - Given a path "/bioentity/case/BNODE:person-51-1/diseases" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "affected female proband with Mucopolysaccharidosis type vi" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "MONDO:0009661" - -## Case to genotype associations - - Scenario: Search for genotypes associated with a case - Given a path "/bioentity/case/BNODE:person-GM21698/genotypes" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "BNODE:genoGM21698" - -## Case to model associations - - Scenario: Search for models associated with a case - Given a path "/bioentity/case/BNODE:person-SL5-2/models" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "Coriell:HG03064" - then the JSON should have some JSONPath "associations[*].relation.label" with "string" "derives_from" - -## Case to phenotype associations -# TODO - -## Case to variant associations - - Scenario: Search for variants associated with a case - Given a path "/bioentity/case/BNODE:person-GM00005/variants" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.label" with "string" "some karyotype alteration on chr14" diff --git a/tests/bioentity-disease.feature b/tests/bioentity-disease.feature deleted file mode 100644 index 9403ef6a..00000000 --- a/tests/bioentity-disease.feature +++ /dev/null @@ -1,99 +0,0 @@ -Feature: Disease entity queries work as expected - -## Disease to Model associations - - Scenario: User queries for a specific form of episodic ataxia disease - Given a path "/bioentity/disease/OMIM:160120/models" - then the content should contain "Kcna1" - and the content should contain "Mus musculus" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "MGI:2655686" - - Scenario: User queries for worm models of supranuclear palsy - Given a path "/bioentity/disease/DOID:678/models?taxon=NCBITaxon:6237" - then the content should contain "wormbase" - and the content should contain "Caenorhabditis" - and the content should contain "ptl-1" - - Scenario: User queries for worm models of lipid storage diseases (e.g. gangliosidosis) - Given a path "/bioentity/disease/DOID:9455/models?taxon=NCBITaxon:6237" - then the content should contain "wormbase" - and the content should contain "Caenorhabditis" - and the content should contain "lipl-1" - - Scenario: User queries for Parkinson disease, late-onset and can see onset and inheritance - Given a path "/bioentity/disease/MONDO:0008199" - when the content is converted to JSON - then the JSON should have some JSONPath "clinical_modifiers[*].id" with "string" "HP:0003676" - then the JSON should have some JSONPath "clinical_modifiers[*].label" with "string" "Progressive" - then the JSON should have some JSONPath "inheritance[*].id" with "string" "HP:0003745" - then the JSON should have some JSONPath "inheritance[*].label" with "string" "Sporadic" - -## Disease to Gene associations - - Scenario: User queries for genes associated with lipid storage diseases (e.g. gangliosidosis) - Given a path "/bioentity/disease/DOID:9455/genes?rows=0&fetch_objects=true&facet=true" - then the content should contain "HGNC:14537" - -## Disease to Gene causal associations - - Scenario: User queries for causal genes associated with Marfan Syndrome - Given a path "/bioentity/disease/MONDO:0007947/genes?rows=10&association_type=causal" - then the JSON should have some JSONPath "associations[0].object.label" with "string" "FBN1" - then the JSON should have some JSONPath "numFound" with "integer" "1" - -## Disease to Gene non causal associations - - Scenario: User queries for non causal genes associated with Marfan Syndrome - Given a path "/bioentity/disease/MONDO:0007947/genes?rows=10&association_type=non_causal" - then the JSON should not have some JSONPath "associations[*].object.label" with "string" "FBN1" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "TGFBR2" - -## Disease to Gene all associations - - Scenario: User queries for all genes associated with Marfan Syndrome - Given a path "/bioentity/disease/MONDO:0007947/genes?rows=10" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "FBN1" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "TGFBR2" - -## Disease to Phenotype associations - - Scenario: User queries for phenotypes associated with a disease - Given a path "/bioentity/disease/OMIM:605543/phenotypes" - then the JSON should have some JSONPath "associations[*].subject.id" with "string" "MONDO:0011562" - then the JSON should have some JSONPath "associations[*].subject.category" containing "string" "disease" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "HP:0001300" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "phenotype" - then the JSON should have some JSONPath "associations[*].relation.label" with "string" "has phenotype" - -## Disease to Case associations - - Scenario: User queries for cases associated with a disease - Given a path "/bioentity/disease/MONDO:0007739/cases" - then the JSON should have some JSONPath "associations[*].subject.id" with "string" "MONDO:0007739" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "Huntington disease" - then the JSON should have some JSONPath "associations[*].subject.category" containing "string" "disease" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "BNODE:person-690-65" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "case" - then the JSON should have some JSONPath "associations[*].relation.label" with "string" "is model of" - -## Disease to Genotype associations - - Scenario: User queries for genotypes associated with a disease - Given a path "/bioentity/disease/MONDO:0007243/genotypes" - then the JSON should have some JSONPath "associations[*].subject.id" with "string" "MONDO:0007243" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "Burkitt lymphoma" - then the JSON should have some JSONPath "associations[*].subject.category" containing "string" "disease" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "dbSNPIndividual:10748" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "genotype" - -## Disease to Variant associations - - Scenario: User queries for variants associated with a disease - Given a path "/bioentity/disease/MONDO:0007243/variants" - then the JSON should have some JSONPath "associations[*].subject.id" with "string" "MONDO:0007243" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "Burkitt lymphoma" - then the JSON should have some JSONPath "associations[*].subject.category" containing "string" "disease" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "ClinVarVariant:12577" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "variant" - then the JSON should have some JSONPath "associations[*].relation.label" with "string" "pathogenic_for_condition" \ No newline at end of file diff --git a/tests/bioentity-gene.feature b/tests/bioentity-gene.feature index 83d38526..c588e736 100644 --- a/tests/bioentity-gene.feature +++ b/tests/bioentity-gene.feature @@ -23,22 +23,6 @@ between these entities ## Gene to Homolog associations - Scenario: User fetches paralogs of SHH - Given a path "/bioentity/gene/NCBIGene:6469/homologs/?homology_type=P" - then the content should contain "DHH" - when the content is converted to JSON - then the JSON should have the top-level property "associations" - and the JSON should have some JSONPath "associations[*].object.id" with "string" "HGNC:2865" - and the JSON should have some JSONPath "associations[*].object.taxon.label" with "string" "Homo sapiens" - - Scenario: User fetches homologs of SHH with taxon Homo sapiens - Given a path "/bioentity/gene/NCBIGene:6469/homologs/?homolog_taxon=NCBITaxon:9606" - then the content should contain "DHH" - when the content is converted to JSON - then the JSON should have the top-level property "associations" - and the JSON should have some JSONPath "associations[*].object.id" with "string" "HGNC:2865" - and the JSON should have some JSONPath "associations[*].object.taxon.label" with "string" "Homo sapiens" - Scenario: User fetches all homologs of SHH Given a path "/bioentity/gene/NCBIGene:6469/homologs?rows=500" then the content should contain "Shh" @@ -50,14 +34,6 @@ between these entities ### TODO ensure label populated in scigraph call -## Gene to Phenotype associations - - Scenario: User fetches all phenotypes for a mouse gene - Given a path "/bioentity/gene/MGI:1342287/phenotypes?rows=500" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "MP:0008521" - and the JSON should have some JSONPath "associations[*].object.label" with "string" "abnormal Bowman membrane" - ## Gene to Function associations Scenario: User fetches all GO functional assignments for a zebrafish gene @@ -71,83 +47,6 @@ between these entities when the content is converted to JSON then the JSON should have some JSONPath "associations[*].slim[*]" with "string" "GO:0048731" -## Gene to Gene Interactions - - Scenario: User fetches all interactions for a mouse gene - Given a path "/bioentity/gene/MGI:1342287/interactions?rows=500" - then the content should contain "https://data.monarchinitiative.org/ttl/biogrid.ttl" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "MGI:88039" - and the JSON should have some JSONPath "associations[*].object.label" with "string" "Apc" - -## Gene to Anatomy associations - - Scenario: "User fetches anatomy terms associated with a gene" - Given a path "/bioentity/gene/NCBIGene%3A13434/anatomy" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].subject.id" with "string" "MGI:1274787" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "UBERON:0007769" - then the JSON should have some JSONPath "associations[*].relation.label" with "string" "expressed in" - -## Gene to Genotype associations - - Scenario: "User fetches genotypes associated with a gene" - Given a path "/bioentity/gene/HGNC:11025/genotypes" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "dbSNPIndividual:19935" - -## Gene to Case associations - - Scenario: "User fetches cases associated with a gene" - Given a path "/bioentity/gene/HGNC:11025/cases" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "BNODE:person-1879-4" - -## Gene to Model associations - - Scenario: "User fetches models associated with a gene" - Given a path "/bioentity/gene/NCBIGene:17988/models" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].subject.id" with "string" "MGI:1341799" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "Ndrg1" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "MMRRC:059206" - -## Gene to Ortholog-Disease associations - - Scenario: "User fetches diseases from orthologs associated with a gene" - Given a path "/bioentity/gene/NCBIGene:17988/ortholog/diseases" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].subject.id" with "string" "HGNC:7679" - then the JSON should have some JSONPath "associations[*].subject.taxon.label" with "string" "Homo sapiens" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "MONDO:0011085" - then the JSON should have some JSONPath "associations[*].relation.label" with "string" "causes condition" - -## Gene to Ortholog-Phenotype associations - - Scenario: "User fetches phenotypes from orthologs associated with a gene" - Given a path "/bioentity/gene/NCBIGene:4750/ortholog/phenotypes?&facet=true" - when the content is converted to JSON - then the JSON should have some JSONPath "facet_counts.subject_taxon_label" containing "string" "Mus musculus" - then the JSON should have some JSONPath "facet_counts.subject_taxon_label" containing "string" "Danio rerio" - -## Gene to Pathway associations - - Scenario: "User fetches pathways associated with a gene" - Given a path "/bioentity/gene/NCBIGene:50846/pathways" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].subject.id" with "string" "HGNC:2865" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "REACT:R-HSA-5658034" - then the JSON should have some JSONPath "associations[*].relation.label" with "string" "involved_in" - -## Gene to Phenotype associations - - Scenario: "User fetches phenotypes associated with a gene" - Given a path "/bioentity/gene/HGNC:11603/phenotypes" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.label" with "string" "Short femur" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "Patellar hypoplasia" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "Hip dysplasia" - ## Gene to Publication associations Scenario: "User fetches publications associated with a gene" @@ -155,11 +54,3 @@ between these entities when the content is converted to JSON then the JSON should have some JSONPath "associations[*].object.id" with "string" "PMID:19453261" then the JSON should have some JSONPath "associations[*].object.id" with "string" "PMID:30290780" - -## Gene to Variant associations - - Scenario: "User fetches variants associated with a gene" - Given a path "/bioentity/gene/HGNC:10896/variants" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "ClinVarVariant:532226" - then the JSON should have some JSONPath "associations[*].relation.label" with "string" "has_affected_feature" \ No newline at end of file diff --git a/tests/bioentity-generic.feature b/tests/bioentity-generic.feature index 7ede9607..4dc62675 100644 --- a/tests/bioentity-generic.feature +++ b/tests/bioentity-generic.feature @@ -6,7 +6,7 @@ Feature: Get associations for any given Bioentity Given a path "/bioentity/HGNC%3A1103/associations?rows=500" when the content is converted to JSON then the JSON should have some JSONPath "associations[*].subject.category" containing "string" "gene" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "MONDO:0007959" + then the JSON should have some JSONPath "associations[*].object.id" with "string" "NCBIGene:6046" ## Get basic information about a Bioentity type @@ -25,4 +25,4 @@ Feature: Get associations for any given Bioentity then the JSON should have some JSONPath "taxon.label" with "string" "Homo sapiens" then the JSON should have some JSONPath "id" with "string" "HGNC:18603" then the JSON should have some JSONPath "label" with "string" "COL25A1" - then the JSON should have JSONPath "association_counts.interaction.counts" equal to "integer" "124" + then the JSON should have JSONPath "association_counts.interaction.counts" greater than "integer" "10" diff --git a/tests/bioentity-genotype.feature b/tests/bioentity-genotype.feature deleted file mode 100644 index fa9eed0c..00000000 --- a/tests/bioentity-genotype.feature +++ /dev/null @@ -1,75 +0,0 @@ -Feature: Genotype association queries that return a list of associations - -## Info about a Genotype - - Scenario: User fetches all information about a genotype - Given a path "/bioentity/genotype/dbSNPIndividual:11441" - then the content should contain "GM10874" - when the content is converted to JSON - -## Genotype to Case associations - - Scenario: User fetches genotype to case associations - Given a path "/bioentity/genotype/dbSNPIndividual%3A10440/cases" - then the content should contain "GM01793" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "BNODE:person-119-2" - then the JSON should have some JSONPath "associations[*].object.taxon.label" with "string" "Homo sapiens" - - -## Genotype to Disease associations - - Scenario: User fetches genotype to case associations - Given a path "/bioentity/genotype/dbSNPIndividual%3A10440/diseases" - then the content should contain "GM01793" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "MONDO:0005090" - then the JSON should have some JSONPath "associations[*].relation.label" with "string" "has phenotype" - -## Genotype to Gene associations - - Scenario: User fetches genotype to gene associations - Given a path "/bioentity/genotype/ZFIN:ZDB-FISH-150901-6607/genes" - then the content should contain "shha" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.label" with "string" "shha" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "shha" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/zfin.ttl" - -## Genotype to Model associations - - Scenario: User fetches genotype to gene associations - Given a path "/bioentity/genotype/BNODE:genoGM25367/models" - then the content should contain "GM25367" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "Coriell:GM25367" - then the JSON should have some JSONPath "associations[*].relation.label" with "string" "has_genotype" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/coriell.ttl" - -## Genotype to Phenotype associations - - Scenario: User fetches genotype to gene associations - Given a path "/bioentity/genotype/BNODE:genoGM25367/phenotypes" - then the content should contain "GM25367" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "HP:0000680" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/coriell.ttl" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/hpoa.ttl" - -## Genotype to Publication associations - - Scenario: User fetches genotype to publication associations - Given a path "/bioentity/genotype/ZFIN:ZDB-FISH-150901-6607/publications" - then the content should contain "shha" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "PMID:9007258" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/zfin.ttl" - -## Genotype to Variant associations - - Scenario: User fetches genotype to publication associations - Given a path "/bioentity/genotype/MONARCH:FBgeno422705/variants" - then the content should contain "GD11869" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].object.id" with "string" "FlyBase:FBal0052385" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/flybase.ttl" diff --git a/tests/bioentity-pathway.feature b/tests/bioentity-pathway.feature deleted file mode 100644 index 91461024..00000000 --- a/tests/bioentity-pathway.feature +++ /dev/null @@ -1,19 +0,0 @@ -Feature: Pathway association queries that return a list of associations - -## Pathway to Gene associations - - Scenario: User fetches pathway to gene associations - Given a path "/bioentity/pathway/REACT:R-HSA-5387390/genes" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "Hh mutants abrogate ligand secretion" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "HGNC:9555" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/ctd.ttl" - -## Pathway to Phenotype associations - - Scenario: User fetches pathway to phenotype associations - Given a path "/bioentity/pathway/REACT:R-HSA-5387390/phenotypes" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "Hh mutants abrogate ligand secretion" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "Dystonia" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "Pelvic girdle muscle atrophy" diff --git a/tests/bioentity-phenotype.feature b/tests/bioentity-phenotype.feature deleted file mode 100644 index f142be6d..00000000 --- a/tests/bioentity-phenotype.feature +++ /dev/null @@ -1,82 +0,0 @@ -Feature: Phenotype entity queries work as expected - - -## Info about a Phenotype - - Scenario: User queries for MP:0000087 - Given a path "/bioentity/phenotype/MP:0000087" - then the content should contain "lower jaw" - and the content should contain "mandible" - -## Phenotype to Gene associations - - Scenario: User queries for mouse genes with abnormal Bowman membrane phenotype - Given a path "/bioentity/phenotype/MP:0008521/genes" - then the content should contain "Klf4" - -### Phenotype to Anatomy associations - - Scenario: Client requires mapping between enlarged thymus (MP) and anatomy - Given a path "/bioentity/phenotype/MP:0000709/anatomy" - then the content should contain "thymus" - and the content should contain "UBERON:0002370" - - Scenario: Client requires mapping between prominent nose (HP) and anatomy - Given a path "/bioentity/phenotype/HP:0000448/anatomy" - then the content should contain "nose" - and the content should contain "UBERON:0000004" - -# TODO: This will always fail until bioentity/phenotype//anatomy route is fixed -# Scenario: Client requires mapping between phenotype (ZP) and anatomy -# Given a path "/bioentity/phenotype/ZP:0004204/anatomy" -# then the content should contain "muscle pioneer" -# and the content should contain "ZFA:0001086" - -### Phenotype to Case associations - - Scenario: Client requires cases associated with a phenotype - Given a path "/bioentity/phenotype/HP:0011951/cases" - then the content should contain "Aspiration pneumonia" - and the content should contain "MONARCH:c000009" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/udp.ttl" - -### Phenotype to Disease associations - - Scenario: Client requires diseases associated with a phenotype - Given a path "/bioentity/phenotype/HP:0011951/diseases" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "Aspiration pneumonia" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "orofaciodigital syndrome IX" - - -### Phenotype to Genotype associations - - Scenario: Client requires genotypes associated with a phenotype - Given a path "/bioentity/phenotype/HP:0011951/genotypes" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "Recurrent aspiration pneumonia" - then the JSON should have some JSONPath "associations[*].object.taxon.label" with "string" "Homo sapiens" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "dbSNPIndividual:15811" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "genotype" - -### Phenotype to Pathway associations - - Scenario: Client requires pathways associated with a phenotype - Given a path "/bioentity/phenotype/MP:0001569/pathways" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "Neonatal hyperbilirubinemia" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "KEGG-path:maphsa00040" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "pathway" - -### Phenotype to Variant associations - - Scenario: Client requires variants associated with a phenotype - Given a path "/bioentity/phenotype/HP:0011951/variants" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "Recurrent aspiration pneumonia" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "ClinVarVariant:158740" -then the JSON should have some JSONPath "associations[*].object.category" containing "string" "variant" - -### Phenotype to Publication associations - - Scenario: Client requires publications associated with a phenotype - Given a path "/bioentity/phenotype/MP:0001569/publications" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "Hyperbilirubinemia" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "PMID:18059474" -then the JSON should have some JSONPath "associations[*].object.category" containing "string" "publication" diff --git a/tests/bioentity-publication.feature b/tests/bioentity-publication.feature index 31e7d036..4ff1dafe 100644 --- a/tests/bioentity-publication.feature +++ b/tests/bioentity-publication.feature @@ -1,12 +1,5 @@ Feature: Publication association queries that return a list of associations -## Publication to Disease associations - - Scenario: User queries for diseases associated with a publication - Given a path "/bioentity/publication/PMID:19652879/diseases" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "congenital factor XI deficiency" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/clinvar.ttl" - ## Publication to Gene associations Scenario: User queries for genes associated with a publication @@ -14,37 +7,3 @@ Feature: Publication association queries that return a list of associations then the JSON should have some JSONPath "associations[*].object.id" with "string" "MGI:88336" then the JSON should have some JSONPath "associations[*].object.id" with "string" "RGD:708418" then the JSON should have some JSONPath "associations[*].object.id" with "string" "MGI:88337" - -## Publication to Phenotype associations - - Scenario: User queries for genes associated with a publication - Given a path "/bioentity/publication/PMID:11751940/phenotypes" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "MP:0004771" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "increased anti-single stranded DNA antibody level" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/mgi_slim.ttl" - -## Publication to Genotype associations - - Scenario: User queries for genes associated with a publication - Given a path "/bioentity/publication/PMID:20220848/genotypes" - then the JSON should have some JSONPath "associations[*].object.taxon.label" with "string" "Drosophila melanogaster" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "MONARCH:FBgeno426941" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/flybase.ttl" - -## Publication to Model associations - - Scenario: User queries for genes associated with a publication - Given a path "/bioentity/publication/PMID:11181576/models" - then the JSON should have some JSONPath "associations[*].object.taxon.label" with "string" "Homo sapiens" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "Coriell:GM05823" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "NIGMS-GM05823" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/coriell.ttl" - -## Publication to Variant ssociations - - Scenario: User queries for genes associated with a publication - Given a path "/bioentity/publication/PMID:11751940/variants" - then the JSON should have some JSONPath "associations[*].object.taxon.label" with "string" "Rattus norvegicus" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "RGD:708418" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "Cd40lg" - then the JSON should have some JSONPath "associations[*].provided_by" containing "string" "https://data.monarchinitiative.org/ttl/ncbigene.ttl" diff --git a/tests/bioentity-substance.feature b/tests/bioentity-substance.feature deleted file mode 100644 index e55b5146..00000000 --- a/tests/bioentity-substance.feature +++ /dev/null @@ -1,19 +0,0 @@ -Feature: substance routes work as expected - -## Get associations between a given drug and an activity - - Scenario: User requests processes or pathways associated with amitrole - Given a path "/bioentity/substance/CHEBI:40036/participant_in/" - then the content should contain "aminotriazole transmembrane transporter activity" - -## Get associations between a given drug and roles - - Scenario: User requests for roles that amitrole plays - Given a path "/bioentity/substance/CHEBI:40036/roles/" - then the content should contain "herbicide" - then the content should contain "carotenoid biosynthesis inhibitor" - - -## Get associations between a given drug and a disease that it treats - -# TODO \ No newline at end of file diff --git a/tests/bioentity-variant.feature b/tests/bioentity-variant.feature deleted file mode 100644 index 843c466f..00000000 --- a/tests/bioentity-variant.feature +++ /dev/null @@ -1,56 +0,0 @@ -Feature: Variant association queries that return a list of associations - -## Variant to Case associations - - Scenario: User queries for cases associated with a variant - Given a path "/bioentity/variant/dbSNP:rs5030868/cases" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "rs5030868-A" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "BNODE:person-GM00325" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "case" - -## Variant to Disease associations - - Scenario: User queries for diseases associated with a variant - Given a path "/bioentity/variant/ClinVarVariant:14925/diseases" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "HSPG2, 9-BP DEL" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "MONDO:0009717" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "disease" - -## Variant to Gene associations - - Scenario: User queries for genes associated with a variant - Given a path "/bioentity/variant/ClinVarVariant:39783/genes" - then the JSON should have some JSONPath "associations[*].subject.label" containing "string" "Gly34Val" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "HGNC:10896" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "gene" - -## Variant to Genotype associations - - Scenario: User queries for genotypes associated with a variant - Given a path "/bioentity/variant/ZFIN:ZDB-ALT-010427-8/genotypes" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "tbx392" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "ZFIN:ZDB-FISH-150901-24810" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "genotype" - -## Variant to Model associations - - Scenario: User queries for models associated with a variant - Given a path "/bioentity/variant/dbSNP:rs5030868/models" - then the JSON should have some JSONPath "associations[*].subject.label" with "string" "rs5030868-A" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "Coriell:GM01165" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "model" - -## Variant to Phenotype associations - - Scenario: User queries for phenotypes associated with a variant - Given a path "/bioentity/variant/ClinVarVariant:39783/phenotypes" - then the JSON should have some JSONPath "associations[*].subject.label" containing "string" "p.Gly34Val" - then the JSON should have some JSONPath "associations[*].object.label" with "string" "Craniosynostosis" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "phenotype" - -## Variant to Publication associations - - Scenario: User queries for publications associated with a variant - Given a path "/bioentity/variant/ClinVarVariant:39783/publications" - then the JSON should have some JSONPath "associations[*].object.id" with "string" "PMID:23103230" - then the JSON should have some JSONPath "associations[*].object.category" containing "string" "publication" diff --git a/tests/bioentityset-taxon.feature b/tests/bioentityset-taxon.feature index ce98f92d..c4a4998a 100644 --- a/tests/bioentityset-taxon.feature +++ b/tests/bioentityset-taxon.feature @@ -1,4 +1,3 @@ - Feature: homologous set of bioentities returned for a given gene all have a valid taxon Scenario Outline: User fetches all homologs for a human gene and they all have their taxon info @@ -6,7 +5,7 @@ Feature: homologous set of bioentities returned for a given gene all have a vali when the content is converted to JSON then the JSON should have some JSONPath "associations[*].object.taxon.id" of type "string" and the JSON should have some JSONPath "associations[*].object.taxon.label" of type "string" - and the gene "associations[*].object" homolog ID should be the authoritative source for taxon + #and the gene "associations[*].object" homolog ID should be the authoritative source for taxon Examples: human genes | hgncID | diff --git a/tests/ontol-information-content.feature b/tests/ontol-information-content.feature deleted file mode 100644 index 32275f52..00000000 --- a/tests/ontol-information-content.feature +++ /dev/null @@ -1,7 +0,0 @@ -Feature: Dynamic information content calculation - - Scenario: Client code fetches ICs for MP terms based on mouse gene associations - Given a path "/ontol/information_content/gene/phenotype/NCBITaxon:10090" - then the content should contain "MP:0000709" - - diff --git a/tests/steps/route-data.py b/tests/steps/route-data.py index 66b1ba2d..0996ce4b 100644 --- a/tests/steps/route-data.py +++ b/tests/steps/route-data.py @@ -192,6 +192,25 @@ def step_impl(context, jsonpath, thing, value): ## Not a thing we know how to deal with yet. assert True is False +@then('the JSON should have JSONPath "{jsonpath}" greater than "{thing}" "{value}"') +def step_impl(context, jsonpath, thing, value): + if not context.content_json : + ## Apparently no JSON at all... + assert True is False + else: + jsonpath_expr = jsonpath_rw.parse(jsonpath) + res = jsonpath_expr.find(context.content_json) + if not res[0] : + assert True is False + else: + if thing == "integer": + assert res[0].value > int(value) + elif thing == "float": + assert res[0].value > float(value) + else: + ## Not a thing we know how to deal with yet. + assert True is False + @then('the JSON should have some JSONPath "{jsonpath}" with "{thing}" "{value}"') def step_impl(context, jsonpath, thing, value): if not context.content_json : @@ -286,4 +305,4 @@ def step_impl(context, jsonpath, thing, value): ## Not a thing we know how to deal with yet. logging.error("Cannot interpret: {}".format(thing)) assert True is False - assert is_found is True + assert is_found is True \ No newline at end of file From 761afb4cbad06d3b1510384387eeb8a8f8ac6037 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Tue, 24 Aug 2021 17:11:55 -0700 Subject: [PATCH 02/34] update to python 3.7.4 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8d756ac5..59d97f82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ dist: xenial language: python python: - - "3.7.0" + - "3.7.4" # command to install dependencies install: From 34fe85c75d73b793ac42915d27f951851fa6b491 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 08:31:09 -0700 Subject: [PATCH 03/34] remove pytests as they don't apply to the GO version of this api --- .travis.yml | 1 - tests/unit/test_sim_endpoints.py | 60 -------------------------------- 2 files changed, 61 deletions(-) delete mode 100644 tests/unit/test_sim_endpoints.py diff --git a/.travis.yml b/.travis.yml index 59d97f82..32c79cda 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,6 @@ script: - "python biolink/app.py >> log.txt 2>&1 &" - sleep 30 - behave -f progress3 tests/ - - pytest tests/unit/ #after_success: # coveralls diff --git a/tests/unit/test_sim_endpoints.py b/tests/unit/test_sim_endpoints.py deleted file mode 100644 index ff092d80..00000000 --- a/tests/unit/test_sim_endpoints.py +++ /dev/null @@ -1,60 +0,0 @@ -from biolink.app import app - - -class TestSimApi(): - """ - Integration tests for sim endpoints (score, compare, search) - Note it may be better to mock the ontobio output to create - more specific tests - """ - - @classmethod - def setup_class(self): - app.testing = True - self.test_client = app.test_client() - - @classmethod - def teardown_class(self): - self.test_client = None - - def test_search(self): - response = self.test_client.get('/api/sim/search?id=HP:0000739&id=HP:0000740') - assert response.status_code == 200 - assert len(response.json['matches']) > 0 - assert {query['id'] for query in response.json['query']['ids']} == {'HP:0000739', 'HP:0000740'} - - def test_search_w_taxon(self): - response = self.test_client.get('/api/sim/search?id=HP:0000739&id=HP:0000740&taxon=9606') - assert response.status_code == 200 - assert len(response.json['matches']) > 0 - assert {match['taxon']['id'] for match in response.json['matches']} == {'NCBITaxon:9606'} - - def test_compare_post(self): - data = { - 'reference_ids': ['HP:0000739', 'HP:0001831'], - 'query_ids': [ - ['HP:0000716', 'HP:0011307'], - ['HP:0001004'] - ] - } - response = self.test_client.post('/api/sim/compare', json=data) - assert response.status_code == 200 - assert len(response.json['matches']) > 0 - - def test_score_post(self): - data = { - 'id': 'testID', - 'features': [ - { - 'id': 'HP:0000739', - 'isPresent': True - }, - { - 'id': 'HP:0011307', - 'isPresent': False - }, - ] - } - response = self.test_client.post('/api/sim/score', json=data) - assert response.status_code == 200 - assert response.json['simple_score'] > 0 From fe30707afd2e7edbc44dbf96223df8169cac70a8 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 09:04:51 -0700 Subject: [PATCH 04/34] add dockerfile, update .travis --- .travis.yml | 2 +- Dockerfile | 31 +++++++++++++++++++++++++++++++ start-server-beta.sh | 2 +- start-server.sh | 2 +- 4 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 Dockerfile diff --git a/.travis.yml b/.travis.yml index 32c79cda..9723b4b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ before_script: # command to run tests script: - "python biolink/app.py >> log.txt 2>&1 &" - - sleep 30 + - sleep 45 - behave -f progress3 tests/ #after_success: diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..76fd9a06 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +FROM python:3.7-slim + +WORKDIR /biolink-api + +VOLUME /config + +RUN apt-get -y update && apt-get install -y git curl + +COPY requirements.txt ./ +COPY wsgi.py ./ +COPY logging.conf ./ + +COPY biolink ./biolink +COPY biomodel ./biomodel +COPY biowikidata ./biowikidata +COPY causalmodels ./causalmodels +COPY conf ./conf +COPY scigraph ./scigraph +COPY tests ./tests +COPY .git ./.git + +RUN mkdir /biolink-api/scripts +COPY docker ./scripts + +ENV PYTHONPATH "${PYTHONPATH}:/biolink-api" + +ENV PATH="/biolink-api/scripts/:$PATH" + +RUN pip install -r requirements.txt + +EXPOSE 5000 \ No newline at end of file diff --git a/start-server-beta.sh b/start-server-beta.sh index 56403f4c..252ffcf2 100755 --- a/start-server-beta.sh +++ b/start-server-beta.sh @@ -7,4 +7,4 @@ export PYTHONPATH=.:$PYTHONPATH pip install git+https://github.com/biolink/ontobio.git pip install setuptools --upgrade #to avoid bdist_wheel errors pip install -r requirements.txt -gunicorn -k gevent --worker-connections 5 --bind 0.0.0.0:8888 wsgi:app +gunicorn -k gevent --worker-connections 5 --bind 0.0.0.0:5000 wsgi:app diff --git a/start-server.sh b/start-server.sh index 15a7efea..d3752793 100755 --- a/start-server.sh +++ b/start-server.sh @@ -6,4 +6,4 @@ source venv/bin/activate export PYTHONPATH=.:$PYTHONPATH pip install setuptools --upgrade #to avoid bdist_wheel errors pip install -r requirements.txt -gunicorn -k gevent --worker-connections 5 --bind 0.0.0.0:8888 wsgi:app +gunicorn -k gevent --worker-connections 5 --bind 0.0.0.0:5000 wsgi:app From c1ae1c183a001bbb26000e89b6b7a5593305fbe1 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 09:20:02 -0700 Subject: [PATCH 05/34] update requirements test for travis --- requirements.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 6f1035dc..f7833ad6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ prefixcommons>=0.0 -ontobio>=1.7.2 +ontobio>=1.17.5 pip>=9.0.1 wheel>0.25.0 +Flask==1.1.2 flask-restplus>=0.10.1 Flask-SQLAlchemy>=2.1 flask-cors>=0.0 @@ -9,7 +10,7 @@ Werkzeug==0.16.1 pysolr>=3.6.0 matplotlib>=0.0 sparqlwrapper>0.0 -gunicorn>=19.0.0 +gunicorn>=19.9.0 scipy>=0.0 jsonpickle>=0.0 behave>=0.0 From 0815de669a26f650f0106d716324da932cca0168 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 09:46:19 -0700 Subject: [PATCH 06/34] small fixes to README and travis testing --- .travis.yml | 3 ++- README.md | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9723b4b8..7b843644 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,8 @@ before_script: # command to run tests script: - - "python biolink/app.py >> log.txt 2>&1 &" + - "python biolink/app.py" + - tail log.txt - sleep 45 - behave -f progress3 tests/ diff --git a/README.md b/README.md index ebb2d6f8..abb7db17 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ The Gene Ontology API instance is accessible here: https://api.geneontology.org/api/ -Is is an implementation of both the [BioLink Model](https://github.com/biolink/biolink-model) and [BioLink Implementation](https://github.com/biolink/biolink-api) which rely on [Ontobio](https://github.com/biolink/ontobio) +It is an implementation of both the [BioLink Model](https://github.com/biolink/biolink-model) +and [BioLink Implementation](https://github.com/biolink/biolink-api) which rely on [Ontobio](https://github.com/biolink/ontobio) ## Running the server @@ -14,12 +15,12 @@ After checking out this repo: ./start-server.sh ``` -This uses gunicorn and starts a server on 8888 by default. pyvenv is +This uses gunicorn and starts a server on 5000 by default. pyvenv is activated automatically. Then look at: -http://localhost:8888/api/ +http://localhost:5000/api/ For the swagger docs From 81bdd65ca759149842135ccd8d61a2bcf3591c23 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 11:04:43 -0700 Subject: [PATCH 07/34] revert ontobio --- requirements.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index f7833ad6..6f1035dc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,7 @@ prefixcommons>=0.0 -ontobio>=1.17.5 +ontobio>=1.7.2 pip>=9.0.1 wheel>0.25.0 -Flask==1.1.2 flask-restplus>=0.10.1 Flask-SQLAlchemy>=2.1 flask-cors>=0.0 @@ -10,7 +9,7 @@ Werkzeug==0.16.1 pysolr>=3.6.0 matplotlib>=0.0 sparqlwrapper>0.0 -gunicorn>=19.9.0 +gunicorn>=19.0.0 scipy>=0.0 jsonpickle>=0.0 behave>=0.0 From 93ccfec953169961390c5fc00d2e4a4fe2a518ba Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 11:10:48 -0700 Subject: [PATCH 08/34] install ontobio on its own --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 7b843644..0316d6ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ python: # command to install dependencies install: + - pip install git+https://github.com/biolink/ontobio.git - pip install -r requirements.txt before_script: From 87f42b3ad33af21b0ba06821e928c54616629109 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 11:21:20 -0700 Subject: [PATCH 09/34] pin Flask --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 6f1035dc..74dd8ece 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,7 @@ prefixcommons>=0.0 ontobio>=1.7.2 pip>=9.0.1 wheel>0.25.0 +Flask==1.1.2 flask-restplus>=0.10.1 Flask-SQLAlchemy>=2.1 flask-cors>=0.0 From 057679119bc45dae7f8054caa3c76a9786b592ab Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 11:37:01 -0700 Subject: [PATCH 10/34] move to actions --- .github/workflows/make-tests.yaml | 22 ++++++++++++++++++++++ .travis.yml => bkup_travis.yml | 0 2 files changed, 22 insertions(+) create mode 100644 .github/workflows/make-tests.yaml rename .travis.yml => bkup_travis.yml (100%) diff --git a/.github/workflows/make-tests.yaml b/.github/workflows/make-tests.yaml new file mode 100644 index 00000000..2e08a2bc --- /dev/null +++ b/.github/workflows/make-tests.yaml @@ -0,0 +1,22 @@ +name: refresh-readmes +on: [push] +jobs: + run-make: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ github.head_ref }} + - uses: actions/setup-python@v2 + name: setup python + with: + python-version: 3.7 + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: run the app and the behave tests + run: | + python biolink/app.py + sleep 30 + behave -f progress3 tests/ diff --git a/.travis.yml b/bkup_travis.yml similarity index 100% rename from .travis.yml rename to bkup_travis.yml From 7f9a91be1da1edb9af7bba01752857473481e219 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 11:38:14 -0700 Subject: [PATCH 11/34] move to actions --- .github/workflows/{make-tests.yaml => run_tests.yaml} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename .github/workflows/{make-tests.yaml => run_tests.yaml} (92%) diff --git a/.github/workflows/make-tests.yaml b/.github/workflows/run_tests.yaml similarity index 92% rename from .github/workflows/make-tests.yaml rename to .github/workflows/run_tests.yaml index 2e08a2bc..722ddc89 100644 --- a/.github/workflows/make-tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -17,6 +17,6 @@ jobs: pip install -r requirements.txt - name: run the app and the behave tests run: | - python biolink/app.py - sleep 30 + python biolink/app.py + sleep 30 behave -f progress3 tests/ From 3dc9ce01ec7299b463e833703ea18a7b1fdc4c6f Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 11:39:07 -0700 Subject: [PATCH 12/34] move to actions --- .github/workflows/run_tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 722ddc89..20de66c8 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -17,6 +17,6 @@ jobs: pip install -r requirements.txt - name: run the app and the behave tests run: | - python biolink/app.py - sleep 30 + python biolink/app.py + sleep 30 behave -f progress3 tests/ From af893439ae08d7e61522df937fd7a5748f2d455e Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 11:41:33 -0700 Subject: [PATCH 13/34] tweak actions --- .github/workflows/run_tests.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 20de66c8..42c254f4 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -15,6 +15,8 @@ jobs: run: | python -m pip install --upgrade pip pip install -r requirements.txt + export PYTHONPATH=.:$PYTHONPATH + python biolink/app.py - name: run the app and the behave tests run: | python biolink/app.py From f8324ddab25486a167eeeb8e2d312bb41c8272ee Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 11:43:47 -0700 Subject: [PATCH 14/34] app starts, try tests --- .github/workflows/run_tests.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 42c254f4..4c19fbb7 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -16,9 +16,8 @@ jobs: python -m pip install --upgrade pip pip install -r requirements.txt export PYTHONPATH=.:$PYTHONPATH - python biolink/app.py - name: run the app and the behave tests run: | - python biolink/app.py - sleep 30 + python biolink/app.py >> log.txt 2>&1 & + sleep 15 behave -f progress3 tests/ From 3d76048f8f417cc45ce3d1ae5bf2d4e98677bb25 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 11:46:35 -0700 Subject: [PATCH 15/34] app starts, try tests --- .github/workflows/run_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 4c19fbb7..21bbcba3 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -18,6 +18,6 @@ jobs: export PYTHONPATH=.:$PYTHONPATH - name: run the app and the behave tests run: | - python biolink/app.py >> log.txt 2>&1 & + python biolink/app.py & sleep 15 behave -f progress3 tests/ From 7bdcd08c4c65c246e8dfa1e13ef301fdb074306a Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 12:01:11 -0700 Subject: [PATCH 16/34] tweak actions --- .github/workflows/run_tests.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 21bbcba3..7f1613ee 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -18,6 +18,8 @@ jobs: export PYTHONPATH=.:$PYTHONPATH - name: run the app and the behave tests run: | - python biolink/app.py & + ls -al + python ./biolink/app.py & sleep 15 - behave -f progress3 tests/ + cd .. + behave -vf progress3 tests/ From b1893361cde3794e75960cb85b73bf2648038526 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 12:11:32 -0700 Subject: [PATCH 17/34] try reusing pythonpath --- .github/workflows/run_tests.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 7f1613ee..ad1db3a0 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -16,9 +16,6 @@ jobs: python -m pip install --upgrade pip pip install -r requirements.txt export PYTHONPATH=.:$PYTHONPATH - - name: run the app and the behave tests - run: | - ls -al python ./biolink/app.py & sleep 15 cd .. From 64a6cadcbf80fe9b1241af3e16757101ceb95270 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 12:15:41 -0700 Subject: [PATCH 18/34] try reusing pythonpath --- .github/workflows/run_tests.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index ad1db3a0..b4da5b8f 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -18,5 +18,4 @@ jobs: export PYTHONPATH=.:$PYTHONPATH python ./biolink/app.py & sleep 15 - cd .. - behave -vf progress3 tests/ + cd tests && behave -vf From 2c009b10f6b85ac0811013a89513613d01d50704 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 12:19:26 -0700 Subject: [PATCH 19/34] try reusing pythonpath --- .github/workflows/run_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index b4da5b8f..543e882b 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -18,4 +18,4 @@ jobs: export PYTHONPATH=.:$PYTHONPATH python ./biolink/app.py & sleep 15 - cd tests && behave -vf + cd tests && behave -v From b5be238c5831978e3147809fe13aa7bb72e094dd Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 12:27:43 -0700 Subject: [PATCH 20/34] formatting of tests --- .github/workflows/run_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 543e882b..94ed636b 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -18,4 +18,4 @@ jobs: export PYTHONPATH=.:$PYTHONPATH python ./biolink/app.py & sleep 15 - cd tests && behave -v + cd tests && behave plain From 24b11dd7672e90bef8a328730bc8c0032d1318d3 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 12:28:24 -0700 Subject: [PATCH 21/34] formatting of tests --- .github/workflows/run_tests.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 94ed636b..a209643c 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -15,6 +15,7 @@ jobs: run: | python -m pip install --upgrade pip pip install -r requirements.txt + - name: Run Tests export PYTHONPATH=.:$PYTHONPATH python ./biolink/app.py & sleep 15 From e5d48fc35e5f3a948ee6a846d21839fa1376f9b3 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 12:30:33 -0700 Subject: [PATCH 22/34] formatting of tests --- .github/workflows/run_tests.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index a209643c..25f87aed 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -16,6 +16,7 @@ jobs: python -m pip install --upgrade pip pip install -r requirements.txt - name: Run Tests + run: | export PYTHONPATH=.:$PYTHONPATH python ./biolink/app.py & sleep 15 From b7bec2fee70eacb87b0571c6ade8876996b74b23 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 12:32:44 -0700 Subject: [PATCH 23/34] formatting of tests --- .github/workflows/run_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 25f87aed..4032402b 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -20,4 +20,4 @@ jobs: export PYTHONPATH=.:$PYTHONPATH python ./biolink/app.py & sleep 15 - cd tests && behave plain + cd tests && behave -f plain From 09868da8612b7bd984e7ca57b74142b4914c36f8 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 12:40:21 -0700 Subject: [PATCH 24/34] formatting of tests --- .github/workflows/run_tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 4032402b..7f4f52aa 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -1,7 +1,7 @@ -name: refresh-readmes +name: Run-tests on: [push] jobs: - run-make: + run-pr-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 From f2004bc120d4e87a4132a71fe5964efab6a04a58 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 25 Aug 2021 14:50:08 -0700 Subject: [PATCH 25/34] got working from a docker container --- Dockerfile | 11 ++++++++++- biolink/app.py | 16 ++++++++++------ wsgi.py | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 76fd9a06..bc7477d7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,4 +28,13 @@ ENV PATH="/biolink-api/scripts/:$PATH" RUN pip install -r requirements.txt -EXPOSE 5000 \ No newline at end of file +ENTRYPOINT ["python"] +CMD ["biolink/app.py"] + +EXPOSE 5000 + + +# docker build -t name_of_image folder_containing_dockerfile (names image and stores it) +# docker run -d --name sierra_test -p 5000:5000 go_api (expose ports and name the container) +# docker rm sierra_test (removes image) +# docker port sierra_test (see the port mapping) diff --git a/biolink/app.py b/biolink/app.py index cfd8f5f7..de76df88 100755 --- a/biolink/app.py +++ b/biolink/app.py @@ -18,7 +18,7 @@ app = Flask(__name__) app.wsgi_app = ProxyFix(app.wsgi_app) -#app = Flask(__name__) +# app = Flask(__name__) app.url_map.strict_slashes = False CORS(app) log_file_path = path.join(path.dirname(path.abspath(__file__)), '../logging.conf') @@ -26,8 +26,8 @@ log = logging.getLogger(__name__) -#def configure_app(flask_app): -#app.config['SERVER_NAME'] = settings.FLASK_SERVER_NAME +# def configure_app(flask_app): +# app.config['SERVER_NAME'] = settings.FLASK_SERVER_NAME app.config['SQLALCHEMY_DATABASE_URI'] = settings.SQLALCHEMY_DATABASE_URI app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = settings.SQLALCHEMY_TRACK_MODIFICATIONS app.config['SWAGGER_UI_DOC_EXPANSION'] = settings.RESTPLUS_SWAGGER_UI_DOC_EXPANSION @@ -36,7 +36,7 @@ app.config['ERROR_404_HELP'] = settings.RESTPLUS_ERROR_404_HELP app.config['ERROR_INCLUDE_MESSAGE'] = settings.ERROR_INCLUDE_MESSAGE -#def initialize_app(flask_app): +# def initialize_app(flask_app): # configure_app(flask_app) blueprint = Blueprint('api', __name__, url_prefix='/api') @@ -60,6 +60,7 @@ app.register_blueprint(blueprint) db.init_app(app) + def preload_ontologies(): ontologies = settings.get_biolink_config().get('ontologies') for ontology in ontologies: @@ -68,15 +69,18 @@ def preload_ontologies(): log.info("Loading {}".format(ontology['id'])) get_ontology(handle) + @app.route("/") def hello(): return render_template('index.html', base_url=request.base_url) + def main(): - #initialize_app(app) + # initialize_app(app) preload_ontologies() log.info('>>>>> Starting development server at http://{}/api/ <<<<<'.format(app.config['SERVER_NAME'])) - app.run(debug=settings.FLASK_DEBUG, use_reloader=settings.FLASK_USE_RELOADER) + app.run(port=5000, debug=settings.FLASK_DEBUG, use_reloader=settings.FLASK_USE_RELOADER, host='0.0.0.0') + if __name__ == "__main__": main() diff --git a/wsgi.py b/wsgi.py index 35b198ac..51538722 100644 --- a/wsgi.py +++ b/wsgi.py @@ -1,4 +1,4 @@ from biolink.app import app if __name__ == "__main__": - app.run() + app.run(host='0.0.0.0', port=5000, debug=True) From 9a4e46c6b3c7b0bcfbf5293ae12fbba7e9154a65 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 1 Sep 2021 13:34:35 -0700 Subject: [PATCH 26/34] format fixes --- README.md | 4 +- biolink/api/bio/association_counts.py | 1 + biolink/api/bio/closure_bins.py | 3 +- biolink/api/bio/endpoints/bioentity.py | 35 +++++++++- biolink/api/cam/endpoints/cam_endpoint.py | 6 +- biolink/api/restplus.py | 6 +- biolink/settings.py | 2 + conf/routes.yaml | 81 ----------------------- docs/prod.md | 0 9 files changed, 51 insertions(+), 87 deletions(-) create mode 100644 docs/prod.md diff --git a/README.md b/README.md index abb7db17..9f6f0125 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ http://localhost:5000/api/ For the swagger docs -To run in development mode: +To run locally in development mode: ``` pyvenv venv @@ -34,5 +34,7 @@ export PYTHONPATH=.:$PYTHONPATH python biolink/app.py ``` +Production AWS environment details + [Production AWS Details](docs/prod.md). diff --git a/biolink/api/bio/association_counts.py b/biolink/api/bio/association_counts.py index 71205a85..7e3e3f1b 100644 --- a/biolink/api/bio/association_counts.py +++ b/biolink/api/bio/association_counts.py @@ -265,6 +265,7 @@ def parse_taxon_pivot(taxon_pivot, key): counts_map[taxon] = counts return counts_map + def merge_counts(d1, d2): d = {} d1_key_set = set(x for x in d1.keys()) diff --git a/biolink/api/bio/closure_bins.py b/biolink/api/bio/closure_bins.py index 6c6f92a7..8a95d469 100644 --- a/biolink/api/bio/closure_bins.py +++ b/biolink/api/bio/closure_bins.py @@ -27,6 +27,7 @@ 'CL:0000000PHENOTYPE': 'Cellular' } + def create_closure_bin(fcmap={}): """ Given a facet count dict from golr_query (i.e. map of class ID to count) @@ -42,7 +43,7 @@ def create_closure_bin(fcmap={}): for curie, label in closure_map.items(): lmap[label] = 0 idmap[curie] = 0 - for k,v in fcmap.items(): + for k, v in fcmap.items(): if k in closure_map: label = closure_map[k] diff --git a/biolink/api/bio/endpoints/bioentity.py b/biolink/api/bio/endpoints/bioentity.py index 7313c501..cf068aad 100644 --- a/biolink/api/bio/endpoints/bioentity.py +++ b/biolink/api/bio/endpoints/bioentity.py @@ -25,7 +25,9 @@ basic_parser = api.parser() basic_parser.add_argument('start', type=int, required=False, default=0, help='beginning row') basic_parser.add_argument('rows', type=int, required=False, default=100, help='number of rows') -basic_parser.add_argument('evidence', action='append', help='Object id, e.g. ECO:0000501 (for IEA; Includes inferred by default) or a specific publication or other supporting object, e.g. ZFIN:ZDB-PUB-060503-2') +basic_parser.add_argument('evidence', action='append', help='Object id, e.g. ECO:0000501 (for IEA; Includes inferred ' + 'by default) or a specific publication or other supporting ' + 'object, e.g. ZFIN:ZDB-PUB-060503-2') core_parser = api.parser() @@ -98,6 +100,7 @@ def get(self, id): obj = scigraph.bioobject(id) return obj + @api.param('id', 'id, e.g. NCBIGene:84570') @api.param('type', 'bioentity type', enum=categories) class GenericObjectByType(Resource): @@ -147,6 +150,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'id, e.g. NCBIGene:3630. Equivalent IDs can be used with same results'}) class GeneInteractions(Resource): @@ -172,6 +176,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'id, e.g. NCBIGene:3630. Equivalent IDs can be used with same results'}) class GeneHomologAssociations(Resource): @@ -200,6 +205,7 @@ def get(self, id): **homolog_args ) + @api.doc(params={'id': 'CURIE identifier of gene, e.g. NCBIGene:4750. Equivalent IDs can be used with same results'}) class GenePhenotypeAssociations(Resource): @@ -227,6 +233,7 @@ def get(self, id): return results + @api.doc(params={'id': 'CURIE identifier of gene, e.g. NCBIGene:4750. Equivalent IDs can be used with same results'}) class GeneDiseaseAssociations(Resource): @@ -251,6 +258,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of gene, e.g. NCBIGene:50846. Equivalent IDs can be used with same results'}) class GenePathwayAssociations(Resource): @@ -269,6 +277,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of gene, e.g. NCBIGene:4750. Equivalent IDs can be used with same results'}) class GeneExpressionAssociations(Resource): @@ -287,6 +296,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of gene, e.g. NCBIGene:13434'}) class GeneAnatomyAssociations(Resource): @@ -305,6 +315,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of gene, e.g. ZFIN:ZDB-GENE-980526-166'}) class GeneGenotypeAssociations(Resource): @@ -324,6 +335,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'id, e.g. NCBIGene:6469. Equivalent IDs can be used with same results'}) class GeneFunctionAssociations(Resource): @@ -374,6 +386,7 @@ def get(self, id): assocs = pr_assocs return assocs + @api.doc(params={'id': 'CURIE identifier of gene, e.g. NCBIGene:4750'}) class GenePublicationAssociations(Resource): @@ -393,6 +406,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of gene, e.g. NCBIGene:17988'}) class GeneModelAssociations(Resource): @@ -413,6 +427,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of gene, e.g. NCBIGene:4750'}) class GeneOrthologPhenotypeAssociations(Resource): @@ -468,6 +483,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of gene, e.g. HGNC:10896'}) class GeneVariantAssociations(Resource): @@ -487,6 +503,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of gene, e.g. HGNC:613, HGNC:11025'}) class GeneCaseAssociations(Resource): @@ -505,6 +522,7 @@ def get(self, id): **core_parser.parse_args() ) + @api.doc(params={'id': 'CURIE identifier of disease, e.g. OMIM:605543, Orphanet:1934, DOID:678. Equivalent IDs can be used with same results'}) class DiseasePhenotypeAssociations(Resource): @@ -530,6 +548,7 @@ def get(self, id): fcs['object_closure'] = slim_facet return results + @api.doc(params={'id': 'CURIE identifier of disease, e.g. OMIM:605543, DOID:678. Equivalent IDs can be used with same results'}) class DiseaseGeneAssociations(Resource): @@ -571,6 +590,7 @@ def get(self, id): """ return condition_to_drug(id) + @api.doc(params={'id': 'CURIE identifier of disease, e.g. OMIM:605543, DOID:678. Equivalent IDs can be used with same results'}) class DiseaseModelAssociations(Resource): @@ -604,6 +624,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of disease, e.g. OMIM:605543, DOID:678. Equivalent IDs can be used with same results'}) @api.doc(params={'taxon': 'CURIE of organism taxonomy class to constrain models, e.g NCBITaxon:10090 (M. musculus).\n\n Higher level taxa may be used'}) @api.deprecated @@ -629,6 +650,7 @@ def get(self, id, taxon): **core_parser.parse_args() ) + @api.doc(params={'id': 'CURIE identifier of disease, e.g. Orphanet:399158, DOID:0080008. Equivalent IDs can be used with same results'}) class DiseaseGenotypeAssociations(Resource): @@ -649,6 +671,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of disease, e.g. OMIM:605543, DOID:678. Equivalent IDs can be used with same results'}) class DiseasePublicationAssociations(Resource): @@ -668,6 +691,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of disease, e.g. DOID:4450. Equivalent IDs can be used with same results'}) class DiseasePathwayAssociations(Resource): @@ -686,6 +710,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of disease, e.g. OMIM:605543, DOID:678. Equivalent IDs can be used with same results'}) class DiseaseVariantAssociations(Resource): @@ -706,6 +731,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'CURIE identifier of disease, e.g. MONDO:0007103, MONDO:0010918. Equivalent IDs can be used with same results'}) class DiseaseCaseAssociations(Resource): @@ -725,6 +751,7 @@ def get(self, id): **core_parser.parse_args() ) + @api.doc(params={'id': 'CURIE identifier of phenotype, e.g. MP:0008521. Equivalent IDs can be used with same results'}) class PhenotypeAnatomyAssociations(Resource): # Note: This depends on https://github.com/biolink/biolink-api/issues/122 @@ -743,6 +770,7 @@ def get(self, id): objs = scigraph.phenotype_to_entity_list(id) return objs + @api.doc(params={'id': 'CURIE identifier of phenotype, e.g. HP:0007359. Equivalent IDs can be used with same results'}) class PhenotypeDiseaseAssociations(Resource): @@ -811,6 +839,7 @@ def get(self, id, taxid): user_agent=USER_AGENT ) + @api.doc(params={'id': 'Pheno class CURIE identifier, e.g WBPhenotype:0000180 (axon morphology variant), MP:0001569 (abnormal circulating bilirubin level)'}) class PhenotypeGenotypeAssociations(Resource): @@ -831,6 +860,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'Pheno class CURIE identifier, e.g WBPhenotype:0000180 (axon morphology variant), MP:0001569 (abnormal circulating bilirubin level)'}) class PhenotypePublicationAssociations(Resource): @@ -850,6 +880,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'Pheno class CURIE identifier, e.g MP:0001569 (abnormal circulating bilirubin level)'}) class PhenotypePathwayAssociations(Resource): @@ -869,6 +900,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'Pheno class CURIE identifier, e.g WBPhenotype:0000180 (axon morphology variant), MP:0001569 (abnormal circulating bilirubin level)'}) class PhenotypeVariantAssociations(Resource): @@ -889,6 +921,7 @@ def get(self, id): **args ) + @api.doc(params={'id': 'Pheno class CURIE identifier, e.g HP:0011951 (Aspiration pneumonia), HP:0002450 (Abnormal motor neuron morphology)'}) class PhenotypeCaseAssociations(Resource): diff --git a/biolink/api/cam/endpoints/cam_endpoint.py b/biolink/api/cam/endpoints/cam_endpoint.py index 2268d9e5..e9cd6b48 100644 --- a/biolink/api/cam/endpoints/cam_endpoint.py +++ b/biolink/api/cam/endpoints/cam_endpoint.py @@ -12,6 +12,7 @@ parser.add_argument('title', help='string to search for in title of model') parser.add_argument('contributor', help='string to search for in contributor of model') + class ModelCollection(Resource): #@api.expect(parser) @@ -28,6 +29,7 @@ def get(self): FILTER(?p != json_model:) }""", limit=1000) + class ModelQuery(Resource): @api.expect(parser) @@ -42,7 +44,8 @@ def get(self): sparql = mq.gen_sparql() return lego_query(sparql, limit=100) - + + class ModelProperties(Resource): @api.expect(parser) @@ -58,6 +61,7 @@ def get(self): FILTER(?p != json_model:) }""", limit=1000) + class ModelContributors(Resource): #@api.expect(parser) diff --git a/biolink/api/restplus.py b/biolink/api/restplus.py index 9a916cbf..2e90ee6f 100644 --- a/biolink/api/restplus.py +++ b/biolink/api/restplus.py @@ -9,8 +9,10 @@ api = Api(version='0.1.1', title='Gene Ontology API', license='BSD3', - contact='laurent.albou@lbl.gov', - description='Gene Ontology API based on the BioLink Model, an integration layer for linked biological objects.\n\n __Source:__ https://github.com/geneontology/biolink-api') + contact='smoxon@lbl.gov', + description='Gene Ontology API based on the BioLink Model, an integration ' + 'layer for linked biological objects.\n\n __Source:__ ' + 'https://github.com/geneontology/biolink-api') @api.errorhandler diff --git a/biolink/settings.py b/biolink/settings.py index ba91b228..09e34393 100644 --- a/biolink/settings.py +++ b/biolink/settings.py @@ -25,6 +25,7 @@ biolink_config = None route_mapping = None + def get_biolink_config(): global biolink_config if biolink_config is None: @@ -32,6 +33,7 @@ def get_biolink_config(): biolink_config = yaml.load(f, Loader=yaml.FullLoader) return biolink_config + def get_route_mapping(): global route_mapping if route_mapping is None: diff --git a/conf/routes.yaml b/conf/routes.yaml index c697c644..5c992225 100644 --- a/conf/routes.yaml +++ b/conf/routes.yaml @@ -43,30 +43,6 @@ route_mapping: - route: /between// resource: biolink.api.link.endpoints.associations_from.AssociationsBetween - # - name: cam - # description: Operations on GO Causal Activity Models (GO-CAMs) - # routes: - # - route: /model - # resource: biolink.api.cam.endpoints.cam_endpoint.ModelCollection - # - route: /model/query - # resource: biolink.api.cam.endpoints.cam_endpoint.ModelQuery - # - route: /model/properties - # resource: biolink.api.cam.endpoints.cam_endpoint.ModelProperties - # - route: /model/contributors - # resource: biolink.api.cam.endpoints.cam_endpoint.ModelContributors - # - route: /instances - # resource: biolink.api.cam.endpoints.cam_endpoint.ModelInstances - # - route: /model/property_values - # resource: biolink.api.cam.endpoints.cam_endpoint.ModelPropertyValues - # - route: /model/ - # resource: biolink.api.cam.endpoints.cam_endpoint.ModelObject - # - route: /instance/ - # resource: biolink.api.cam.endpoints.cam_endpoint.InstanceObject - # - route: /activity - # resource: biolink.api.cam.endpoints.cam_endpoint.ActivityCollection - # - route: /physical_interaction - # resource: biolink.api.cam.endpoints.cam_endpoint.PhysicalInteraction - - name: bioentityset description: Operations over sets of entities routes: @@ -79,26 +55,12 @@ route_mapping: - route: /overrepresentation resource: biolink.api.entityset.endpoints.overrepresentation.OverRepresentation - # - name: bioentityset/homologs - # description: Map gene IDs to their homologs - # routes: - # - route: / - # resource: biolink.api.entityset.endpoints.geneset_homologs.EntitySetHomologs - - name: bioentityset/slimmer description: maps a set of entities to a slim routes: - route: /function resource: biolink.api.entityset.endpoints.slimmer.EntitySetFunctionSlimmer - # - name: evidence/graph - # description: Operations on evidence graphs - # routes: - # - route: / - # resource: biolink.api.evidence.endpoints.graph.EvidenceGraphObject - # - route: //image - # resource: biolink.api.evidence.endpoints.graph.EvidenceGraphImage - - name: graph description: Operations over data graphs routes: @@ -117,24 +79,6 @@ route_mapping: - route: /contract/ resource: biolink.api.identifier.endpoints.prefixes.PrefixContract - # - name: mart - # description: Perform bulk operations - # routes: - # - route: /gene// - # resource: biolink.api.mart.endpoints.mart.MartGeneAssociationsResource - # - route: /paralog// - # resource: biolink.api.mart.endpoints.mart.MartParalogAssociationsResource - # - route: /ortholog// - # resource: biolink.api.mart.endpoints.mart.MartOrthologAssociationsResource - - # - name: ontol - # description: extract a subgraph from an ontology - # routes: - # - route: /subgraph// - # resource: biolink.api.ontol.endpoints.subgraph.ExtractOntologySubgraphResource - # - route: /information_content/// - # resource: biolink.api.ontol.endpoints.termstats.InformationContentResource - - name: ontol/labeler description: Assign labels to IDs routes: @@ -159,20 +103,6 @@ route_mapping: - route: /shared// resource: biolink.api.ontol.endpoints.ontology_endpoint.OntologyTermsSharedAncestor - # - name: owl/ontology - # description: OWL-level operations on an ontology - # routes: - # - route: /dlquery/ - # resource: biolink.api.owl.endpoints.ontology.DLQuery - # - route: /sparql/ - # resource: biolink.api.owl.endpoints.ontology.SparqlQuery - - # - name: pair/sim - # description: pairwise similarity between two entities - # routes: - # - route: /jaccard// - # resource: biolink.api.pair.endpoints.pairsim.PairSimJaccardResource - - name: search description: Search for entities routes: @@ -180,14 +110,3 @@ route_mapping: resource: biolink.api.search.endpoints.entitysearch.SearchEntities - route: /entity/autocomplete/ resource: biolink.api.search.endpoints.entitysearch.Autocomplete - - # Those routes are producing continuous WORKER TIMEOUT - # - name: sim - # description: Perform semantic similarity, ranking, and classification - # routes: - # - route: /score - # resource: biolink.api.sim.endpoints.annotation_score.AnnotationScore - # - route: /search - # resource: biolink.api.sim.endpoints.semanticsim.SimSearch - # - route: /compare - # resource: biolink.api.sim.endpoints.semanticsim.SimCompare diff --git a/docs/prod.md b/docs/prod.md new file mode 100644 index 00000000..e69de29b From 909c0820ea397f377e9b060cea7a5505a400cc04 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 19 Jan 2022 11:07:18 -0800 Subject: [PATCH 27/34] fix Dockerfile to echo biolink-api dir structure --- biolink/api/search/endpoints/entitysearch.py | 3 ++- biolink/datamodel/serializers.py | 9 ++++++--- conf/config.yaml | 10 ++-------- docker/start-server | 6 ++++++ 4 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 docker/start-server diff --git a/biolink/api/search/endpoints/entitysearch.py b/biolink/api/search/endpoints/entitysearch.py index 98e6573d..01f7a55f 100644 --- a/biolink/api/search/endpoints/entitysearch.py +++ b/biolink/api/search/endpoints/entitysearch.py @@ -118,7 +118,8 @@ def get(self, term): Returns list of matching concepts or entities using lexical search """ args = simple_parser.parse_args() - q = GolrSearchQuery(term, user_agent=USER_AGENT, **args) + print(args) + q = GolrSearchQuery(term, user_agent=USER_AGENT, **args, url='https://golr.monarchinitiative.org/solr/') #, url='https://solr.monarchinitiative.org/solr/search') results = q.autocomplete() return results diff --git a/biolink/datamodel/serializers.py b/biolink/datamodel/serializers.py index 4ff01def..ff929896 100644 --- a/biolink/datamodel/serializers.py +++ b/biolink/datamodel/serializers.py @@ -179,9 +179,12 @@ # A search result that returns a set of associations association_results = api.inherit('AssociationResults', search_result, { - 'associations': fields.List(fields.Nested(association), description='Complete representation of full association object, plus evidence'), - 'compact_associations': fields.List(fields.Nested(compact_association_set), description='Compact representation in which objects (e.g. phenotypes) are collected for subject-predicate pairs'), - 'objects': fields.List(fields.String, description='List of distinct objects used') + 'associations': fields.List(fields.Nested(association), + description='Complete representation of full association object, plus evidence'), + 'compact_associations': fields.List(fields.Nested(compact_association_set), + description='Compact representation in which objects (e.g. phenotypes) are collected for subject-predicate pairs'), + 'objects': fields.List(fields.String, + description='List of distinct objects used') }) d2p_association = api.inherit('D2PAssociation', association, { diff --git a/conf/config.yaml b/conf/config.yaml index e4b90ed1..43b21bbf 100644 --- a/conf/config.yaml +++ b/conf/config.yaml @@ -2,7 +2,7 @@ solr_assocs: url: "https://solr.monarchinitiative.org/solr/golr" timeout: 30 amigo_solr_assocs: - url: "http://golr.berkeleybop.org" + url: "http://golr.berkeleybop.org/" timeout: 30 solr_search: url: "https://solr.monarchinitiative.org/solr/search" @@ -11,7 +11,7 @@ amigo_solr_search: url: "http://golr.berkeleybop.org" timeout: 30 sparql: - url: "http://sparql.hegroup.org/sparql" + url: "http://rdf-testing.geneontology.io/blazegraph/#query" timeout: 30 scigraph_ontology: url: "https://scigraph-ontology.monarchinitiative.org/scigraph/" @@ -28,15 +28,9 @@ ontologies: - id: hp handle: hp pre_load: false -# - id: mp -# handle: mp -# pre_load: false - id: uberon handle: uberon pre_load: false - id: mondo handle: mondo pre_load: false -# - id: monarch -# handle: data/monarch.json -# pre_load: false diff --git a/docker/start-server b/docker/start-server new file mode 100644 index 00000000..da5408e5 --- /dev/null +++ b/docker/start-server @@ -0,0 +1,6 @@ +#!/bin/sh + +cp /config/biolink-config.yaml /biolink-api/conf/config.yaml +cp /config/ontobio-config.yaml /usr/local/lib/python3.7/site-packages/ontobio/config.yaml + +gunicorn "$@" \ No newline at end of file From dafd8acd9e16a98dc657b94074840ea96db51727 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 16 Feb 2022 19:58:20 -0800 Subject: [PATCH 28/34] fixing up test branch for running on AWS --- Dockerfile | 6 +++--- biolink/app.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index bc7477d7..abfab699 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ COPY tests ./tests COPY .git ./.git RUN mkdir /biolink-api/scripts -COPY docker ./scripts +# COPY docker ./scripts ENV PYTHONPATH "${PYTHONPATH}:/biolink-api" @@ -31,10 +31,10 @@ RUN pip install -r requirements.txt ENTRYPOINT ["python"] CMD ["biolink/app.py"] -EXPOSE 5000 +EXPOSE 8888 # docker build -t name_of_image folder_containing_dockerfile (names image and stores it) -# docker run -d --name sierra_test -p 5000:5000 go_api (expose ports and name the container) +# docker run -d --name sierra_test -p 8888:8888 go_api (expose ports and name the container) # docker rm sierra_test (removes image) # docker port sierra_test (see the port mapping) diff --git a/biolink/app.py b/biolink/app.py index de76df88..5a81479c 100755 --- a/biolink/app.py +++ b/biolink/app.py @@ -79,7 +79,7 @@ def main(): # initialize_app(app) preload_ontologies() log.info('>>>>> Starting development server at http://{}/api/ <<<<<'.format(app.config['SERVER_NAME'])) - app.run(port=5000, debug=settings.FLASK_DEBUG, use_reloader=settings.FLASK_USE_RELOADER, host='0.0.0.0') + app.run(port=8888, debug=settings.FLASK_DEBUG, use_reloader=settings.FLASK_USE_RELOADER, host='0.0.0.0') if __name__ == "__main__": From f7708a79fc9fa3d60ece1a5973d39387015469b2 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 16 Feb 2022 20:29:34 -0800 Subject: [PATCH 29/34] change 5000 to 8888 for tests to run on AWs --- tests/environment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/environment.py b/tests/environment.py index 2faac7ed..288d8dd5 100644 --- a/tests/environment.py +++ b/tests/environment.py @@ -11,7 +11,7 @@ def before_all(context): ## Determine the server target. ##context.target = 'http://api.monarchinitiative.org/api' - context.target = 'http://127.0.0.1:5000/api' + context.target = 'http://127.0.0.1:8888/api' context.content_type = None ## Do this after completing everything. From c3037c3361b405dda5bb711432759d028e97f132 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 23 Feb 2022 16:59:09 -0800 Subject: [PATCH 30/34] change venv commands a little to accommodate ubuntu on AWs --- start-server.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/start-server.sh b/start-server.sh index d3752793..42bd31a6 100755 --- a/start-server.sh +++ b/start-server.sh @@ -1,9 +1,8 @@ # http://gunicorn-docs.readthedocs.io/en/latest/design.html # Generally we recommend (2 x $num_cores) + 1 as the number of workers to start off with # http://stackoverflow.com/questions/35837786/how-to-run-flask-with-gunicorn-in-multithreaded-mode -pyvenv venv -source venv/bin/activate -export PYTHONPATH=.:$PYTHONPATH -pip install setuptools --upgrade #to avoid bdist_wheel errors +python3 -m venv . +source ./bin/activate pip install -r requirements.txt +export PYTHONPATH=.:$PYTHONPATH gunicorn -k gevent --worker-connections 5 --bind 0.0.0.0:5000 wsgi:app From f6dd788fa4ed67426cca4def4134aeb68e3ce332 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Thu, 24 Feb 2022 13:06:03 -0800 Subject: [PATCH 31/34] fix itsdangerous to 2.1.1 after update --- requirements.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 74dd8ece..e01db58d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ prefixcommons>=0.0 -ontobio>=1.7.2 +ontobio>=2.7.16 +itsdangerous==2.0.1 pip>=9.0.1 wheel>0.25.0 Flask==1.1.2 @@ -10,7 +11,7 @@ Werkzeug==0.16.1 pysolr>=3.6.0 matplotlib>=0.0 sparqlwrapper>0.0 -gunicorn>=19.0.0 +gunicorn==19.9.0 scipy>=0.0 jsonpickle>=0.0 behave>=0.0 @@ -22,4 +23,4 @@ cachier>=0.1.26 flask-limiter>=0.0 gevent>=0.0 gitpython>=2.1.11 -mygene==3.1.0 +mygene==3.1.0 \ No newline at end of file From 89a2ed32058c3b91aa0efba121cc4f4dc3632db8 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 2 Mar 2022 14:54:15 -0800 Subject: [PATCH 32/34] clean up PEP in route to debugging dependencies --- biolink/api/bio/endpoints/bioentity.py | 1 - biolink/api/entityset/endpoints/slimmer.py | 50 +-- .../api/ontol/endpoints/ontology_endpoint.py | 372 +++++++----------- biolink/api/ontol/endpoints/slimmer.py | 34 -- biolink/app.py | 4 +- biolink/error_handlers.py | 79 ++-- biolink/ontology/ontology_manager.py | 1 + wsgi.py | 2 +- 8 files changed, 213 insertions(+), 330 deletions(-) delete mode 100644 biolink/api/ontol/endpoints/slimmer.py diff --git a/biolink/api/bio/endpoints/bioentity.py b/biolink/api/bio/endpoints/bioentity.py index cf068aad..89b6affd 100644 --- a/biolink/api/bio/endpoints/bioentity.py +++ b/biolink/api/bio/endpoints/bioentity.py @@ -1,6 +1,5 @@ import logging -from flask import request from flask_restplus import Resource, inputs, marshal from biolink.datamodel.serializers import node, named_object, bio_object,\ association_results, association, disease_object, d2p_association_results diff --git a/biolink/api/entityset/endpoints/slimmer.py b/biolink/api/entityset/endpoints/slimmer.py index 4e30047a..cbd52fc0 100644 --- a/biolink/api/entityset/endpoints/slimmer.py +++ b/biolink/api/entityset/endpoints/slimmer.py @@ -1,14 +1,8 @@ import logging - -from flask import request from flask_restplus import Resource, inputs -from biolink.datamodel.serializers import association from ontobio.golr.golr_associations import map2slim -from ontobio.config import Config, get_config from biolink.api.restplus import api -from scigraph.scigraph_util import SciGraph from biolink import USER_AGENT -from biolink.settings import get_biolink_config from biothings_client import get_client @@ -17,22 +11,33 @@ INVOLVED_IN = 'involved_in' ACTS_UPSTREAM_OF_OR_WITHIN = 'acts_upstream_of_or_within' -FUNCTION_CATEGORY='function' -PHENOTYPE_CATEGORY='phenotype' -ANATOMY_CATEGORY='anatomy' +FUNCTION_CATEGORY = 'function' +PHENOTYPE_CATEGORY = 'phenotype' +ANATOMY_CATEGORY = 'anatomy' parser = api.parser() -parser.add_argument('subject', action='append', help='Entity ids to be examined, e.g. NCBIGene:9342, NCBIGene:7227, NCBIGene:8131, NCBIGene:157570, NCBIGene:51164, NCBIGene:6689, NCBIGene:6387', required=True) -parser.add_argument('slim', action='append', help='Map objects up (slim) to a higher level category. Value can be ontology class ID (IMPLEMENTED) or subset ID (TODO)', required=True) -parser.add_argument('exclude_automatic_assertions', type=inputs.boolean, default=False, help='If set, excludes associations that involve IEAs (ECO:0000501)') +parser.add_argument('subject', action='append', + help='Entity ids to be examined, e.g. NCBIGene:9342, NCBIGene:7227, NCBIGene:8131,' + + 'NCBIGene:157570, NCBIGene:51164, NCBIGene:6689, NCBIGene:6387', + required=True) +parser.add_argument('slim', action='append', + help='Map objects up (slim) to a higher level category. Value can be ontology class' + + 'ID (IMPLEMENTED) or subset ID (TODO)', + required=True) +parser.add_argument('exclude_automatic_assertions', type=inputs.boolean, default=False, + help='If set, excludes associations that involve IEAs (ECO:0000501)') parser.add_argument('rows', type=int, required=False, default=100, help='number of rows') parser.add_argument('start', type=int, required=False, help='beginning row') -@api.param('relationship_type', "relationship type ('{}' or '{}')".format(INVOLVED_IN, ACTS_UPSTREAM_OF_OR_WITHIN), enum=[INVOLVED_IN, ACTS_UPSTREAM_OF_OR_WITHIN], default=ACTS_UPSTREAM_OF_OR_WITHIN) -class EntitySetFunctionSlimmer(Resource): +@api.param('relationship_type', "relationship type ('{}' or '{}')".format(INVOLVED_IN, ACTS_UPSTREAM_OF_OR_WITHIN), + enum=[INVOLVED_IN, ACTS_UPSTREAM_OF_OR_WITHIN], default=ACTS_UPSTREAM_OF_OR_WITHIN) +class EntitySetFunctionSlimmer(Resource): function_parser = parser.copy() - function_parser.add_argument('relationship_type', choices=[INVOLVED_IN, ACTS_UPSTREAM_OF_OR_WITHIN], default=ACTS_UPSTREAM_OF_OR_WITHIN, help="relationship type ('{}' or '{}')".format(INVOLVED_IN, ACTS_UPSTREAM_OF_OR_WITHIN)) + function_parser.add_argument('relationship_type', choices=[INVOLVED_IN, ACTS_UPSTREAM_OF_OR_WITHIN], + default=ACTS_UPSTREAM_OF_OR_WITHIN, + help="relationship type ('{}' or '{}')".format(INVOLVED_IN, + ACTS_UPSTREAM_OF_OR_WITHIN)) @api.expect(function_parser) def get(self): @@ -44,17 +49,16 @@ def get(self): del args['slim'] subjects = args.get('subject') del args['subject'] + logging.info(args) - # Note that GO currently uses UniProt as primary ID for some sources: https://github.com/biolink/biolink-api/issues/66 + # Note that GO currently uses UniProt as primary ID + # for some sources: https://github.com/biolink/biolink-api/issues/66 # https://github.com/monarch-initiative/dipper/issues/461 - sg_dev = SciGraph(get_biolink_config()['scigraph_data']['url']) - subjects = [x.replace('WormBase:', 'WB:') if 'WormBase:' in x else x for x in subjects] slimmer_subjects = [] for s in subjects: if 'HGNC:' in s or 'NCBIGene:' in s or 'ENSEMBL:' in s: - #prots = sg_dev.gene_to_uniprot_proteins(s) prots = gene_to_uniprot_from_mygene(s) if len(prots) == 0: prots = [s] @@ -78,7 +82,6 @@ def get(self): proteinId = association['subject']['id'] if taxon == 'NCBITaxon:9606' and proteinId.startswith('UniProtKB:'): if proteinId not in checked: - #genes = sg_dev.uniprot_protein_to_genes(proteinId) genes = uniprot_to_gene_from_mygene(proteinId) for gene in genes: if gene.startswith('HGNC'): @@ -89,6 +92,7 @@ def get(self): return results + class EntitySetAnatomySlimmer(Resource): @api.expect(parser) @@ -112,6 +116,7 @@ def get(self): ) return results + class EntitySetPhenotypeSlimmer(Resource): @api.expect(parser) @@ -124,7 +129,6 @@ def get(self): del args['slim'] subjects = args.get('subject') del args['subject'] - subjects = [x.replace('WormBase:', 'WB:') if 'WormBase:' in x else x for x in subjects] results = map2slim( subjects=subjects, @@ -135,6 +139,7 @@ def get(self): ) return results + def gene_to_uniprot_from_mygene(id): """ Query MyGeneInfo with a gene and get its corresponding UniProt ID @@ -146,7 +151,7 @@ def gene_to_uniprot_from_mygene(id): id = id.replace('NCBIGene', 'entrezgene') try: results = mg.query(id, fields='uniprot') - print("results from mygene for ", id , ": ", results) + print("results from mygene for ", id, ": ", results) if results['hits']: for hit in results['hits']: if 'uniprot' not in hit: @@ -173,6 +178,7 @@ def gene_to_uniprot_from_mygene(id): return uniprot_ids + def uniprot_to_gene_from_mygene(id): """ Query MyGeneInfo with a UniProtKB id and get its corresponding HGNC gene diff --git a/biolink/api/ontol/endpoints/ontology_endpoint.py b/biolink/api/ontol/endpoints/ontology_endpoint.py index 07c351c9..9fad4d23 100644 --- a/biolink/api/ontol/endpoints/ontology_endpoint.py +++ b/biolink/api/ontol/endpoints/ontology_endpoint.py @@ -1,53 +1,50 @@ import logging -from flask import request from flask_restplus import Resource, inputs -from biolink.datamodel.serializers import association from biolink.api.restplus import api -from causalmodels.lego_sparql_util import lego_query, ModelQuery - -from ontobio.sparql.sparql_go import goSummary, goSubsets, subset +from ontobio.sparql.sparql_go import goSummary, goSubsets from ontobio.sparql.sparql_ontol_utils import run_sparql_on, EOntology, transform, transformArray - -from ontobio.golr.golr_query import GolrSearchQuery, run_solr_on, run_solr_text_on, ESOLR, ESOLRDoc, replace - -from ontobio.ontol_factory import OntologyFactory +from ontobio.golr.golr_query import run_solr_on, run_solr_text_on, ESOLR, ESOLRDoc, replace from biolink.ontology.ontology_manager import get_ontology from ontobio.io.ontol_renderers import OboJsonGraphRenderer - -from biolink.api.entityset.endpoints.slimmer import gene_to_uniprot_from_mygene, uniprot_to_gene_from_mygene - +from biolink.api.entityset.endpoints.slimmer import gene_to_uniprot_from_mygene import json -### Some query parameters & parsers +# Some query parameters & parsers IS_A = "isa" IS_A_PART_OF = "isa_partof" REGULATES = "regulates" related_params = api.parser() -related_params.add_argument('relationship_type', choices=[IS_A, IS_A_PART_OF, REGULATES], default=IS_A_PART_OF, help="relationship type ('{}', '{}' or '{}')".format(IS_A, IS_A_PART_OF, REGULATES)) +related_params.add_argument('relationship_type', choices=[IS_A, IS_A_PART_OF, REGULATES], default=IS_A_PART_OF, + help="relationship type ('{}', '{}' or '{}')".format(IS_A, IS_A_PART_OF, REGULATES)) TOPOLOGY = "topology_graph" REGULATES_TRANSITIVITY = "regulates_transitivity_graph" NEIGHBORHOOD_GRAPH = "neighborhood_graph" NEIGHBORHOOD_LIMITED_GRAPH = "neighborhood_limited_graph" graph_params = api.parser() -graph_params.add_argument('graph_type', choices=[TOPOLOGY, REGULATES_TRANSITIVITY, NEIGHBORHOOD_GRAPH, NEIGHBORHOOD_LIMITED_GRAPH], default=TOPOLOGY, help="graph type ('{}', '{}' or '{}')".format(TOPOLOGY, REGULATES_TRANSITIVITY, NEIGHBORHOOD_GRAPH, NEIGHBORHOOD_LIMITED_GRAPH)) - +graph_params.add_argument('graph_type', + choices=[TOPOLOGY, REGULATES_TRANSITIVITY, NEIGHBORHOOD_GRAPH, NEIGHBORHOOD_LIMITED_GRAPH], + default=TOPOLOGY, + help="graph type ('{}', '{}' or '{}')".format(TOPOLOGY, REGULATES_TRANSITIVITY, + NEIGHBORHOOD_GRAPH)) subgraph_params = api.parser() subgraph_params.add_argument('cnode', action='append', help='Additional classes') subgraph_params.add_argument('include_ancestors', type=inputs.boolean, default=True, help='Include Ancestors') subgraph_params.add_argument('include_descendants', type=inputs.boolean, help='Include Descendants') -subgraph_params.add_argument('relation', action='append', default=['subClassOf', 'BFO:0000050'], help='Additional classes') +subgraph_params.add_argument('relation', action='append', default=['subClassOf', 'BFO:0000050'], + help='Additional classes') subgraph_params.add_argument('include_meta', type=inputs.boolean, default=False, help='Include metadata in response') -### END +# END log = logging.getLogger(__name__) + @api.doc(params={'id': 'CURIE identifier of a GO term, e.g. GO:0003677'}) class OntologyTerm(Resource): @@ -59,6 +56,7 @@ def get(self, id): results = run_sparql_on(query, EOntology.GO) return transform(results[0], ['synonyms', 'relatedSynonyms', 'alternativeIds', 'xrefs', 'subsets']) + @api.doc(params={'id': 'CURIE identifier of a GO term, e.g. GO:0000981'}) class OntologyTermGraph(Resource): @@ -69,36 +67,14 @@ def get(self, id): """ args = graph_params.parse_args() - graph_type = args['graph_type'] + "_json" # GOLR field names + graph_type = args['graph_type'] + "_json" # GOLR field names data = run_solr_on(ESOLR.GOLR, ESOLRDoc.ONTOLOGY, id, graph_type) # step required as these graphs are stringified in the json - data[graph_type] = json.loads(data[graph_type]) - - return data - -# @ns.route('/term//ancestor') -# class OntologyTermAncestor(Resource): - -# def get(self, id): -# """ -# Returns ancestors of an ontology term -# """ -# return None + data[graph_type] = json.loads(data[graph_type]) -# @ns.route('/term//descendant') -# class OntologyTermDescendant(Resource): - -# def get(self, id): -# """ -# Returns descendants of an ontology term -# """ - -# ont = get_ontology("go") -# print("ONT: ", ont) -# print("GRAPH: ", ont.get_graph()) + return data -# return None @api.doc(params={'id': 'CURIE identifier of a GO term, e.g. GO:0007275'}) class OntologyTermSubgraph(Resource): @@ -116,7 +92,7 @@ def get(self, id): # COMMENT: based on the CURIE of the id, we should be able to find out the ontology automatically ont = get_ontology("go") relations = args.relation - print("Traversing: {} using {}".format(qnodes,relations)) + print("Traversing: {} using {}".format(qnodes, relations)) nodes = ont.traverse_nodes(qnodes, up=args.include_ancestors, down=args.include_descendants, @@ -128,6 +104,7 @@ def get(self, id): json_obj = ojr.to_json(subont, include_meta=args.include_meta) return json_obj + @api.doc(params={'id': 'CURIE identifier of a GO term, e.g. GO:0006259'}) class OntologyTermSubsets(Resource): @@ -141,6 +118,7 @@ def get(self, id): results = replace(results, "subset", "OBO:go#", "") return results + @api.doc(params={'id': 'name of a slim subset, e.g. goslim_agr, goslim_generic'}) class OntologySubset(Resource): @@ -149,7 +127,6 @@ def get(self, id): Returns meta data of an ontology subset (slim) """ - q = "*:*" qf = "" fq = "&fq=subset:" + id + "&rows=1000" @@ -173,7 +150,7 @@ def get(self, id): for term in data: source = term['source'] if source not in tr: - tr[source] = { "annotation_class_label" : source, "terms" : [] } + tr[source] = {"annotation_class_label": source, "terms": []} ready_term = term.copy() del ready_term["source"] tr[source]["terms"].append(ready_term) @@ -195,10 +172,9 @@ def get(self, id): result = [] for category in tr: cat = tr[category] - result.append(cat) - + result.append(cat) - # if goslim_agr, reorder the list based on the temporary json object below + # if goslim_agr, reorder the list based on the temporary json object below if id == "goslim_agr": temp = [] for agr_category in agr_slim_order: @@ -218,51 +194,8 @@ def get(self, id): return result -# @ns.route('/term//related') -# @api.doc(params={'id': 'CURIE identifier of a GO term, e.g. GO:0030182'}) -# class OntologyTermsRelated(Resource): - -# @api.expect(related_params) -# def get(self, id): -# """ -# Returns related ontology terms based on a given relationship type -# """ -# args = related_params.parse_args() -# relationship = args['relationship_type'] - -# closure = relationship + "_closure" -# closure_label = relationship + "_closure_label" - -# data = run_solr_on(ESOLR.GOLR, ESOLRDoc.ONTOLOGY, id, closure + "," + closure_label) -# data = mergeWithLabels(data, closure, "goid", closure_label, "label") - -# # args = { -# # "q": "*:*", -# # "fq": "id:\"" + id + "\"", -# # "url": "http://golr-aux.geneontology.io/solr/", -# # "category": "ontology_class" -# # } -# # print(args) - -# # GolrSearchQuery(term=id, category="ontology_class", url="http://golr-aux.geneontology.io/solr/", fq="id:\"" + id + "\"") -# # q = GolrSearchQuery(id, args) -# # print("QUERY RESYLT: " , q.search()) -# return data - - -# @ns.route('/relation//') -# @api.doc(params={'subject': 'CURIE identifier of a GO term, e.g. GO:0006259', -# 'object': 'CURIE identifier of a GO term, e.g. GO:0046483' }) -# class OntologyTermsRelation(Resource): - -# def get(self, subject, object): -# """ -# Returns relations between two ontology terms -# """ -# return None - @api.doc(params={'subject': 'CURIE identifier of a GO term, e.g. GO:0006259', - 'object': 'CURIE identifier of a GO term, e.g. GO:0046483' }) + 'object': 'CURIE identifier of a GO term, e.g. GO:0046483'}) class OntologyTermsSharedAncestor(Resource): def get(self, subject, object): @@ -274,7 +207,7 @@ def get(self, subject, object): subres = run_solr_on(ESOLR.GOLR, ESOLRDoc.ONTOLOGY, subject, fields) objres = run_solr_on(ESOLR.GOLR, ESOLRDoc.ONTOLOGY, object, fields) - + print("SUBJECT: ", subres) print("OBJECT: ", objres) @@ -288,19 +221,22 @@ def get(self, subject, object): if found: shared.append(sub) sharedLabels.append(subres['isa_partof_closure_label'][i]) - return { "goids" : shared, "gonames: " : sharedLabels } + return {"goids": shared, "gonames: ": sharedLabels} ribbon_parser = api.parser() ribbon_parser.add_argument('subset', help='Name of the subset to map GO terms (e.g. goslim_agr)') ribbon_parser.add_argument('subject', action='append', help='List of Gene ids (e.g. MGI:98214, RGD:620474)') -ribbon_parser.add_argument('ecodes', action='append', help='List of Evidence Codes to include (e.g. EXP, IDA). Has priority over exclude_IBA') +ribbon_parser.add_argument('ecodes', action='append', + help='List of Evidence Codes to include (e.g. EXP, IDA). Has priority over exclude_IBA') ribbon_parser.add_argument('exclude_IBA', type=inputs.boolean, default=False, help='If true, excludes IBA annotations') -ribbon_parser.add_argument('exclude_PB', type=inputs.boolean, default=False, help='If true, excludes direct annotations to protein binding') -ribbon_parser.add_argument('cross_aspect', type=inputs.boolean, default=False, help='If true, can retrieve terms from other aspects if using a cross-aspect relationship such as regulates_closure') +ribbon_parser.add_argument('exclude_PB', type=inputs.boolean, default=False, + help='If true, excludes direct annotations to protein binding') +ribbon_parser.add_argument('cross_aspect', type=inputs.boolean, default=False, + help='If true, can retrieve terms from other aspects if using a cross-aspect relationship such as regulates_closure') -class OntologyRibbons(Resource): +class OntologyRibbons(Resource): aspect_map = { "P": "GO:0008150", "F": "GO:0003674", @@ -347,17 +283,25 @@ def get(self): del group["annotation_class_label"] group["type"] = "Term" - - category["groups"] = [{"id" : category["id"], "label" : "all " + category["label"].lower().replace("_", " "), "description" : "Show all " + category["label"].lower().replace("_", " ") + " annotations", "type" : "All"}] + category["groups"] + [{"id" : category["id"], "label" : "other " + category["label"].lower().replace("_", " "), "description" : "Represent all annotations not mapped to a specific term", "type" : "Other"}] - + + category["groups"] = [{"id": category["id"], + "label": "all " + category["label"].lower().replace("_", " "), + "description": "Show all " + category["label"].lower().replace("_", + " ") + " annotations", + "type": "All"}] + category["groups"] + [{"id": category["id"], + "label": "other " + category[ + "label"].lower().replace("_", " "), + "description": "Represent all annotations not mapped to a specific term", + "type": "Other"}] + # Step 2: create the entities / subjects subject_ids = args.subject # ID conversion subject_ids = [x.replace('WormBase:', 'WB:') if 'WormBase:' in x else x for x in subject_ids] slimmer_subjects = [] - mapped_ids = { } - reverse_mapped_ids = { } + mapped_ids = {} + reverse_mapped_ids = {} for s in subject_ids: if 'HGNC:' in s or 'NCBIGene:' in s or 'ENSEMBL:' in s: prots = gene_to_uniprot_from_mygene(s) @@ -370,7 +314,7 @@ def get(self): else: slimmer_subjects.append(s) - print("SLIMMER SUBS : " , slimmer_subjects) + print("SLIMMER SUBS : ", slimmer_subjects) subject_ids = slimmer_subjects # should remove any undefined subject @@ -384,11 +328,11 @@ def get(self): subjects = [] for subject_id in subject_ids: - entity = { "id" : subject_id , - "groups" : { }, - "nb_classes" : 0, - "nb_annotations": 0, - "terms" : set() } + entity = {"id": subject_id, + "groups": {}, + "nb_classes": 0, + "nb_annotations": 0, + "terms": set()} if subject_id.startswith("MGI:"): subject_id = "MGI:" + subject_id @@ -430,7 +374,6 @@ def get(self): entity['terms'].add(annot['annotation_class']) entity['nb_annotations'] += 1 - for cat in categories: for gp in cat['groups']: @@ -450,12 +393,14 @@ def get(self): # if the group has not been met yet, create it if group not in entity['groups']: - entity['groups'][group] = { } - entity['groups'][group]['ALL'] = { "terms" : set(), "nb_classes" : 0, "nb_annotations" : 0 } + entity['groups'][group] = {} + entity['groups'][group]['ALL'] = {"terms": set(), "nb_classes": 0, + "nb_annotations": 0} # if the subgroup has not been met yet, create it if annot['evidence_type'] not in entity['groups'][group]: - entity['groups'][group][annot['evidence_type']] = { "terms" : set(), "nb_classes" : 0, "nb_annotations" : 0 } + entity['groups'][group][annot['evidence_type']] = {"terms": set(), "nb_classes": 0, + "nb_annotations": 0} # for each annotation, add the term and increment the nb of annotations entity['groups'][group][annot['evidence_type']]['terms'].add(annot['annotation_class']) @@ -463,16 +408,10 @@ def get(self): entity['groups'][group]['ALL']['terms'].add(annot['annotation_class']) entity['groups'][group]['ALL']['nb_annotations'] += 1 - # entity['terms'].add(annot['annotation_class']) - # entity['nb_annotations'] += 1 - - - # other = get_others() terms = self.get_category_terms(cat) terms = [term["id"] for term in terms] - - other = { } - other["ALL"] = { "terms" : set(), "nb_classes" : 0, "nb_annotations" : 0 } + + other = {"ALL": {"terms": set(), "nb_classes": 0, "nb_annotations": 0}} for annot in data: aspect = self.aspect_map[annot["aspect"]] @@ -490,40 +429,10 @@ def get(self): other["ALL"]["nb_annotations"] += 1 other["ALL"]["terms"].add(annot['annotation_class']) if annot['evidence_type'] not in other: - other[annot['evidence_type']] = { "terms" : set(), "nb_classes" : 0, "nb_annotations" : 0 } + other[annot['evidence_type']] = {"terms": set(), "nb_classes": 0, "nb_annotations": 0} other[annot['evidence_type']]["nb_annotations"] += 1 other[annot['evidence_type']]["terms"].add(annot['annotation_class']) - - - # # creating list of annotations not annotated to a specific term - # not_found = set() - # for annot in data: - # found = False - # for gp in cat['groups']: - # if annot['annotation_class'] == gp['id']: - # found = True - # if not found: - # not_found.add(annot['annotation_class']) - - # for nf in not_found: - # for annot in data: - # if nf == annot['annotation_class']: - # # print(nf, annot['annotation_class']) - # aspect = self.aspect_map[annot["aspect"]] - - # # only allow annotated terms belonging to the same category - # if cat['id'] == aspect: - - # # if the subgroup has not been met yet, create it - # if annot['evidence_type'] not in other: - # other[annot['evidence_type']] = { "terms" : set(), "nb_classes" : 0, "nb_annotations" : 0 } - - # # for each annotation, add the term and increment the nb of annotations - # other[annot['evidence_type']]['terms'].add(annot['annotation_class']) - # other[annot['evidence_type']]['nb_annotations'] += 1 - # other['ALL']['terms'].add(annot['annotation_class']) - # other['ALL']['nb_annotations'] += 1 - + entity['groups'][cat['id'] + "-other"] = other # compute the number of classes for each group that have subgroup (annotations) @@ -540,7 +449,6 @@ def get(self): subjects.append(entity) - # fill out the entity details q = "*:*" qf = "" @@ -557,14 +465,12 @@ def get(self): entity['taxon_id'] = entity_detail['taxon'] entity['taxon_label'] = entity_detail['taxon_label'] - # map the entity back to their original IDs for entity in subjects: if entity['id'] in reverse_mapped_ids: - entity['id'] = reverse_mapped_ids[entity['id']] - + entity['id'] = reverse_mapped_ids[entity['id']] - # if any subject without annotation is retrieved, remove it + # if any subject without annotation is retrieved, remove it to_remove = [] for entity in subjects: if entity['nb_annotations'] == 0: @@ -572,96 +478,84 @@ def get(self): for entity in to_remove: subjects.remove(entity) - - - # http://golr-aux.geneontology.io/solr/select/?q=*:*&fq=document_category:%22bioentity%22&rows=10&wt=json&fl=bioentity,bioentity_label,taxon,taxon_label&fq=bioentity:(%22MGI:MGI:98214%22%20or%20%22RGD:620474%22) - result = { "categories" : categories , "subjects" : subjects } + # http://golr-aux.geneontology.io/solr/select/?q=*:*&fq=document_category:%22bioentity%22&rows=10&wt=json&fl=bioentity,bioentity_label,taxon,taxon_label&fq=bioentity:(%22MGI:MGI:98214%22%20or%20%22RGD:620474%22) - # print("CATEGORIES : " , categories) - # print("SUBJECTS : " , subjects) + result = {"categories": categories, "subjects": subjects} return result - - - - - - - - -# this is a temporary json object, while waiting the ontology gets an annotation field to specify the order of a term in a slim +# this is a temporary json object, while waiting the +# ontology gets an annotation field to specify the order of a term in a slim agr_slim_order = [ - { - "category" : "GO:0003674", - "terms" : [ - "GO:0003824", - "GO:0030234", - "GO:0038023", - "GO:0005102", - "GO:0005215", - "GO:0005198", - "GO:0008092", - "GO:0003677", - "GO:0003723", - "GO:0003700", - "GO:0008134", - "GO:0036094", - "GO:0046872", - "GO:0030246", - "GO:0097367", - "GO:0008289" - ] - }, + { + "category": "GO:0003674", + "terms": [ + "GO:0003824", + "GO:0030234", + "GO:0038023", + "GO:0005102", + "GO:0005215", + "GO:0005198", + "GO:0008092", + "GO:0003677", + "GO:0003723", + "GO:0003700", + "GO:0008134", + "GO:0036094", + "GO:0046872", + "GO:0030246", + "GO:0097367", + "GO:0008289" + ] + }, { - "category" : "GO:0008150", - "terms" : [ - "GO:0007049", - "GO:0016043", - "GO:0051234", - "GO:0008283", - "GO:0030154", - "GO:0008219", - "GO:0032502", - "GO:0000003", - "GO:0002376", - "GO:0050877", - "GO:0050896", - "GO:0023052", - "GO:0006259", - "GO:0016070", - "GO:0019538", - "GO:0005975", - "GO:1901135", - "GO:0006629", - "GO:0042592", - "GO:0009056", - "GO:0007610" - ] + "category": "GO:0008150", + "terms": [ + "GO:0007049", + "GO:0016043", + "GO:0051234", + "GO:0008283", + "GO:0030154", + "GO:0008219", + "GO:0032502", + "GO:0000003", + "GO:0002376", + "GO:0050877", + "GO:0050896", + "GO:0023052", + "GO:0006259", + "GO:0016070", + "GO:0019538", + "GO:0005975", + "GO:1901135", + "GO:0006629", + "GO:0042592", + "GO:0009056", + "GO:0007610" + ] }, { - "category" : "GO:0005575", - "terms" : [ - "GO:0005576", - "GO:0005886", - "GO:0045202", - "GO:0030054", - "GO:0042995", - "GO:0031410", - "GO:0005768", - "GO:0005773", - "GO:0005794", - "GO:0005783", - "GO:0005829", - "GO:0005739", - "GO:0005634", - "GO:0005694", - "GO:0005856", - "GO:0032991" - ] + "category": "GO:0005575", + "terms": [ + "GO:0005576", + "GO:0005886", + "GO:0045202", + "GO:0030054", + "GO:0042995", + "GO:0031410", + "GO:0005768", + "GO:0005773", + "GO:0005794", + "GO:0005783", + "GO:0005829", + "GO:0005739", + "GO:0005634", + "GO:0005694", + "GO:0005856", + "GO:0032991" + ] } ] - diff --git a/biolink/api/ontol/endpoints/slimmer.py b/biolink/api/ontol/endpoints/slimmer.py deleted file mode 100644 index 3cc04962..00000000 --- a/biolink/api/ontol/endpoints/slimmer.py +++ /dev/null @@ -1,34 +0,0 @@ -""" -@Deprecated -""" -import logging - -from flask import request -from flask_restplus import Resource -from biolink.datamodel.serializers import association -from biolink.api.restplus import api - -import pysolr - -log = logging.getLogger(__name__) - -parser = api.parser() -#parser.add_argument('subject_taxon', help='SUBJECT TAXON id, e.g. NCBITaxon:9606. Includes inferred by default') - -class MapToSlimResource(Resource): - - - @api.expect(parser) - def get(self, subset): - """ - TODO Maps to slim - """ - args = parser.parse_args() - - return [] - - - - - - diff --git a/biolink/app.py b/biolink/app.py index 5a81479c..679911ef 100755 --- a/biolink/app.py +++ b/biolink/app.py @@ -18,7 +18,6 @@ app = Flask(__name__) app.wsgi_app = ProxyFix(app.wsgi_app) -# app = Flask(__name__) app.url_map.strict_slashes = False CORS(app) log_file_path = path.join(path.dirname(path.abspath(__file__)), '../logging.conf') @@ -36,8 +35,7 @@ app.config['ERROR_404_HELP'] = settings.RESTPLUS_ERROR_404_HELP app.config['ERROR_INCLUDE_MESSAGE'] = settings.ERROR_INCLUDE_MESSAGE -# def initialize_app(flask_app): -# configure_app(flask_app) +# configure_app(flask_app) blueprint = Blueprint('api', __name__, url_prefix='/api') api.init_app(blueprint) diff --git a/biolink/error_handlers.py b/biolink/error_handlers.py index 125ae84d..74eb6c6f 100644 --- a/biolink/error_handlers.py +++ b/biolink/error_handlers.py @@ -4,6 +4,7 @@ from biolink import settings import logging + class CustomException(Exception): def __init__(self, message, status_code=500, debug=None): Exception.__init__(self) @@ -22,36 +23,45 @@ def to_dict(self): } } + class NoResultFoundException(CustomException): """ Use this exception when results are expected but no result found """ + def __init__(self, message, status_code=404, debug=None): CustomException.__init__(self, message, status_code, debug) + class UnrecognizedBioentityTypeException(CustomException): """ Use this exception when encountering an unrecognized Bioentity type """ + def __init__(self, message, status_code=400, debug=None): CustomException.__init__(self, message, status_code, debug) + class RouteNotImplementedException(CustomException): """ Use this exception for routes that have yet to be implemented """ + def __init__(self, message=None, status_code=500, debug=None): if not message: message = 'Route not yet implemented' CustomException.__init__(self, message, status_code, debug) + class UnhandledException(CustomException): """ Use this exception if its unclear which exception to raise """ + def __init__(self, message, status_code=500, debug=None): CustomException.__init__(self, message, status_code, debug) + @api.errorhandler def default_error_handler(e): """ @@ -61,11 +71,12 @@ def default_error_handler(e): message = 'An exception occurred: {}'.format(e) logging.error(message) return { - 'error': { - 'message': message, - 'code': status_code - } - }, status_code + 'error': { + 'message': message, + 'code': status_code + } + }, status_code + @api.errorhandler(NoResultFoundException) def no_result_found_exception_handler(e): @@ -76,6 +87,7 @@ def no_result_found_exception_handler(e): logging.error(message) return e.to_dict(), e.status_code + @api.errorhandler(UnrecognizedBioentityTypeException) def unrecognized_bioentity_type_exception(e): """ @@ -86,6 +98,7 @@ def unrecognized_bioentity_type_exception(e): logging.error(message) return e.to_dict(), e.status_code + @api.errorhandler(RouteNotImplementedException) def route_not_implemented_exception(e): """ @@ -95,6 +108,7 @@ def route_not_implemented_exception(e): logging.error(message) return e.to_dict(), e.status_code + @api.errorhandler(UnhandledException) def unhandled_exception_handler(e): """ @@ -104,6 +118,7 @@ def unhandled_exception_handler(e): logging.error(message) return e.to_dict(), e.status_code + @api.errorhandler(InvalidSyntax) def invalid_syntax_exception_handler(e): """ @@ -112,11 +127,12 @@ def invalid_syntax_exception_handler(e): message = 'Invalid syntax for CURIE {}'.format(e.id) logging.error(message) return { - 'error': { - 'message': message, - 'code': 400 - } - }, 400 + 'error': { + 'message': message, + 'code': 400 + } + }, 400 + @api.errorhandler(NoExpansion) def no_expansion_exception_handler(e): @@ -126,11 +142,12 @@ def no_expansion_exception_handler(e): message = 'No expansion for {}'.format(e.id) logging.error(message) return { - 'error': { - 'message': message, - 'code': 400 - } - }, 400 + 'error': { + 'message': message, + 'code': 400 + } + }, 400 + @api.errorhandler(NoContraction) def no_contraction_exception_handler(e): @@ -140,11 +157,12 @@ def no_contraction_exception_handler(e): message = 'No contraction for URI {}'.format(e.uri) logging.error(message) return { - 'error': { - 'message': message, - 'code': 400 - } - }, 400 + 'error': { + 'message': message, + 'code': 400 + } + }, 400 + @api.errorhandler(NoPrefix) def no_prefix_exception_handler(e): @@ -154,11 +172,12 @@ def no_prefix_exception_handler(e): message = 'No prefix for URI {}'.format(e.uri) logging.error(message) return { - 'error': { - 'message': message, - 'code': 400 - } - }, 400 + 'error': { + 'message': message, + 'code': 400 + } + }, 400 + @api.errorhandler(AmbiguousPrefix) def ambiguous_prefix_exception_handler(e): @@ -168,8 +187,8 @@ def ambiguous_prefix_exception_handler(e): message = 'Ambiguous prefix for URI {}'.format(e.uri) logging.error(message) return { - 'error': { - 'message': message, - 'code': 400 - } - }, 400 + 'error': { + 'message': message, + 'code': 400 + } + }, 400 diff --git a/biolink/ontology/ontology_manager.py b/biolink/ontology/ontology_manager.py index 9954c626..946c89a1 100644 --- a/biolink/ontology/ontology_manager.py +++ b/biolink/ontology/ontology_manager.py @@ -6,6 +6,7 @@ cfg = get_biolink_config() omap = {} + def get_ontology(id): handle = id for c in cfg['ontologies']: diff --git a/wsgi.py b/wsgi.py index 51538722..9e058b27 100644 --- a/wsgi.py +++ b/wsgi.py @@ -1,4 +1,4 @@ from biolink.app import app if __name__ == "__main__": - app.run(host='0.0.0.0', port=5000, debug=True) + app.run(host='0.0.0.0', port=8888, debug=True) From dbaf29fdbc23622f531ae21b3fdaf454f1e5cccc Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 2 Mar 2022 15:04:25 -0800 Subject: [PATCH 33/34] remove stub code for unused endpoints --- biolink/api/evidence/endpoints/graph.py | 68 --------------------- biolink/api/genome/endpoints/region.py | 23 ------- biolink/api/identifier/endpoints/mapper.py | 26 -------- biolink/api/image/endpoints/images.py | 32 ---------- biolink/api/metadata/endpoints/datasets.py | 17 ------ biolink/api/nlp/endpoints/annotate.py | 28 --------- biolink/api/owl/endpoints/ontology.py | 35 ----------- biolink/api/pair/endpoints/pairsim.py | 36 ----------- biolink/api/patient/endpoints/individual.py | 34 ----------- biolink/api/pub/endpoints/pubs.py | 32 ---------- biolink/api/variation/endpoints/analyze.py | 29 --------- tests/association-gene-phenotype.feature | 25 -------- tests/association-phenotype.feature | 12 ---- 13 files changed, 397 deletions(-) delete mode 100644 biolink/api/evidence/endpoints/graph.py delete mode 100644 biolink/api/genome/endpoints/region.py delete mode 100644 biolink/api/identifier/endpoints/mapper.py delete mode 100644 biolink/api/image/endpoints/images.py delete mode 100644 biolink/api/metadata/endpoints/datasets.py delete mode 100644 biolink/api/nlp/endpoints/annotate.py delete mode 100644 biolink/api/owl/endpoints/ontology.py delete mode 100644 biolink/api/pair/endpoints/pairsim.py delete mode 100644 biolink/api/patient/endpoints/individual.py delete mode 100644 biolink/api/pub/endpoints/pubs.py delete mode 100644 biolink/api/variation/endpoints/analyze.py delete mode 100644 tests/association-gene-phenotype.feature delete mode 100644 tests/association-phenotype.feature diff --git a/biolink/api/evidence/endpoints/graph.py b/biolink/api/evidence/endpoints/graph.py deleted file mode 100644 index f1052c6f..00000000 --- a/biolink/api/evidence/endpoints/graph.py +++ /dev/null @@ -1,68 +0,0 @@ -import logging - -from flask import request, send_file -from flask_restplus import Resource -from biolink.datamodel.serializers import association, bbop_graph -from ontobio.golr.golr_associations import get_association, search_associations -from biolink.api.restplus import api -from ontobio.obograph_util import convert_json_object -import tempfile -import pysolr -#import matplotlib.pyplot as plt -import networkx as nx - -from biolink import USER_AGENT - -log = logging.getLogger(__name__) - -parser = api.parser() -#parser.add_argument('subject_taxon', help='SUBJECT TAXON id, e.g. NCBITaxon:9606. Includes inferred by default') - -@api.doc(params={'id': 'association id, e.g. cfef92b7-bfa3-44c2-a537-579078d2de37'}) -class EvidenceGraphObject(Resource): - - @api.expect(parser) - @api.marshal_list_with(bbop_graph) - def get(self,id): - """ - Returns evidence graph object for a given association. - - Note that every association is assumed to have a unique ID - """ - args = parser.parse_args() - - ## TODO: restore this next release of OntoBio (0.2.3 or higher) - ## assoc = get_association(id) - - results = search_associations(fq={'id':id}, user_agent=USER_AGENT) - assoc = results['associations'][0] if len(results['associations']) > 0 else {} - eg = assoc.get('evidence_graph') - return [eg] - -@api.doc(params={'id': 'association id, e.g. cfef92b7-bfa3-44c2-a537-579078d2de37'}) -class EvidenceGraphImage(Resource): - - @api.expect(parser) - def get(self,id): - """ - Returns evidence graph as a png - - TODO - requires matplotlib which is hard to install - """ - args = parser.parse_args() - - assoc = get_association(id, user_agent=USER_AGENT) - eg = {'graphs':[assoc.get('evidence_graph')]} - digraph = convert_json_object(eg) - #fp = tempfile.TemporaryFile() - nx.draw(digraph) - fn = '/tmp/'+id+'.png' # TODO - plt.savefig(fn) - return send_file(fn) - - - - - - - diff --git a/biolink/api/genome/endpoints/region.py b/biolink/api/genome/endpoints/region.py deleted file mode 100644 index 147105bb..00000000 --- a/biolink/api/genome/endpoints/region.py +++ /dev/null @@ -1,23 +0,0 @@ -import logging - -from flask_restplus import Resource -from biolink.datamodel.serializers import sequence_feature -from biolink.api.restplus import api - -from biolink.error_handlers import RouteNotImplementedException - -log = logging.getLogger(__name__) - -parser = api.parser() - -class FeaturesWithinResource(Resource): - - - @api.marshal_list_with(sequence_feature) - @api.expect(parser) - def get(self, build, reference, begin, end): - """ - Returns list of matches - """ - args = parser.parse_args() - raise RouteNotImplementedException() diff --git a/biolink/api/identifier/endpoints/mapper.py b/biolink/api/identifier/endpoints/mapper.py deleted file mode 100644 index a7fd20a6..00000000 --- a/biolink/api/identifier/endpoints/mapper.py +++ /dev/null @@ -1,26 +0,0 @@ -import logging - -from flask_restplus import Resource -from biolink.datamodel.serializers import association -from biolink.api.restplus import api - -from biolink.error_handlers import RouteNotImplementedException - -log = logging.getLogger(__name__) - -parser = api.parser() -#parser.add_argument('subject_taxon', help='SUBJECT TAXON id, e.g. NCBITaxon:9606. Includes inferred by default') - -class IdentifierMapper(Resource): - - @api.expect(parser) - @api.marshal_list_with(association) - - @api.expect(parser) - @api.marshal_list_with(association) - def get(self, source, target): - """ - TODO maps a list of identifiers from a source to a target - """ - args = parser.parse_args() - raise RouteNotImplementedException() diff --git a/biolink/api/image/endpoints/images.py b/biolink/api/image/endpoints/images.py deleted file mode 100644 index db3725a0..00000000 --- a/biolink/api/image/endpoints/images.py +++ /dev/null @@ -1,32 +0,0 @@ -import logging - -from flask import request -from flask_restplus import Resource -from biolink.datamodel.serializers import association -from biolink.api.restplus import api -import pysolr - -log = logging.getLogger(__name__) - -parser = api.parser() -#parser.add_argument('subject_taxon', help='SUBJECT TAXON id, e.g. NCBITaxon:9606. Includes inferred by default') - -class Foo(Resource): - - @api.expect(parser) - @api.marshal_list_with(association) - - @api.expect(parser) - @api.marshal_list_with(association) - def get(self, term): - """ - Returns list of matches - """ - args = parser.parse_args() - - return [] - - - - - diff --git a/biolink/api/metadata/endpoints/datasets.py b/biolink/api/metadata/endpoints/datasets.py deleted file mode 100644 index 990726da..00000000 --- a/biolink/api/metadata/endpoints/datasets.py +++ /dev/null @@ -1,17 +0,0 @@ -from biolink.api.restplus import api -from flask_restplus import Resource -from biolink.settings import get_biolink_config -from scigraph.scigraph_util import SciGraph - - -scigraph = SciGraph(get_biolink_config()['scigraph_data']['url']) - - -class MetadataForDatasets(Resource): - - def get(self): - """ - Get metadata for all datasets from SciGraph - """ - - return scigraph.get_datasets() diff --git a/biolink/api/nlp/endpoints/annotate.py b/biolink/api/nlp/endpoints/annotate.py deleted file mode 100644 index 3f2a5632..00000000 --- a/biolink/api/nlp/endpoints/annotate.py +++ /dev/null @@ -1,28 +0,0 @@ -import logging - -from flask import request -from flask_restplus import Resource -from biolink.datamodel.serializers import association -from biolink.api.restplus import api -from biolink.error_handlers import RouteNotImplementedException -import pysolr - -log = logging.getLogger(__name__) - -parser = api.parser() -parser.add_argument('category', action='append', help='E.g. phenotype') - -class Annotate(Resource): - - @api.expect(parser) - @api.marshal_list_with(association) - - @api.expect(parser) - @api.marshal_list_with(association) - def get(self, text): - """ - Not yet implemented. For now using scigraph annotator directly - """ - args = parser.parse_args() - - raise RouteNotImplementedException('Use SciGraph annotator instead') diff --git a/biolink/api/owl/endpoints/ontology.py b/biolink/api/owl/endpoints/ontology.py deleted file mode 100644 index ee749071..00000000 --- a/biolink/api/owl/endpoints/ontology.py +++ /dev/null @@ -1,35 +0,0 @@ -import logging - -from flask_restplus import Resource -from biolink.datamodel.serializers import association -from biolink.api.restplus import api - -from biolink.error_handlers import RouteNotImplementedException - -log = logging.getLogger(__name__) - -parser = api.parser() -#parser.add_argument('subject_taxon', help='SUBJECT TAXON id, e.g. NCBITaxon:9606. Includes inferred by default') - -class DLQuery(Resource): - - @api.expect(parser) - @api.marshal_list_with(association) - def get(self, query): - """ - Placeholder - use OWLery for now - """ - args = parser.parse_args() - raise RouteNotImplementedException('Use Owlery API instead') - -class SparqlQuery(Resource): - - @api.expect(parser) - @api.marshal_list_with(association) - def get(self, query): - """ - Placeholder - use direct SPARQL endpoint for now - """ - args = parser.parse_args() - raise RouteNotImplementedException('Use SPARQL endpoint directly') - diff --git a/biolink/api/pair/endpoints/pairsim.py b/biolink/api/pair/endpoints/pairsim.py deleted file mode 100644 index 767b291b..00000000 --- a/biolink/api/pair/endpoints/pairsim.py +++ /dev/null @@ -1,36 +0,0 @@ -import logging - -from flask import request -from flask_restplus import Resource -from ontobio.golr.golr_sim import subject_pair_simj -from biolink.api.restplus import api -from biolink import USER_AGENT - -log = logging.getLogger(__name__) - -parser = api.parser() -parser.add_argument('object_category', help='e.g. disease, phenotype, gene. Two subjects will be compared based on overlap between associations to objects in this category') - -@api.doc(params={'id1': 'id, e.g. NCBIGene:10891; ZFIN:ZDB-GENE-980526-166; UniProtKB:Q15465'}) -@api.doc(params={'id2': 'id, e.g. NCBIGene:1200; ZFIN:ZDB-GENE-980528-2059; UniProtKB:P12644'}) -class PairSimJaccardResource(Resource): - - @api.expect(parser) - def get(self, id1, id2): - """ - Get pairwise similarity - """ - args = parser.parse_args() - - results = subject_pair_simj( - id1, - id2, - user_agent=USER_AGENT, - **args - ) - return results - - - - - diff --git a/biolink/api/patient/endpoints/individual.py b/biolink/api/patient/endpoints/individual.py deleted file mode 100644 index 9f1b3efd..00000000 --- a/biolink/api/patient/endpoints/individual.py +++ /dev/null @@ -1,34 +0,0 @@ -import logging - -from flask_restplus import Resource -from biolink.datamodel.serializers import association -from biolink.api.restplus import api - -from biolink.error_handlers import RouteNotImplementedException - -log = logging.getLogger(__name__) - -parser = api.parser() -#parser.add_argument('subject_taxon', help='SUBJECT TAXON id, e.g. NCBITaxon:9606. Includes inferred by default') - -class Individual(Resource): - - @api.expect(parser) - @api.marshal_list_with(association) - def get(self, id): - """ - Returns list of matches - """ - args = parser.parse_args() - raise RouteNotImplementedException() - -class Pedigree(Resource): - - @api.expect(parser) - @api.marshal_list_with(association) - def get(self, id): - """ - Returns list of matches - """ - args = parser.parse_args() - raise RouteNotImplementedException() diff --git a/biolink/api/pub/endpoints/pubs.py b/biolink/api/pub/endpoints/pubs.py deleted file mode 100644 index 9c8ee439..00000000 --- a/biolink/api/pub/endpoints/pubs.py +++ /dev/null @@ -1,32 +0,0 @@ -import logging - -from flask import request -from flask_restplus import Resource -from biolink.datamodel.serializers import association -from biolink.api.restplus import api -import pysolr - -log = logging.getLogger(__name__) - -parser = api.parser() -#parser.add_argument('subject_taxon', help='SUBJECT TAXON id, e.g. NCBITaxon:9606. Includes inferred by default') - -class Foo(Resource): - - @api.expect(parser) - @api.marshal_list_with(association) - - @api.expect(parser) - @api.marshal_list_with(association) - def get(self, term): - """ - TODO Returns list of matches - """ - args = parser.parse_args() - - return [] - - - - - diff --git a/biolink/api/variation/endpoints/analyze.py b/biolink/api/variation/endpoints/analyze.py deleted file mode 100644 index 057a0db9..00000000 --- a/biolink/api/variation/endpoints/analyze.py +++ /dev/null @@ -1,29 +0,0 @@ -import logging - -from flask_restplus import Resource -from biolink.datamodel.serializers import association -from biolink.api.restplus import api - -from biolink.error_handlers import RouteNotImplementedException - -log = logging.getLogger(__name__) - -parser = api.parser() -#parser.add_argument('subject_taxon', help='SUBJECT TAXON id, e.g. NCBITaxon:9606. Includes inferred by default') - -class Analyze(Resource): - - @api.expect(parser) - @api.marshal_list_with(association) - def get(self, term): - """ - Returns list of matches - """ - args = parser.parse_args() - raise RouteNotImplementedException() - - - - - - diff --git a/tests/association-gene-phenotype.feature b/tests/association-gene-phenotype.feature deleted file mode 100644 index 4eb3a34a..00000000 --- a/tests/association-gene-phenotype.feature +++ /dev/null @@ -1,25 +0,0 @@ -Feature: Association queries work as expected - -## Gene-Phenotype Associations - - Scenario: User queries for mouse genes with abnormal Bowman membrane phenotype - Given a path "/association/find/gene/phenotype/?subject_taxon=NCBITaxon:10090&rows=10&object=MP:0008521" - then the content should contain "abnormal Bowman membrane morphology" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].subject.id" with "string" "MGI:1342287" - and the JSON should have some JSONPath "associations[*].object.id" with "string" "MP:0008521" - and the JSON should have some JSONPath "associations[*].object.label" with "string" "abnormal Bowman membrane morphology" - - Scenario: User queries for mouse genes with cornea phenotypes (including subtypes in the ontology), omitting evidence - Given a path "/association/find/gene/phenotype/?subject_taxon=NCBITaxon:10090&rows=1000&fl_excludes_evidence=true&object=MP:0008521" - then the content should contain "abnormal Bowman membrane morphology" - when the content is converted to JSON - then the JSON should have some JSONPath "associations[*].subject.id" with "string" "MGI:1342287" - and the JSON should have some JSONPath "associations[*].object.id" with "string" "MP:0008521" - and the JSON should have some JSONPath "associations[*].object.label" with "string" "abnormal Bowman membrane morphology" - - - Scenario: User queries for mouse genes with cornea phenotypes (using an HPO ID), omitting evidence - Given a path "/association/find/gene/phenotype/?subject_taxon=NCBITaxon:10090&rows=1000&fl_excludes_evidence=true&object=HP:0000481" - then the content should contain "Abnormality of corneal thickness" - and the content should contain "abnormal Bowman membrane morphology" diff --git a/tests/association-phenotype.feature b/tests/association-phenotype.feature deleted file mode 100644 index 20215e7a..00000000 --- a/tests/association-phenotype.feature +++ /dev/null @@ -1,12 +0,0 @@ -Feature: Association queries return lists of associations - -## Phenotype Associations - - Scenario: Client wants human and mouse genes with eyelid abnormalities, using a HPO ID - Given a path "/association/find/gene/phenotype?subject_taxon=NCBITaxon:40674&object=HP:0000492&fl_excludes_evidence=true&page=1" - when the content is converted to JSON -#### then the JSON should have some JSONPath "associations[*].object.id" with "string" "HP:0011025" - - Scenario: Client wants human and mouse genes with cardiovascular phenotypes, using an MP ID - Given a path "/association/find/gene/phenotype?subject_taxon=NCBITaxon:40674&object=MP:0001340&fl_excludes_evidence=true&page=1" - when the content is converted to JSON From ce4900d5a5852f35494e3672e2bf59f0e6533c93 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 2 Mar 2022 16:44:41 -0800 Subject: [PATCH 34/34] send in the url parameter to use golr instead of monarch --- CONTRIBUTING.md | 307 --------------------- README-dependencies.md | 8 - biolink/api/entityset/endpoints/slimmer.py | 5 + bkup_travis.yml | 24 -- runtime.txt | 1 - 5 files changed, 5 insertions(+), 340 deletions(-) delete mode 100644 CONTRIBUTING.md delete mode 100644 README-dependencies.md delete mode 100644 bkup_travis.yml delete mode 100644 runtime.txt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 5673eceb..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,307 +0,0 @@ -# How to contribute code to the Monarch Initiative - -##### Audience -These guidelines are for developers of Monarch software, whether internal or in the broader community. - -## Basic principles of the Monarch-flavored [GitHub Workflow](http://guides.github.com/overviews/flow/) - -##### Principle 1: Work from a personal fork -* Prior to adopting the workflow, a developer will perform a *one-time setup* to create a personal Fork of the appropriate shared repo (e.g., `biolink-api`) and will subsequently perform their development and testing on a task-specific branch within their forked repo. This forked repo will be associated with that developer's GitHub account, and is distinct from the shared repo managed by the Monarch Initiative. - -##### Principle 2: Commit to personal branches of that fork -* Changes will never be committed directly to the master branch on the shared repo. Rather, they will be composed as branches within the developer's forked repo, where the developer can iterate and refine their code prior to submitting it for review. - -##### Principle 3: Propose changes via pull request of personal branches -* Each set of changes will be developed as a task-specific *branch* in the developer's forked repo, and then a [pull request](github.com/government/best-practices/compare) will be created to develop and propose changes to the shared repo. This mechanism provides a way for developers to discuss, revise and ultimately merge changes from the forked repo into the shared Monarch repo. - -##### Principle 4: Delete or ignore stale branches, but don't recycle merged ones -* Once a pull request has been merged, the task-specific branch is no longer needed and may be deleted or ignored. It is bad practice to reuse an existing branch once it has been merged. Instead, a subsequent branch and pull-request cycle should begin when a developer switches to a different coding task. -* You may create a pull request in order to get feedback, but if you wish to continue working on the branch, so state with "DO NOT MERGE YET". - -## Table of contents - - - -- [One Time Setup - Forking a Shared Repo](#one-time-setup---forking-a-shared-repo) - - [Step 1 - Backup your existing repo (optional)](#step-1---backup-your-existing-repo-optional) - - [Step 2 - Fork `biolink-api` via the Web](#step-2---fork-biolink-api-via-the-web) - - [Step 3 - Clone the Fork Locally](#step-3---clone-the-fork-locally) - - [Step 4 - Configure the local forked repo](#step-4---configure-the-local-forked-repo) - - [Step 5 - Configure `.bashrc` to show current branch (optional)](#step-5---configure--bashrc-to-show-current-branch-optional) -- [Typical Development Cycle](#typical-development-cycle) - - [Refresh and clean up local environment](#refresh-and-clean-up-local-environment) - - [Step 1 - Fetch remotes](#step-1---fetch-remotes) - - [Step 2 - Ensure that 'master' is up to date](#step-2---ensure-that-master-is-up-to-date) - - [Create a new branch](#create-a-new-branch) - - [Changes, Commits and Pushes](#changes-commits-and-pushes) - - [Reconcile branch with upstream changes](#reconcile-branch-with-upstream-changes) - - [Fetching the upstream branch](#fetching-the-upstream-branch) - - [Rebasing to avoid Conflicts and Merge Commits](#rebasing-to-avoid-conflicts-and-merge-commits) - - [Dealing with merge conflicts during rebase](#dealing-with-merge-conflicts-during-rebase) - - [Advanced: Interactive rebase](#advanced-interactive-rebase) - - [Submitting a PR (pull request)](#submitting-a-pr-pull-request) - - [Reviewing a pull request](#reviewing-a-pull-request) - - [Respond to TravisCI tests](#respond-to-travisci-tests) - - [Respond to peer review](#respond-to-peer-review) - - [Repushing to a PR branch](#repushing-to-a-pr-branch) - - [Merge a pull request](#merge-a-pull-request) - - [Celebrate and get back to work](#celebrate-and-get-back-to-work) -- [GitHub Tricks and Tips](#github-tricks-and-tips) -- [References and Documentation](#references-and-documentation) - - - - - -## One Time Setup - Forking a Shared Repo - -The official shared Monarch repositories (e.g., `biolink-api`, `phenogrid`) are intended to be modified solely via pull requests that are reviewed and merged by a set of responsible 'gatekeeper' developers within the Monarch development team. These pull requests are initially created as task-specific named branches within a developer's personal forked repo. - -Typically, a developer will fork a shared repo once, which creates a personal copy of the repo that is associated with the developer's GitHub account. Subsequent pull requests are developed as branches within this personal forked repo. The repo need never be forked again, although each pull request will be based upon a new named branch within this forked repo. - - -### Step 1 - Fork `biolink-api` via the Web - -The easiest way to fork the `biolink-api` repository is via the GitHub web interface: - -- Ensure you are logged into GitHub as your GitHub user. -- Navigate to the biolink-api shared repo at [https://github.com/biolink/biolink-api](https://github.com/biolink/biolink-api). -- Notice the 'Fork' button in the upper right corner. It has a number to the right of the button. -![](docs/images/githubForkButton.png) -- Click the Fork button. The resulting behavior will depend upon whether your GitHub user is a member of a GitHub organization. If not a member of an organization, then the fork operation will be performed and the forked repo will be created in the user's account. -- If your user is a member of an organization (e.g., biolink or acme-incorporated), then GitHub will present a dialog for the user to choose where to place the forked repo. The user should click on the icon corresponding to their username. -![](docs/images/githubForkTarget.png) -- *If you accidentally click the number, you will be on the Network Graphs page and should go back.* - -### Step 2 - Clone the Fork Locally - -At this point, you will have a fork of the shared repo (e.g., biolink-api) stored within GitHub, but it is not yet available on your local development machine. This is done as follows: - - # Assumes that directory ~/MI/ will contain your Monarch repos. - # Assumes that your username is MarieCurie. - # Adapt these instructions to suit your environment - > cd ~/MI - > git clone git@github.com:MarieCurie/biolink-api.git - > cd biolink-api - -Notice that we are using the SSH transport to clone this repo, rather than the HTTPS transport. The telltale indicator of this is the `git@github.com:MarieCurie...` rather than the alternative `https://github.com/MarieCurie...`. - -*Note: If you encounter difficulties with the above `git clone`, you may need to associate your local public SSH key with your GitHub account. See [Which remote URL should I use?](https://help.github.com/articles/which-remote-url-should-i-use/) for information.* - -### Step 3 - Configure the local forked repo - -The `git clone` above copied the forked repo locally, and configured the symbolic name 'origin' to point back to the *remote* GitHub fork. We will need to create an additional *remote* name to point back to the shared version of the repo (the one that we forked in Step 2). The following should work: - - # Assumes that you are already in the local biolink-api directory - > git remote add upstream https://github.com/biolink/biolink-api.git - -Verify that remotes are configured correctly by using the command `git remote -v`. The output should resemble: - - - upstream https://github.com/biolink/biolink-api.git (fetch) - upstream https://github.com/biolink/biolink-api.git (push) - origin git@github.com:MarieCurie/biolink-api.git (fetch) - origin git@github.com:MarieCurie/biolink-api.git (push) - - -### Step 4 - Configure `.bashrc` to show current branch (optional) - -One of the important things when using Git is to know what branch your working directory is tracking. This can be easily done with the `git status` command, but checking your branch periodically can get tedious. It is easy to configure your `bash` environment so that your current git branch is always displayed in your bash prompt. - -If you want to try this out, add the following to your `~/.bashrc` file: - - function parse_git_branch() - { - git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ \1/' - } - LIGHT_GRAYBG="\[\033[0;47m\]" - LIGHT_PURPLE="\[\033[0;35m\]" - NO_COLOR="\[\033[0m\]" - export PS1="$LIGHT_PURPLE\w$LIGHT_GRAYBG\$(parse_git_branch)$NO_COLOR \$ " - -You will need to open up a new Terminal window (or re-login to your existing terminal) to see the effect of the above `.bashrc` changes. - -If you cd to a git working directory, the branch will be displayed in the prompt. For example: - - ~ $ - ~ $ # This isn't a git directory, so no branch is shown - ~ $ - ~ $ cd /tmp - /tmp $ - /tmp $ # This isn't a git directory, so no branch is shown - /tmp $ - /tmp $ cd ~/MI/biolink-api/ - ~/MI/biolink-api fix-feedback-button $ - ~/MI/biolink-api fix-feedback-button $ # The current branch is shown - ~/MI/biolink-api fix-feedback-button $ - ~/MI/biolink-api fix-feedback-button $ git status - On branch fix-feedback-button - Changes not staged for commit: - (use "git add ..." to update what will be committed) - (use "git checkout -- ..." to discard changes in working directory) - ... remaining output of git status elided ... - ---- - -## Typical Development Cycle - -Once you have completed the One-time Setup above, then it will be possible to create new branches and pull requests using the instructions below. The typical development cycle will have the following phases: - -- Refresh and clean up local environment -- Create a new task-specific branch -- Perform ordinary development work, periodically committing to the branch -- Prepare and submit a Pull Request (PR) that refers to the branch -- Participate in PR Review, possibly making changes and pushing new commits to the branch -- Celebrate when your PR is finally Merged into the shared repo. -- Move onto the next task and repeat this cycle - - -### Refresh and clean up local environment - -Git will not automatically sync your Forked repo with the original shared repo, and will not automatically update your local copy of the Forked repo. These tasks are part of the developer's normal *cycle*, and should be the first thing done prior to beginning a new development effort and creating a new branch. In addition, this - -#### Step 1 - Fetch remotes - -In the (likely) event that the *upstream* repo (the biolink-api shared repo) has changed since the developer last began a task, it is important to update the local copy of the upstream repo so that its changes can be incorporated into subsequent development. - - > git fetch upstream # Updates the local copy of shared repo BUT does not affect the working directory, it simply makes the upstream code available locally for subsequent Git operations. See step 2. - -#### Step 2 - Ensure that 'master' is up to date - -Assuming that new development begins with branch 'master' (a good practice), then we want to make sure our local 'master' has all the recent changes from 'upstream'. This can be done as follows: - - > git checkout master - > git reset --hard upstream/master - -The above command is potentially dangerous if you are not paying attention, as it will remove any local commits to master (which you should not have) as well as any changes to local files that are also in the upstream/master version (which you should not have). In other words, the above command ensures a proper clean slate where your local master branch is identical to the upstream master branch. - -Some people advocate the use of `git merge upstream/master` or `git rebase upstream/master` instead of the `git reset --hard`. One risk of these options is that unintended local changes accumulate in the branch and end up in an eventual pull request. Basically, it leaves open the possibility that a developer is not really branching from upstream/master, but is branching from some developer-specific branch point. - - -### Create a new branch - -Once you have updated the local copy of the master branch of your forked repo, you can create a named branch from this copy and begin to work on your code and pull-request. This is done with: - - > git checkout -b fix-feedback-button # This is an example name - -This will create a local branch called 'fix-feedback-button' and will configure your working directory to track that branch instead of 'master'. - -You may now freely make modifications and improvements and these changes will be accumulated into the new branch when you commit. - -If you followed the instructions in [Step 5 - Configure `.bashrc` to show current branch (optional)](#step-5---configure--bashrc-to-show-current-branch-optional), your shell prompt should look something like this: - - ~/MI/biolink-api fix-feedback-button $ - -### Changes, Commits and Pushes - -Once you are in your working directory on a named branch, you make changes as normal. When you make a commit, you will be committing to the named branch by default, and not to master. - -You may wish to periodically `git push` your code to GitHub. Note the use of an explicit branch name that matches the branch you are on (this may not be necessary; a git expert may know better): - - > git push origin fix-feedback-button # This is an example name - -Note that we are pushing to 'origin', which is our forked repo. We are definitely NOT pushing to the shared 'upstream' remote, for which we may not have permission to push. - - -### Reconcile branch with upstream changes - -If you have followed the instructions above at [Refresh and clean up local environment](#refresh-and-clean-up-local-environment), then your working directory and task-specific branch will be based on a starting point from the latest-and-greatest version of the shared repo's master branch. Depending upon how long it takes you to develop your changes, and upon how much other developer activity there is, it is possible that changes to the upstream master will conflict with changes in your branch. - -So it is a good practice to periodically pull down these upstream changes and reconcile your task branch with the upstream master branch. At the least, this should be performed prior to submitting a PR. - -#### Fetching the upstream branch - -The first step is to fetch the update upstream master branch down to your local development machine. Note that this command will NOT affect your working directory, but will simply make the upstream master branch available in your local Git environment. - - > git fetch upstream - -#### Rebasing to avoid Conflicts and Merge Commits - -Now that you've fetched the upstream changes to your local Git environment, you will use the `git rebase` command to adjust your branch - - - > # Make that your changes are committed to your branch - > # before doing any rebase operations - > git status - # ... Review the git status output to ensure your changes are committed - # ... Also a good chance to double-check that you are on your - # ... task branch and not accidentally on master - > git rebase upstream/master - -The rebase command will have the effect of adjusting your commit history so that your task branch changes appear to be based upon the most recently fetched master branch, rather than the older version of master you may have used when you began your task branch. - -By periodically rebasing in this way, you can ensure that your changes are in sync with the rest of Monarch development and you can avoid hassles with merge conflicts during the PR process. - - -#### Dealing with merge conflicts during rebase - -Sometimes conflicts happen where another developer has made changes and committed them to the upstream master (ideally via a successful PR) and some of those changes overlap with the code you are working on in your branch. The `git rebase` command will detect these conflicts and will give you an opportunity to fix them before continuing the rebase operation. The Git instructions during rebase should be sufficient to understand what to do, but a very verbose explanation can be found at [Rebasing Step-by-Step](http://gitforteams.com/resources/rebasing.html) - -#### Advanced: Interactive rebase - -As you gain more confidence in Git and this workflow, you may want to create PRs that are easier to review and best reflect the intent of your code changes. One technique that is helpful is to use the *interactive rebase* capability of Git to help you clean up your branch prior to submitting it as a PR. This is completely optional for novice Git users, but it does produce a nicer shared commit history. - -See [squashing commits with rebase](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) for a good explanation. - - -### Submitting a PR (pull request) - -Once you have developed code and are confident it is ready for review and final integration into the upstream version, you will want to do a final `git push origin ...` (see Changes, Commits and Pushes above). Then you will use the GitHub website to perform the operation of creating a Pull Request based upon the newly pushed branch. - -See [submitting a pull request](https://help.github.com/articles/creating-a-pull-request). - - -### Reviewing a pull request - -The set of open PRs for the biolink-api can be viewed by first visiting the shared biolink-api GitHub page at [https://github.com/biolink/biolink-api](https://github.com/biolink/biolink-api). - -Click on the 'Pull Requests' link on the right-side of the page: -![](docs/images/githubPullRequest.png) - -Note that the Pull Request you created from your forked repo shows up in the shared repo's Pull Request list. One way to avoid confusion is to think of the shared repo's PR list as a queue of changes to be applied, pending their review and approval. - -### Respond to TravisCI tests - -The GitHub Pull Request mechanism is designed to allow review and refinement of code prior to its final merge to the shared repo. After creating your Pull Request, the TravisCI tests for biolink-api will be executed automatically, ensuring that the code that 'worked fine' on your development machine also works in the production-like environment provided by TravisCI. The current status of the tests can be found near the bottom of the individual PR page, to the right of the Merge Request symbol: -![](docs/images/githubTestProgress.png) -![](docs/images/githubTestStatus.png) - -TBD - Something should be written about developers running tests PRIOR to TravisCI and the the PR. This may already be in the README.md, but should be cited. - - -### Respond to peer review - -The GitHub Pull Request mechanism is designed to allow review and refinement of code prior to its final merge to the shared repo. After creating your Pull Request, the TravisCI tests for biolink-api will be executed automatically, ensuring that the code that 'worked fine' on your development machine also works in the production-like environment provided by TravisCI. The current status of the tests can be found - -### Repushing to a PR branch - -It's likely that after created a Pull Request, you will receive useful peer review or your TravisCI tests will have failed. In either case, you will make the required changes on your development machine, retest your changes, and you can then push your new changes back to your task branch and the PR will be automatically updated. This allows a PR to evolve in response to feedback from peers. Once everyone is satisfied, the PR may be merged. (see below). - - -### Merge a pull request - -One of the goals behind the workflow described here is to enable a large group of developers to meaningfully contribute to the Monarch codebase. The Pull Request mechanism encourages review and refinement of the proposed code changes. As a matter of informal policy, Monarch expects that a PR will not be merged by its author and that a PR will not be merged without at least one reviewer approving it (via a comment such as +1 in the PR's Comment section). - -### Celebrate and get back to work - -You have successfully gotten your code improvements into the shared repository. Congratulations! The branch you created for this PR is no longer useful, and may be deleted from your forked repo or may be kept. But in no case should the branch be further developed or reused once it has been successfully merge. Subsequent development should be on a new branch. Prepare for your next work by returning to [Refresh and clean up local environment](#refresh-and-clean-up-local-environment). - ---- - -## GitHub Tricks and Tips - -- Add `?w=1` to a GitHub file compare URL to ignore whitespace differences. - - -## References and Documentation - -- The instructions presented here are derived from several sources. However, a very readable and complete article is [Using the Fork-and-Branch Git Workflow](http://blog.scottlowe.org/2015/01/27/using-fork-branch-git-workflow/). Note that the article doesn't make clear that certain steps like Forking are one-time setup steps, after which Branch-PullRequest-Merge steps are used; the instructions below will attempt to clarify this. - -- New to GitHub? The [GitHub Guides](http://guides.github.com) are a great place to start. - -- Advanced GitHub users might want to check out the [GitHub Cheat Sheet](https://github.com/tiimgreen/github-cheat-sheet/blob/master/README.md) -- - -## Notes - -The process described below is initially intended to be used in the `biolink-api` repository, although it may later be adopted by the other Monarch-related source code repositories, such as `phenogrid`. diff --git a/README-dependencies.md b/README-dependencies.md deleted file mode 100644 index 3158660f..00000000 --- a/README-dependencies.md +++ /dev/null @@ -1,8 +0,0 @@ - -Some of these may be moved into separate modules, https://github.com/biolink/biolink-api/issues/49 - -biolink <- prefixcommons, biogolr, obographs, biowikidata, causalmodels -prefixcommons <- [] -biogolr <- prefixcommons -obographs <- prefixcommons, biogolr - diff --git a/biolink/api/entityset/endpoints/slimmer.py b/biolink/api/entityset/endpoints/slimmer.py index cbd52fc0..2733985f 100644 --- a/biolink/api/entityset/endpoints/slimmer.py +++ b/biolink/api/entityset/endpoints/slimmer.py @@ -3,6 +3,8 @@ from ontobio.golr.golr_associations import map2slim from biolink.api.restplus import api from biolink import USER_AGENT +from biolink.settings import get_biolink_config +from pprint import pprint from biothings_client import get_client @@ -66,11 +68,14 @@ def get(self): else: slimmer_subjects.append(s) + solr_assocs = get_biolink_config() + results = map2slim( subjects=slimmer_subjects, slim=slim, object_category='function', user_agent=USER_AGENT, + url=solr_assocs.get("amigo_solr_assocs").get("url"), **args ) diff --git a/bkup_travis.yml b/bkup_travis.yml deleted file mode 100644 index 0316d6ac..00000000 --- a/bkup_travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -dist: xenial - -language: python -python: - - "3.7.4" - -# command to install dependencies -install: - - pip install git+https://github.com/biolink/ontobio.git - - pip install -r requirements.txt - -before_script: - - "export PYTHONPATH=.:$PYTHONPATH" - - "export FLASK_USE_RELOADER=False" - -# command to run tests -script: - - "python biolink/app.py" - - tail log.txt - - sleep 45 - - behave -f progress3 tests/ - -#after_success: -# coveralls diff --git a/runtime.txt b/runtime.txt deleted file mode 100644 index c0354eef..00000000 --- a/runtime.txt +++ /dev/null @@ -1 +0,0 @@ -python-3.5.2