diff --git a/routes/reslevis.py b/routes/reslevis.py index 67df1f7..99c47f6 100644 --- a/routes/reslevis.py +++ b/routes/reslevis.py @@ -1,8 +1,10 @@ import asyncio +import json from fastapi import APIRouter, Depends, HTTPException, Query, Request import httpx import config_env from typing import List, Optional +from urllib.parse import urlencode from schemas.reslevis import ( BuildingItem, @@ -170,12 +172,42 @@ async def _core_get_json( raise HTTPException(status_code=502, detail="Invalid CORE response") from exc +async def _core_get_json_via_curl( + path: str, + params: Optional[dict] = None, +): + query_string = urlencode(params or {}) + url = f"{CORE_BASE_URL}{path}" + if query_string: + url = f"{url}?{query_string}" + + cmd = ["curl", "-sS", "-X", "GET"] + if CORE_BASE_URL.startswith("https://"): + cmd.append("-k") + cmd.append(url) + + process = await asyncio.create_subprocess_exec( + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout, stderr = await process.communicate() + + if process.returncode != 0: + detail = (stderr or stdout).decode("utf-8", errors="replace").strip() or "CORE curl request failed" + raise HTTPException(status_code=502, detail=detail) + + try: + return json.loads(stdout.decode("utf-8")) + except ValueError as exc: + raise HTTPException(status_code=502, detail="Invalid CORE response") from exc + + async def _fetch_tracks_for_tracker( - client: httpx.AsyncClient, tracker_id: str, params: Optional[dict] = None, ) -> List[dict]: - payload = await _core_get_json(client, f"/reslevis/getTracks/{tracker_id}", params=params) + payload = await _core_get_json_via_curl(f"/reslevis/getTracks/{tracker_id}", params=params) if not isinstance(payload, list): raise HTTPException(status_code=502, detail="Unexpected CORE response type") return [_normalize_track(row) for row in payload if isinstance(row, dict)] @@ -186,22 +218,21 @@ def _sort_tracks_desc(rows: List[dict]) -> List[dict]: async def _fetch_all_tracks(params: dict) -> List[dict]: - async with httpx.AsyncClient(timeout=30.0, verify=False) as client: - trackers_payload = await _core_get_json(client, "/reslevis/getTrackers") - if not isinstance(trackers_payload, list): - raise HTTPException(status_code=502, detail="Unexpected CORE tracker response type") - - tracker_ids = [] - for item in trackers_payload: - if not isinstance(item, dict): - continue - tracker_id = item.get("id") - if tracker_id: - tracker_ids.append(str(tracker_id)) - - batches = await asyncio.gather( - *[_fetch_tracks_for_tracker(client, tracker_id, params) for tracker_id in tracker_ids] - ) + trackers_payload = await _core_get_json_via_curl("/reslevis/getTrackers") + if not isinstance(trackers_payload, list): + raise HTTPException(status_code=502, detail="Unexpected CORE tracker response type") + + tracker_ids = [] + for item in trackers_payload: + if not isinstance(item, dict): + continue + tracker_id = item.get("id") + if tracker_id: + tracker_ids.append(str(tracker_id)) + + batches = await asyncio.gather( + *[_fetch_tracks_for_tracker(tracker_id, params) for tracker_id in tracker_ids] + ) merged = [row for batch in batches for row in batch] merged = _sort_tracks_desc(merged) @@ -402,13 +433,9 @@ async def getTracks( selected_tracker_id = tracker_id or request.query_params.get("id") - try: - if selected_tracker_id: - async with httpx.AsyncClient(timeout=30.0, verify=False) as client: - return await _fetch_tracks_for_tracker(client, selected_tracker_id, params) - return await _fetch_all_tracks(params) - except httpx.RequestError as exc: - raise HTTPException(status_code=502, detail=f"CORE request failed: {exc}") from exc + if selected_tracker_id: + return await _fetch_tracks_for_tracker(selected_tracker_id, params) + return await _fetch_all_tracks(params) @router.get( @@ -431,11 +458,7 @@ async def getTrack( if to: params["to"] = to - try: - async with httpx.AsyncClient(timeout=30.0, verify=False) as client: - return await _fetch_tracks_for_tracker(client, tracker_id, params) - except httpx.RequestError as exc: - raise HTTPException(status_code=502, detail=f"CORE request failed: {exc}") from exc + return await _fetch_tracks_for_tracker(tracker_id, params) @router.post("/postTrack", tags=["Reslevis"], dependencies=[Depends(get_current_user)])