22
33import dotenv
44import httpx
5- from fastapi import APIRouter , Body , Depends , HTTPException , Request , Response , status
5+ from fastapi import (
6+ APIRouter ,
7+ Body ,
8+ Depends ,
9+ HTTPException ,
10+ Query ,
11+ Request ,
12+ Response ,
13+ status ,
14+ )
615from slugify import slugify
716from sqlalchemy import func , insert , select , update
817from sqlalchemy .exc import NoResultFound , NoSuchTableError
3039from api .query_parser import ParserException
3140from api .routes .security import has_access
3241
33- interchange_router = APIRouter (
34- prefix = "/interchange-data " ,
35- tags = ["interchange-data " ],
42+ convert_router = APIRouter (
43+ prefix = "/convert " ,
44+ tags = ["convert " ],
3645 responses = {404 : {"description" : "Not found" }},
3746)
3847
@@ -176,13 +185,12 @@ def spot_to_fieldsite(feat) -> FieldSite:
176185 )
177186
178187
179- @interchange_router .post ("/spot-to-fieldsite" )
180188def multiple_spot_to_fieldsite (
181189 feat : Union [dict , List [dict ]] = Body (...)
182190) -> List [FieldSite ]:
183191 """
184192 Accept a single FeatureCollection or a list of FeatureCollections and
185- return a FieldSite for each qualifying Point feature (non-image-basemap) .
193+ return a FieldSite for each qualifying Point feature.
186194 """
187195 out : list [FieldSite ] = []
188196
@@ -229,23 +237,21 @@ def fieldsite_to_checkin(fs: FieldSite) -> dict:
229237 return d
230238
231239
232- @interchange_router .post ("/fieldsite-to-checkin" )
233240def multiple_fieldsite_to_checkin (
234241 fieldsites : list [FieldSite ] = Body (...),
235242) -> list [dict ]:
236243 out : list [dict ] = []
237244 for fs in fieldsites :
238245 try :
246+ if not isinstance (fs , FieldSite ):
247+ fs = FieldSite (** fs )
239248 out .append (fieldsite_to_checkin (fs ))
240249 except Exception :
241250 continue
242251 return out
243252
244253
245- @interchange_router .post ("/spot-to-checkin" )
246- async def spot_to_checkin (
247- request : Request , spot : Union [dict , List [dict ]] = Body (...)
248- ) -> list [dict ]:
254+ def spot_to_checkin (spot : Union [dict , List [dict ]] = Body (...)) -> list [dict ]:
249255 """Pipeline: Spot JSON (FeatureCollection[s]) or FieldSite list -> Checkin list."""
250256 # If it's already a list of FieldSite-like dicts (has 'location'), skip the first hop
251257 if (
@@ -258,6 +264,30 @@ async def spot_to_checkin(
258264 else :
259265 # Convert FeatureCollection (or list of them) -> FieldSite list
260266 fieldsites = multiple_spot_to_fieldsite (spot )
261-
262267 # Convert FieldSite list -> Checkin list
263268 return multiple_fieldsite_to_checkin (fieldsites )
269+
270+
271+ @convert_router .post ("/field-site" )
272+ async def convert_field_site (
273+ payload : Union [dict , List [dict ]] = Body (...),
274+ in_ : str = Query (..., alias = "in" ),
275+ out : str = Query (..., alias = "out" ),
276+ ) -> Any :
277+ """
278+ Unified converter:
279+ - ?in=spot&out=fieldsite -> spot FeatureCollection(s) -> FieldSite
280+ - ?in=fieldsite&out=checkin -> FieldSite -> Checkin
281+ - ?in=spot&out=checkin -> spot FeatureCollection(s) -> FieldSite -> Checkin
282+ """
283+ key = (in_ .lower (), out .lower ())
284+ if key == ("spot" , "fieldsite" ):
285+ return multiple_spot_to_fieldsite (payload )
286+ if key == ("fieldsite" , "checkin" ):
287+ return multiple_fieldsite_to_checkin (payload )
288+ if key == ("spot" , "checkin" ):
289+ return spot_to_checkin (payload )
290+ raise HTTPException (
291+ status_code = 400 ,
292+ detail = "Unsupported conversion. Use in=[spot|fieldsite], out=[fieldsite|checkin]." ,
293+ )
0 commit comments