11from flask import Flask , jsonify , request
22from flask_restful import Resource
3- from ormgap import Crop , Group , Accession , Country
3+ from ormgap import Crop , Group , Accession , Country , Project
44import re
55
66def is_valid_object_id (value ):
@@ -12,6 +12,138 @@ def is_valid_object_id(value):
1212 pattern = re .compile ("[0-9a-f]{24}" )
1313 return pattern .match (value ) is not None
1414
15+ class AccessionsByIDCropProject (Resource ):
16+
17+ def __init__ (self ):
18+ super ().__init__ ()
19+
20+ def get (self ):
21+ """
22+ Get accessions from database by crop id(s), iso, and project ext_id
23+ ---
24+ parameters:
25+ - name: id
26+ in: query
27+ description: Crop id(s)
28+ required: true
29+ type: string
30+ example: 6035f5e5c6be2f14d07d6c7d or 6035f5e5c6be2f14d07d6c7d,6035f5e5c6be2f14d07d6c7e
31+ - name: iso
32+ in: query
33+ description: ISO code of the country
34+ required: true
35+ type: string
36+ example: KE
37+ - name: project
38+ in: query
39+ description: The external project identifier
40+ required: true
41+ type: string
42+ example: "lga" or "bolder"
43+ responses:
44+ 200:
45+ description: List of accessions based on provided filters
46+ schema:
47+ id: Accession
48+ properties:
49+ id:
50+ type: string
51+ description: Id of the accession
52+ species_name:
53+ type: string
54+ description: Name of the species of the accession.
55+ crop:
56+ type: string
57+ description: Id of the crop that the accession belongs to.
58+ landrace_group:
59+ type: string
60+ description: Id group that the landrace belongs to.
61+ country:
62+ type: string
63+ description: Iso2 country to which the accession belongs.
64+ institution_name:
65+ type: string
66+ description: Name of the institution that holds the accession.
67+ source_database:
68+ type: string
69+ description: Name of the database where the accession was originally stored. Optional.
70+ latitude:
71+ type: float
72+ description: Latitude of the geographical location where the accession was collected.
73+ longitude:
74+ type: float
75+ description: Longitude of the geographical location where the accession was collected.
76+ accession_id:
77+ type: string
78+ description: The identifier of the accession in source database.
79+ ext_id:
80+ type: string
81+ description: External identifier for the accession.
82+ other_attributes:
83+ type: dict
84+ description: Additional attributes of the accession.
85+ """
86+ # Retrieve the parameters
87+ crop_ids = request .args .get ('id' ) # Comma separated crop ids
88+ iso = request .args .get ('iso' ) # Country iso
89+ project_ext_id = request .args .get ('project' ) # Project external id
90+
91+ # Validate inputs
92+ if not crop_ids or not iso or not project_ext_id :
93+ return {'error' : 'Crop ID(s), Iso 2, and Project ext_id are required' }, 400
94+
95+ # Convert iso to uppercase and process crop_ids
96+ iso = iso .upper ()
97+ crop_id_list = list (dict .fromkeys (crop_ids .replace (" " , "" ).split (',' )))
98+
99+ # Get country by iso
100+ country = Country .objects (iso_2 = iso ).first ()
101+ if not country :
102+ return {"error" : f"Country with iso 2 '{ iso } ' not found" }, 404
103+
104+ # Get project by ext_id
105+ project = Project .objects (ext_id = project_ext_id ).first ()
106+ if not project :
107+ return {"error" : f"Project with ext_id '{ project_ext_id } ' not found" }, 404
108+
109+ # Prepare list to store results
110+ json_data = []
111+
112+ for crop_id in crop_id_list :
113+ if is_valid_object_id (crop_id ):
114+ crop = Crop .objects (id = crop_id ).first ()
115+ if crop :
116+ # Filter accessions by crop, country, and project
117+ accessions = Accession .objects (crop = crop , country = country , project = project )
118+ crop_data = {
119+ "crop_id" : str (crop .id ),
120+ "accessions" : [
121+ {
122+ "id" : str (x .id ),
123+ "species_name" : x .species_name ,
124+ "ext_id" : x .ext_id ,
125+ "crop" : str (x .crop .id ),
126+ "landrace_group" : str (x .landrace_group .id ) if x .landrace_group else None ,
127+ "country" : x .country .iso_2 ,
128+ "institution_name" : x .institution_name ,
129+ "source_database" : x .source_database ,
130+ "latitude" : x .latitude ,
131+ "longitude" : x .longitude ,
132+ "accession_id" : x .accession_id ,
133+ "other_attributes" : x .other_attributes
134+ }
135+ for x in accessions
136+ ]
137+ }
138+ json_data .append (crop_data )
139+ else :
140+ json_data .append ({"crop_id" : crop_id , "error" : "Crop not found" })
141+ else :
142+ json_data .append ({"crop_id" : crop_id , "error" : "Invalid crop ID" })
143+
144+ return jsonify (json_data )
145+
146+
15147class AccessionsByIDCrop (Resource ):
16148
17149 def __init__ (self ):
@@ -105,7 +237,7 @@ def get(self):
105237 crop_data = {"crop_id" : str (crop .id ),
106238 "accessions" : [{"id" : str (x .id ), "species_name" : x .species_name ,
107239 "ext_id" : x .ext_id , "crop" : str (x .crop .id ),
108- "landrace_group" :str (x .landrace_group .id ),
240+ "landrace_group" : str (x .landrace_group .id ) if x . landrace_group else None ,
109241 "country" : x .country .iso_2 ,
110242 "institution_name" :x .institution_name ,
111243 "source_database" :x .source_database ,
@@ -215,7 +347,7 @@ def get(self):
215347 group_data = {"group_id" : str (group .id ),
216348 "accessions" : [{"id" : str (x .id ), "species_name" : x .species_name ,
217349 "ext_id" : x .ext_id , "crop" : str (x .crop .id ),
218- "landrace_group" :str (x .landrace_group .id ),
350+ "landrace_group" : str (x .landrace_group .id ) if x . landrace_group else None ,
219351 "country" : x .country .iso_2 ,
220352 "institution_name" :x .institution_name ,
221353 "source_database" :x .source_database ,
0 commit comments