""" Utility functions for URL detection and management. Automatically detects frontend URL from cloud platform environment variables, request headers, or falls back to environment variables. """ import os from typing import Optional from fastapi import Request def get_frontend_url(request: Optional[Request] = None) -> str: """ Automatically detect the frontend URL from various sources. Priority order: 1. FRONTEND_URL environment variable (manual override) 2. Cloud platform environment variables (AWS ECS, Azure Container Instances, etc.) 3. Request headers (Origin, Referer, X-Forwarded-Host) 4. Default fallback to localhost Args: request: Optional FastAPI Request object to extract headers Returns: Frontend URL string (without trailing slash) """ # 1. Check manual override from .env file # We use get_setting to allow runtime updates from utils.config_loader import get_setting frontend_url = get_setting("FRONTEND_URL") if frontend_url: return frontend_url.rstrip('/') # 2. Check cloud platform environment variables # AWS ECS/Fargate aws_container_url = os.getenv("AWS_CONTAINER_URL") or os.getenv("ECS_CONTAINER_METADATA_URI_V4") if aws_container_url: # Extract base URL from container metadata or use directly # For ECS, you might need to construct from service discovery # This is a placeholder - adjust based on your AWS setup pass # Azure Container Instances / App Service azure_website_hostname = os.getenv("WEBSITE_HOSTNAME") # Azure App Service azure_container_url = os.getenv("AZURE_CONTAINER_URL") if azure_website_hostname: # Azure App Service provides WEBSITE_HOSTNAME scheme = "https" if os.getenv("HTTPS") == "on" else "http" return f"{scheme}://{azure_website_hostname}".rstrip('/') if azure_container_url: return azure_container_url.rstrip('/') # Generic cloud platform variables # Check for common reverse proxy headers that indicate the public URL public_url = os.getenv("PUBLIC_URL") or os.getenv("BASE_URL") or os.getenv("APP_URL") if public_url: return public_url.rstrip('/') # 3. Try to extract from request headers if available if request: # Check Origin header (most reliable for CORS requests) origin = request.headers.get("origin") if origin: return origin.rstrip('/') # Check Referer header referer = request.headers.get("referer") if referer: # Extract base URL from referer from urllib.parse import urlparse parsed = urlparse(referer) if parsed.scheme and parsed.netloc: return f"{parsed.scheme}://{parsed.netloc}".rstrip('/') # Check X-Forwarded-Host (common in reverse proxy setups) forwarded_host = request.headers.get("x-forwarded-host") forwarded_proto = request.headers.get("x-forwarded-proto", "https") if forwarded_host: return f"{forwarded_proto}://{forwarded_host}".rstrip('/') # Check Host header and construct URL host = request.headers.get("host") if host: # Determine scheme from headers scheme = request.headers.get("x-forwarded-proto", "https" if request.url.scheme == "https" else "http") # For cloud deployments, typically use https if "localhost" not in host.lower() and "127.0.0.1" not in host: scheme = "https" return f"{scheme}://{host}".rstrip('/') # 4. Final fallback to localhost (development) or inferred production # If we are likely in production (e.g. on AWS), default to the Vercel app if os.getenv("AWS_EXECUTION_ENV") or os.getenv("NODE_ENV") == "production": return "https://medisync-ai1.vercel.app" return "http://localhost:3000" def get_backend_url(request: Optional[Request] = None) -> str: """ Automatically detect the backend URL (useful for internal redirects). Args: request: Optional FastAPI Request object Returns: Backend URL string (without trailing slash) """ # Check manual override backend_url = os.getenv("BACKEND_URL") if backend_url: return backend_url.rstrip('/') # Try to construct from request if request: base_url = str(request.base_url).rstrip('/') return base_url # Fallback return "http://localhost:8000"