Pant0x's picture
Add HF Space Gradio SDK backend (free tier)
34a66f3
Raw
History Blame Contribute Delete
4.47 kB
from typing import Any, Dict, List, Optional
from fastapi import APIRouter, Header, HTTPException
import requests
from app.core.config import (
SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY,
SUPABASE_TIMEOUT_SECONDS, SUPABASE_RAW_BUCKET, SUPABASE_PROCESSED_BUCKET,
SUPABASE_ENFORCE_AUTH, MODEL_INFERENCE_PROVIDER, MODEL_SERVICE_ENABLE_LOCAL_ENDPOINT,
MODEL_PATHS, MODELS_DIR, PARKING_HOURLY_RATE_EGP, PARKING_DAILY_RATE_EGP,
PARKING_EXTRA_AFTER_FIRST_HOUR_EGP, PARKING_BILLING_MODE, PARKING_LOCATION_HOURLY_RATES,
PARKING_LOCATION_PRICING, PARKING_LOCATION_CAPACITIES, GARAGE_TOTAL_CAPACITY,
APP_SERVICE_FEE_EGP, CORE_TABLES,
supabase_configured, model_service_configured, resolve_model_service_infer_url,
should_load_local_models, LOGGER,
)
from app.services.supabase_client import supabase_list_buckets, supabase_table_exists
from app.security.auth import require_authenticated_user, require_developer_user, _supabase_headers
router = APIRouter(tags=["health"])
@router.get("/health")
def health():
local_models_required = should_load_local_models()
status_value = "ok"
model_inference_payload: Dict[str, Any] = {
"provider": MODEL_INFERENCE_PROVIDER,
"local_models_required": local_models_required,
"local_endpoint_enabled": MODEL_SERVICE_ENABLE_LOCAL_ENDPOINT,
"remote_service_configured": model_service_configured(),
"remote_infer_url": resolve_model_service_infer_url(),
}
return {
"status": status_value,
"model_inference": model_inference_payload,
"supabase_configured": supabase_configured(),
"supabase_auth_enforced": SUPABASE_ENFORCE_AUTH,
"pricing": {
"default_billing_mode": PARKING_BILLING_MODE,
"default_hourly_rate_egp": round(max(0.0, PARKING_HOURLY_RATE_EGP), 2),
"default_daily_rate_egp": round(max(0.0, PARKING_DAILY_RATE_EGP), 2),
"default_extra_after_first_hour_egp": round(max(0.0, PARKING_EXTRA_AFTER_FIRST_HOUR_EGP), 2),
"location_hourly_rates": PARKING_LOCATION_HOURLY_RATES,
"location_pricing": PARKING_LOCATION_PRICING,
"location_capacities": PARKING_LOCATION_CAPACITIES,
"garage_total_capacity": GARAGE_TOTAL_CAPACITY,
"app_service_fee_egp": round(max(0.0, APP_SERVICE_FEE_EGP), 2),
},
}
@router.get("/supabase/health")
def supabase_health():
if not supabase_configured():
return {"status": "disabled", "reason": "Set SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY"}
try:
response = requests.get(
f"{SUPABASE_URL}/auth/v1/settings",
headers={"apikey": SUPABASE_ANON_KEY},
timeout=SUPABASE_TIMEOUT_SECONDS,
)
if response.status_code != 200:
return {"status": "error", "http_status": response.status_code, "detail": response.text[:400]}
existing_buckets = set(supabase_list_buckets())
required_buckets = {SUPABASE_RAW_BUCKET, SUPABASE_PROCESSED_BUCKET}
missing_buckets = sorted(required_buckets - existing_buckets)
table_checks: Dict[str, Any] = {}
all_tables_ready = True
for table_name in sorted(CORE_TABLES):
exists, detail = supabase_table_exists(table_name)
table_checks[table_name] = {"exists": exists, "detail": detail}
if not exists:
all_tables_ready = False
ready_for_persistence = all_tables_ready and not missing_buckets
return {
"status": "ok" if ready_for_persistence else "partial",
"url": SUPABASE_URL,
"readiness": {
"ready_for_persistence": ready_for_persistence,
"missing_buckets": missing_buckets,
"tables": table_checks,
},
}
except requests.RequestException as exc:
return {"status": "error", "detail": str(exc)}
@router.get("/models")
def models():
return {
"inference_provider": MODEL_INFERENCE_PROVIDER,
"local_models_required": should_load_local_models(),
"remote_service_configured": model_service_configured(),
"remote_infer_url": resolve_model_service_infer_url(),
}
@router.get("/developer/models")
def developer_models(authorization: Optional[str] = Header(default=None)):
request_user, requester_role = require_developer_user(authorization)
return models()