5
5
import logging
6
6
7
7
from flask import Flask , jsonify , make_response , abort , render_template , request
8
- # from apispec import APISpec
9
- # from apispec.ext.marshmallow import MarshmallowPlugin
10
- # from apispec_webframeworks.flask import FlaskPlugin
11
- # from flask_swagger_ui import get_swaggerui_blueprint
12
8
from flasgger import Swagger , swag_from
13
9
from db import get_mongo_connection
14
10
from concurrent .futures import ThreadPoolExecutor
@@ -647,23 +643,10 @@ def associated_string_genes(gene_symbol: str, min_combined_score: int = 400) ->
647
643
return res
648
644
649
645
650
- # Create an APISpec
651
- # spec = APISpec(
652
- # title="BioAPI",
653
- # version=VERSION,
654
- # openapi_version="2.0.0",
655
- # info=dict(
656
- # description="""
657
- # ## A powerful abstraction of genomics databases.
658
- # BioAPI is part of the Multiomix project. For more information, visit our [website](https://omicsdatascience.org/).
659
- # To contribute: [OmicsDatascience](https://github.com/omics-datascience/BioAPI)"""),
660
- # plugins=[FlaskPlugin()],
661
- # )
662
-
663
-
664
646
def create_app ():
665
647
# Creates and configures the app
666
648
flask_app = Flask (__name__ , instance_relative_config = True )
649
+
667
650
swagger_config = {
668
651
"headers" : [
669
652
],
@@ -672,8 +655,8 @@ def create_app():
672
655
{
673
656
"endpoint" : "swagger" ,
674
657
"route" : "/apispec.json" ,
675
- "rule_filter" : lambda rule : True , # all in
676
- "model_filter" : lambda tag : True , # all in
658
+ "rule_filter" : lambda rule : True ,
659
+ "model_filter" : lambda tag : True
677
660
}
678
661
],
679
662
"title" : "BioAPI" ,
@@ -726,8 +709,6 @@ def gene_symbols():
726
709
return make_response (response , 200 , headers )
727
710
728
711
@flask_app .route ("/gene-symbols-finder/" , methods = ['GET' ])
729
- # @doc(description='Gene symbols finder', tags=['Genes'])
730
- # @use_kwargs(args=swagger_schemas.GeneSymbolsFinderRequestSchema, location="query")
731
712
@swag_from ("swagger_specs/geneSymbolFinder.yml" )
732
713
def gene_symbol_finder ():
733
714
"""Takes a string of any length and returns a list of genes that contain that search criteria."""
@@ -751,8 +732,6 @@ def gene_symbol_finder():
751
732
abort (400 , e )
752
733
753
734
@flask_app .route ("/information-of-genes" , methods = ['POST' ])
754
- # @doc(description='Genes information', tags=['Genes'], consumes=["application/json"])
755
- # @use_kwargs(args=swagger_schemas.InformationOfGenesRequestSchema, location="json")
756
735
@swag_from ("swagger_specs/informationOfGenes.yml" )
757
736
def information_of_genes ():
758
737
"""Receives a list of gene IDs and returns information about them."""
@@ -771,7 +750,6 @@ def information_of_genes():
771
750
return make_response (response , 200 , headers )
772
751
773
752
@flask_app .route ("/genes-of-its-group/<gene_id>" , methods = ['GET' ])
774
- # @doc(description='Gene Groups', tags=['Genes'], params={"gene_id": {"description": "Identifier of the gene for any database", "type": "string", "required": True}})
775
753
@swag_from ("swagger_specs/genesOfItsGroup.yml" )
776
754
def genes_in_the_same_group (gene_id : str ):
777
755
response = {"gene_id" : None , "groups" : [],
@@ -809,9 +787,6 @@ def genes_in_the_same_group(gene_id: str):
809
787
810
788
@flask_app .route ("/pathway-genes/<pathway_source>/<pathway_id>" , methods = ['GET' ])
811
789
@swag_from ("swagger_specs/genesOfMetabolicPathway.yml" )
812
- # @doc(description='Genes of a metabolic pathway', tags=['Genes'],
813
- # params={"pathway_source": {"description": "Database to query", "type": "string", "required": True, "example": "kegg", "enum": ["kegg", "biocarta", "ehmn", "humancyc", "inoh", "netpath", "pid", "reactome", "smpdb", "signalink", "wikipathways"]},
814
- # "pathway_id": {"description": "Pathway identifier in the source database", "type": "string", "required": True, "example": "hsa00740"}})
815
790
def pathway_genes (pathway_source , pathway_id ):
816
791
if pathway_source .lower () not in PATHWAYS_SOURCES :
817
792
abort (404 , f'{ pathway_source } is an invalid pathway source' )
@@ -820,18 +795,17 @@ def pathway_genes(pathway_source, pathway_id):
820
795
return make_response (response , 200 , headers )
821
796
822
797
@flask_app .route ("/pathways-in-common" , methods = ['POST' ])
823
- # @doc(description='Metabolic pathways from different genes', tags=['Pathways'], consumes=["application/json"])
824
- # @use_kwargs(args=swagger_schemas.PathwaysInCommonRequestSchema, location="json")
825
- def pathways_in_common (gene_ids : List [str ]):
826
- # body = request.get_json() # type: ignore
827
- # if "gene_ids" not in body:
828
- # abort(400, "gene_ids is mandatory")
829
-
830
- # gene_ids = body['gene_ids']
831
- # if not isinstance(gene_ids, list):
832
- # abort(400, "gene_ids must be a list")
833
- # if len(gene_ids) == 0:
834
- # abort(400, "gene_ids must contain at least one gene symbol")
798
+ @swag_from ("swagger_specs/pathwaysInCommon.yml" )
799
+ def pathways_in_common ():
800
+ body = request .get_json () # type: ignore
801
+ if "gene_ids" not in body :
802
+ abort (400 , "gene_ids is mandatory" )
803
+
804
+ gene_ids = body ['gene_ids' ]
805
+ if not isinstance (gene_ids , list ):
806
+ abort (400 , "gene_ids must be a list" )
807
+ if len (gene_ids ) == 0 :
808
+ abort (400 , "gene_ids must contain at least one gene symbol" )
835
809
836
810
pathways_tmp = [get_pathways_of_gene (gene ) for gene in gene_ids ]
837
811
pathways_intersection = list (set .intersection (* map (set , pathways_tmp )))
@@ -842,36 +816,35 @@ def pathways_in_common(gene_ids: List[str]):
842
816
return make_response (response , 200 , headers )
843
817
844
818
@flask_app .route ("/expression-of-genes" , methods = ['POST' ])
845
- # @doc(description='Gets gene expression in healthy tissue', tags=['Expression Data'], consumes=["application/json"])
846
- # @use_kwargs(args=swagger_schemas.ExpressionOfGenesRequestSchema, location="json")
847
- def expression_data_from_gtex (gene_ids : list [str ], tissue : str , type : str ):
848
- # body = request.get_json() # type: ignore
819
+ @swag_from ("swagger_specs/expressionOfGenes.yml" )
820
+ def expression_data_from_gtex ():
821
+ body = request .get_json () # type: ignore
849
822
850
- # if "gene_ids" not in body:
851
- # abort(400, "gene_ids is mandatory")
823
+ if "gene_ids" not in body :
824
+ abort (400 , "gene_ids is mandatory" )
852
825
853
- # gene_ids = body['gene_ids']
854
- # if not isinstance(gene_ids, list):
855
- # abort(400, "gene_ids must be a list")
826
+ gene_ids = body ['gene_ids' ]
827
+ if not isinstance (gene_ids , list ):
828
+ abort (400 , "gene_ids must be a list" )
856
829
857
- # if len(gene_ids) == 0:
858
- # abort(400, "gene_ids must contain at least one gene symbol")
830
+ if len (gene_ids ) == 0 :
831
+ abort (400 , "gene_ids must contain at least one gene symbol" )
859
832
860
- # if "tissue" not in body:
861
- # abort(400, "tissue is mandatory")
833
+ if "tissue" not in body :
834
+ abort (400 , "tissue is mandatory" )
862
835
863
- # tissue = body['tissue']
864
- # if "type" in body:
865
- # if body['type'] not in ["gzip", "json"]:
866
- # abort(400, "allowed values for the 'type' key are 'json' or 'gzip'")
867
- # else:
868
- # type_response = body['type']
869
- # else:
870
- # type_response = 'json'
836
+ tissue = body ['tissue' ]
837
+ if "type" in body :
838
+ if body ['type' ] not in ["gzip" , "json" ]:
839
+ abort (400 , "allowed values for the 'type' key are 'json' or 'gzip'" )
840
+ else :
841
+ type_response = body ['type' ]
842
+ else :
843
+ type_response = 'json'
871
844
872
845
expression_data = get_expression_from_gtex (tissue , gene_ids )
873
846
874
- if type == "gzip" :
847
+ if type_response == "gzip" :
875
848
content = gzip .compress (json .dumps (
876
849
expression_data ).encode ('utf8' ), 5 )
877
850
response = make_response (content )
@@ -881,9 +854,8 @@ def expression_data_from_gtex(gene_ids: list[str], tissue: str, type: str):
881
854
return jsonify (expression_data )
882
855
883
856
@flask_app .route ("/genes-to-terms" , methods = ['POST' ])
884
- # @doc(description='Gene Ontology terms related to a list of genes', tags=['Gene Ontology'], consumes=["application/json"])
885
- # @use_kwargs(args=swagger_schemas.GenesToTermsRequestSchema, location="json")
886
- def genes_to_go_terms (gene_ids : list [str ], filter_type : str , p_value_threshold : float | None , correction_method : str , relation_type : list [str ], ontology_type : list [str ]):
857
+ @swag_from ("swagger_specs/genesToTerms.yml" )
858
+ def genes_to_go_terms ():
887
859
"""Receives a list of genes and returns the related terms"""
888
860
valid_filter_types = ["union" , "intersection" , "enrichment" ]
889
861
valid_ontology_types = ["biological_process" ,
@@ -970,6 +942,7 @@ def genes_to_go_terms(gene_ids: list[str], filter_type: str, p_value_threshold:
970
942
return jsonify (response )
971
943
972
944
@flask_app .route ("/related-terms" , methods = ['POST' ])
945
+ @swag_from ("swagger_specs/relatedTerms.yml" )
973
946
def related_terms ():
974
947
"""Receives a term and returns the related terms"""
975
948
valid_ontology_types = ["biological_process" ,
@@ -1017,19 +990,18 @@ def related_terms():
1017
990
return jsonify (response )
1018
991
1019
992
@flask_app .route ("/information-of-oncokb" , methods = ['POST' ])
1020
- # @doc(description='Therapies and actionable genes in cancer', tags=['Genes'], consumes=["application/json"])
1021
- # @use_kwargs(args=swagger_schemas.InformationOfOncokbRequestSchema, location="json")
1022
- def oncokb_data (gene_ids : list [str ], query : str ):
1023
- # body = request.get_json() # type: ignore
993
+ @swag_from ("swagger_specs/informationOfOncokb.yml" )
994
+ def oncokb_data ():
995
+ body = request .get_json () # type: ignore
1024
996
1025
- # if "gene_ids" not in body:
1026
- # abort(400, "gene_ids is mandatory")
997
+ if "gene_ids" not in body :
998
+ abort (400 , "gene_ids is mandatory" )
1027
999
1028
- # gene_ids = body['gene_ids']
1029
- # query = "" if "query" not in body else body['query']
1000
+ gene_ids = body ['gene_ids' ]
1001
+ query = "" if "query" not in body else body ['query' ]
1030
1002
1031
- # if not isinstance(gene_ids, list):
1032
- # abort(400, "gene_ids must be a list")
1003
+ if not isinstance (gene_ids , list ):
1004
+ abort (400 , "gene_ids must be a list" )
1033
1005
1034
1006
if len (gene_ids ) == 0 :
1035
1007
abort (400 , "gene_ids must contain at least one gene symbol" )
@@ -1039,6 +1011,7 @@ def oncokb_data(gene_ids: list[str], query: str):
1039
1011
return jsonify (data )
1040
1012
1041
1013
@flask_app .route ("/drugs-pharm-gkb" , methods = ['POST' ])
1014
+ @swag_from ("swagger_specs/cancerDrugsRelatedToGenes.yml" )
1042
1015
def cancer_drugs_related_to_genes ():
1043
1016
"""Receives genes and returns the related drugs"""
1044
1017
response = {}
@@ -1053,6 +1026,7 @@ def cancer_drugs_related_to_genes():
1053
1026
return jsonify (response )
1054
1027
1055
1028
@flask_app .route ("/string-relations" , methods = ['POST' ])
1029
+ @swag_from ("swagger_specs/stringRelations.yml" )
1056
1030
def string_relations_to_gene ():
1057
1031
body = request .get_json ()
1058
1032
optionals = {}
@@ -1070,6 +1044,7 @@ def string_relations_to_gene():
1070
1044
return jsonify (res )
1071
1045
1072
1046
@flask_app .route ("/drugs-regulating-gene/<gene_id>" , methods = ['GET' ])
1047
+ @swag_from ("swagger_specs/drugsRegulatingGene.yml" )
1073
1048
def drugs_regulating_gene (gene_id ):
1074
1049
return {
1075
1050
"link" : "https://go.drugbank.com/pharmaco/transcriptomics?q%5Bg%5B0%5D%5D%5Bm%5D=or&q%5Bg%5B0%5D%5D"
0 commit comments