lexenvs-harbor / src /lexenvs /harbor_app.py
endishai's picture
Upload folder using huggingface_hub
c430a3f verified
"""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."""
@svcs.fastapi.lifespan
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")
@harbor_app.get("/")
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",
}
@harbor_app.get("/health/live")
async def liveness() -> dict[str, str]:
"""Lightweight liveness probe."""
return {"status": "ok"}
return harbor_app
app = create_harbor_app()