Ekaropolus 0eb2b393f2
All checks were successful
continuous-integration/drone/push Build is passing
SAMI Functionality add
2025-09-16 16:18:45 -06:00

77 lines
2.4 KiB
Python

# pxy_routing/api/views.py
from __future__ import annotations
import uuid
from rest_framework.decorators import api_view, throttle_classes
from rest_framework.response import Response
from rest_framework import status
from rest_framework.throttling import ScopedRateThrottle
from pxy_routing.services.factory import get_routing_provider
def _err(code: str, message: str, hint: str | None = None, http_status: int = 400):
return Response(
{
"ok": False,
"code": code,
"message": message,
"hint": hint,
"trace_id": str(uuid.uuid4()),
},
status=http_status,
)
@api_view(["GET"])
@throttle_classes([ScopedRateThrottle])
def routing_health(request):
routing_health.throttle_scope = "routing_health" # DRF scoped throttle
provider = get_routing_provider()
try:
info = provider.health() or {}
ok = bool(info.get("ok", False))
return Response(
{
"ok": ok,
"provider": info.get("provider"),
**info, # includes base_url/profile/reason
}
)
except Exception as e:
return _err(
code="routing_health_error",
message="Routing health check failed",
hint=str(e),
http_status=status.HTTP_502_BAD_GATEWAY,
)
@api_view(["POST"])
@throttle_classes([ScopedRateThrottle])
def routing_isochrone(request):
routing_isochrone.throttle_scope = "routing_isochrone" # DRF scoped throttle
data = request.data or {}
center = data.get("center")
minutes = data.get("minutes")
if not isinstance(center, (list, tuple)) or len(center) != 2:
return _err("invalid", "center must be [lat, lon]", http_status=status.HTTP_400_BAD_REQUEST)
try:
minutes = int(minutes)
except Exception:
return _err("invalid", "minutes must be an integer", http_status=status.HTTP_400_BAD_REQUEST)
provider = get_routing_provider()
try:
feat = provider.isochrone(tuple(center), minutes)
return Response(feat)
except Exception as e:
# Map to a consistent envelope for upstream/provider issues
return _err(
code="routing_error",
message="Failed to compute isochrone",
hint=str(e),
http_status=status.HTTP_502_BAD_GATEWAY,
)
# Backward-compatible aliases expected by urls.py
health = routing_health
isochrone = routing_isochrone