initial project setup with README and ignore
This commit is contained in:
5
app/controllers/__init__.py
Normal file
5
app/controllers/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
"""Controllers package."""
|
||||
|
||||
from .route_controller import RouteController
|
||||
|
||||
__all__ = ["RouteController"]
|
||||
87
app/controllers/route_controller.py
Normal file
87
app/controllers/route_controller.py
Normal file
@@ -0,0 +1,87 @@
|
||||
"""Controller for provider payload optimization and forwarding."""
|
||||
|
||||
import logging
|
||||
import hashlib
|
||||
import json
|
||||
from typing import Dict, Any
|
||||
import httpx
|
||||
from fastapi import HTTPException
|
||||
|
||||
from app.core.exceptions import ValidationError, APIException
|
||||
from app.services.routing.route_optimizer import RouteOptimizer
|
||||
from app.services import cache
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RouteController:
|
||||
"""Controller for optimizing provider payloads and forwarding upstream."""
|
||||
|
||||
def __init__(self):
|
||||
self.route_optimizer = RouteOptimizer()
|
||||
|
||||
def _hash_key(self, prefix: str, payload: Dict[str, Any]) -> str:
|
||||
"""Create a stable cache key from a dict payload."""
|
||||
# ensure deterministic json by sorting keys
|
||||
serialized = json.dumps(payload, sort_keys=True, separators=(",", ":"))
|
||||
digest = hashlib.sha256(serialized.encode("utf-8")).hexdigest()
|
||||
return f"routes:{prefix}:{digest}"
|
||||
|
||||
async def optimize_and_forward_provider_payload(self, orders: list[dict], forward_url: str) -> dict:
|
||||
"""Optimize provider payload and return it (forwarding paused).
|
||||
|
||||
- Input: list of provider orders (dicts)
|
||||
- Output: {code, details, message, status} where details is the optimized array
|
||||
"""
|
||||
try:
|
||||
if not isinstance(orders, list) or not orders:
|
||||
raise ValidationError("Orders array is required", field="body")
|
||||
|
||||
optimized = await self.route_optimizer.optimize_provider_payload(orders)
|
||||
|
||||
# Debug sample of optimized payload (first 3 items, select keys)
|
||||
try:
|
||||
sample = [
|
||||
{
|
||||
k: item.get(k)
|
||||
for k in ("orderheaderid", "orderid", "deliverycustomerid", "step", "previouskms", "cumulativekms", "eta")
|
||||
}
|
||||
for item in optimized[:3]
|
||||
]
|
||||
logger.debug(f"Optimized payload sample: {sample}")
|
||||
trace = [
|
||||
{
|
||||
"orderid": item.get("orderid"),
|
||||
"step": item.get("step"),
|
||||
"prev": item.get("previouskms"),
|
||||
"cum": item.get("cumulativekms"),
|
||||
}
|
||||
for item in optimized
|
||||
]
|
||||
logger.debug(f"Optimized order trace: {trace}")
|
||||
except Exception:
|
||||
logger.debug("Optimized payload sample logging failed")
|
||||
|
||||
# Forwarding paused: return optimized payload directly
|
||||
return {
|
||||
"code": 200,
|
||||
"details": optimized,
|
||||
"message": "Success",
|
||||
"status": True,
|
||||
}
|
||||
except ValidationError:
|
||||
raise
|
||||
except httpx.HTTPStatusError as e:
|
||||
status_code = e.response.status_code
|
||||
body_text = e.response.text
|
||||
logger.error(f"Forwarding failed: {status_code} - {body_text}")
|
||||
# Surface upstream details to the client for faster debugging
|
||||
raise APIException(
|
||||
status_code=502,
|
||||
message=f"Upstream service error (status {status_code}): {body_text}",
|
||||
code="UPSTREAM_ERROR"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error optimizing/forwarding provider payload: {e}", exc_info=True)
|
||||
raise APIException(status_code=500, message="Internal server error", code="INTERNAL_ERROR")
|
||||
# Batch routes removed - use single-route optimization for each pickup location
|
||||
Reference in New Issue
Block a user