Spaces:
Sleeping
Sleeping
| """Minimal FastAPI app for Harbor RL environment. | |
| This is a lean entry point that only includes task evaluation | |
| endpoints — no database, auth, CSRF, or background workers. | |
| Run with: uvicorn lexenvs.harbor_app:app --host 0.0.0.0 --port 8000 | |
| """ | |
| from __future__ import annotations | |
| import logging | |
| import os | |
| from collections.abc import AsyncGenerator | |
| import svcs | |
| from fastapi import FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from lexenvs.config.settings import get_settings | |
| from lexenvs.routers import tasks | |
| from lexenvs.services.claim_extractor import ClaimExtractor | |
| from lexenvs.services.objective_evaluator_service import ObjectiveEvaluatorService | |
| from lexenvs.services.rubric_evaluator_service import ( | |
| RubricEvaluatorService, | |
| create_rubric_evaluator_service, | |
| ) | |
| from lexenvs.services.task_loader_service import ( | |
| TaskLoaderService, | |
| create_task_loader_service, | |
| ) | |
| from lexenvs.utils import load_card_database | |
| logger = logging.getLogger(__name__) | |
| def create_harbor_app() -> FastAPI: | |
| """Factory to create the Harbor FastAPI application.""" | |
| async def lifespan(app: FastAPI, registry: svcs.Registry) -> AsyncGenerator[None, None]: | |
| """Register task-related services.""" | |
| registry.register_factory(TaskLoaderService, create_task_loader_service) | |
| registry.register_factory(RubricEvaluatorService, create_rubric_evaluator_service) | |
| # Register objective evaluator if card database exists | |
| card_db = load_card_database() | |
| if card_db is not None: | |
| settings = get_settings() | |
| claim_extractor = None | |
| if settings.openrouter_api_key: | |
| claim_extractor = ClaimExtractor( | |
| api_key=settings.openrouter_api_key, | |
| model=settings.claim_extractor_model, | |
| base_url=settings.claim_extractor_base_url, | |
| ) | |
| logger.info( | |
| "Factual fidelity: LLM claim extraction enabled via %s", | |
| settings.claim_extractor_base_url, | |
| ) | |
| else: | |
| logger.info("Factual fidelity: no OPENROUTER_API_KEY, LLM extraction disabled") | |
| registry.register_value( | |
| ObjectiveEvaluatorService, | |
| ObjectiveEvaluatorService(card_db, claim_extractor=claim_extractor), | |
| ) | |
| yield | |
| harbor_app = FastAPI( | |
| title="LexEnvs Harbor Environment", | |
| description="Harbor-compatible RL environment for credit card optimization tasks", | |
| version="1.0.0", | |
| docs_url="/docs", | |
| lifespan=lifespan, | |
| ) | |
| allowed_origins = os.environ.get("LEX_ENVS_CORS_ORIGINS", "*").split(",") | |
| harbor_app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=allowed_origins, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| harbor_app.include_router(tasks.router, prefix="/api") | |
| async def root() -> dict[str, str]: | |
| """Root endpoint — confirms the server is running.""" | |
| return { | |
| "service": "LexEnvs Harbor Environment", | |
| "docs": "/docs", | |
| "health": "/health/live", | |
| "tasks": "/api/tasks", | |
| } | |
| async def liveness() -> dict[str, str]: | |
| """Lightweight liveness probe.""" | |
| return {"status": "ok"} | |
| return harbor_app | |
| app = create_harbor_app() | |