Add POI feature and imporve the overall backend implementation

This commit is contained in:
Urtzi Alfaro
2025-11-12 15:34:10 +01:00
parent e8096cd979
commit 5783c7ed05
173 changed files with 16862 additions and 9078 deletions

View File

@@ -22,7 +22,7 @@ from app.middleware.rate_limit import RateLimitMiddleware
from app.middleware.subscription import SubscriptionMiddleware
from app.middleware.demo_middleware import DemoMiddleware
from app.middleware.read_only_mode import ReadOnlyModeMiddleware
from app.routes import auth, tenant, notification, nominatim, subscription, demo, pos
from app.routes import auth, tenant, notification, nominatim, subscription, demo, pos, geocoding, poi_context
from shared.monitoring.logging import setup_logging
from shared.monitoring.metrics import MetricsCollector
@@ -71,6 +71,8 @@ app.include_router(tenant.router, prefix="/api/v1/tenants", tags=["tenants"])
app.include_router(subscription.router, prefix="/api/v1", tags=["subscriptions"])
app.include_router(notification.router, prefix="/api/v1/notifications", tags=["notifications"])
app.include_router(nominatim.router, prefix="/api/v1/nominatim", tags=["location"])
app.include_router(geocoding.router, prefix="/api/v1/geocoding", tags=["geocoding"])
app.include_router(poi_context.router, prefix="/api/v1/poi-context", tags=["poi-context"])
app.include_router(pos.router, prefix="/api/v1/pos", tags=["pos"])
app.include_router(demo.router, prefix="/api/v1", tags=["demo"])

View File

@@ -0,0 +1,74 @@
# gateway/app/routes/geocoding.py
from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import JSONResponse
import httpx
import structlog
from app.core.config import settings
logger = structlog.get_logger()
router = APIRouter()
@router.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"])
async def proxy_geocoding(request: Request, path: str):
"""
Proxies all geocoding requests to the External Service geocoding endpoints.
Forwards requests from /api/v1/geocoding/* to external-service:8000/api/v1/geocoding/*
"""
try:
# Construct the external service URL
external_url = f"{settings.EXTERNAL_SERVICE_URL}/api/v1/geocoding/{path}"
# Get request body for POST/PUT/PATCH
body = None
if request.method in ["POST", "PUT", "PATCH"]:
body = await request.body()
# Forward headers (excluding host)
headers = {
key: value
for key, value in request.headers.items()
if key.lower() not in ["host", "content-length"]
}
# Make the proxied request
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.request(
method=request.method,
url=external_url,
params=request.query_params,
headers=headers,
content=body
)
# Return the response from external service
return JSONResponse(
content=response.json() if response.text else None,
status_code=response.status_code,
headers=dict(response.headers)
)
except httpx.RequestError as exc:
logger.error("External service geocoding request failed", error=str(exc), path=path)
raise HTTPException(
status_code=503,
detail=f"Geocoding service unavailable: {exc}"
)
except httpx.HTTPStatusError as exc:
logger.error(
f"External service geocoding responded with error {exc.response.status_code}",
detail=exc.response.text,
path=path
)
raise HTTPException(
status_code=exc.response.status_code,
detail=f"Geocoding service error: {exc.response.text}"
)
except Exception as exc:
logger.error("Unexpected error in geocoding proxy", error=str(exc), path=path)
raise HTTPException(
status_code=500,
detail="Internal server error in geocoding proxy"
)

View File

@@ -0,0 +1,91 @@
"""
POI Context Proxy Router
Forwards all POI context requests to the External Service
"""
from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import JSONResponse
import httpx
import structlog
from app.core.config import settings
logger = structlog.get_logger()
router = APIRouter()
@router.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"])
async def proxy_poi_context(request: Request, path: str):
"""
Proxies all POI context requests to the External Service.
Forwards requests from /api/v1/poi-context/* to external-service:8000/api/v1/poi-context/*
Args:
request: The incoming request
path: The path after /api/v1/poi-context/
Returns:
JSONResponse with the response from the external service
Raises:
HTTPException: If the external service is unavailable or returns an error
"""
try:
# Construct the external service URL
external_url = f"{settings.EXTERNAL_SERVICE_URL}/poi-context/{path}"
logger.debug("Proxying POI context request",
method=request.method,
path=path,
external_url=external_url)
# Get request body for POST/PUT/PATCH requests
body = None
if request.method in ["POST", "PUT", "PATCH"]:
body = await request.body()
# Copy headers (exclude host and content-length as they'll be set by httpx)
headers = {
key: value
for key, value in request.headers.items()
if key.lower() not in ["host", "content-length"]
}
# Make the request to the external service
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.request(
method=request.method,
url=external_url,
params=request.query_params,
headers=headers,
content=body
)
logger.debug("POI context proxy response",
status_code=response.status_code,
path=path)
# Return the response from the external service
return JSONResponse(
content=response.json() if response.text else None,
status_code=response.status_code,
headers=dict(response.headers)
)
except httpx.RequestError as exc:
logger.error("External service POI request failed",
error=str(exc),
path=path,
external_url=external_url)
raise HTTPException(
status_code=503,
detail=f"POI service unavailable: {exc}"
)
except Exception as exc:
logger.error("Unexpected error in POI proxy",
error=str(exc),
path=path)
raise HTTPException(
status_code=500,
detail="Internal server error in POI proxy"
)