web-client/bff/tracker_client.py
Markov 2f1778c821
Some checks failed
Deploy Web Client / deploy (push) Has been cancelled
feat: BFF (Python FastAPI) — proxy to Tracker with JWT auth
- BFF on port 8200: auth + proxy to tracker
- All /api/* routes go through BFF
- WebSocket proxy with JWT auth
- Tracker no longer exposed to internet
- Logging on all requests
- Removed Next.js API routes for auth (BFF handles it)
2026-02-15 19:44:55 +01:00

63 lines
1.6 KiB
Python

"""HTTP client for Tracker API."""
import logging
from typing import Any, Optional
import httpx
from config import TRACKER_URL, TRACKER_TOKEN
logger = logging.getLogger("bff.tracker")
_client: Optional[httpx.AsyncClient] = None
def get_client() -> httpx.AsyncClient:
global _client
if _client is None or _client.is_closed:
_client = httpx.AsyncClient(
base_url=TRACKER_URL,
headers={"Authorization": f"Bearer {TRACKER_TOKEN}"},
timeout=30.0,
)
return _client
async def tracker_request(method: str, path: str, **kwargs) -> httpx.Response:
client = get_client()
logger.info("[TRACKER] %s %s", method, path)
resp = await client.request(method, path, **kwargs)
logger.info("[TRACKER] %s %s%d", method, path, resp.status_code)
return resp
async def tracker_get(path: str, **kwargs) -> Any:
resp = await tracker_request("GET", path, **kwargs)
resp.raise_for_status()
return resp.json()
async def tracker_post(path: str, **kwargs) -> Any:
resp = await tracker_request("POST", path, **kwargs)
resp.raise_for_status()
return resp.json()
async def tracker_patch(path: str, **kwargs) -> Any:
resp = await tracker_request("PATCH", path, **kwargs)
resp.raise_for_status()
return resp.json()
async def tracker_delete(path: str, **kwargs) -> int:
resp = await tracker_request("DELETE", path, **kwargs)
resp.raise_for_status()
return resp.status_code
async def close_client():
global _client
if _client and not _client.is_closed:
await _client.aclose()
_client = None