Spaces:
Running
Running
| """ | |
| API HTTP do corretor de redacao ENEM. | |
| Endpoints: | |
| GET /health -> {"status": "ok"} | |
| POST /corrigir -> body {"texto": "..."}, retorna notas C1..C5 + total | |
| """ | |
| from __future__ import annotations | |
| from contextlib import asynccontextmanager | |
| from typing import Optional | |
| from fastapi import FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from pydantic import BaseModel, Field | |
| from corretor import corrigir, diagnosticar, load_models | |
| async def lifespan(app: FastAPI): | |
| # Pre-carrega os 5 modelos no startup para a primeira request nao pagar o custo. | |
| load_models() | |
| yield | |
| app = FastAPI( | |
| title="Dissero - Corretor ENEM", | |
| description="API de correcao automatica de redacao ENEM (modelos kamel-usp).", | |
| version="0.1.0", | |
| lifespan=lifespan, | |
| ) | |
| # CORS restrito: Vite local + deploys do Vercel (production + previews). | |
| ALLOWED_ORIGINS = [ | |
| "http://localhost:5173", | |
| "http://localhost:4173", | |
| "https://dissero.vercel.app", | |
| "https://dissertaai.vercel.app", | |
| "https://dissero-git-main-tonetos-projects.vercel.app", | |
| ] | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=ALLOWED_ORIGINS, | |
| allow_origin_regex=r"^https://dissero-[a-z0-9-]+-tonetos-projects\.vercel\.app$", | |
| allow_credentials=True, | |
| allow_methods=["POST", "GET", "OPTIONS"], | |
| allow_headers=["*"], | |
| ) | |
| class RedacaoRequest(BaseModel): | |
| texto: str = Field(..., min_length=1, description="Texto da redacao em portugues.") | |
| class C5Boost(BaseModel): | |
| de: int | |
| para: int | |
| elementos: int | |
| class CorrecaoResponse(BaseModel): | |
| C1: int | |
| C2: int | |
| C3: int | |
| C4: int | |
| C5: int | |
| total: int | |
| # Metadados (transparencia da decisao) | |
| modelo_usado: Optional[str] = None | |
| jbcs_total: Optional[int] = None | |
| local_total: Optional[int] = None | |
| c5_boost: Optional[C5Boost] = None | |
| def health() -> dict: | |
| return {"status": "ok"} | |
| def corrigir_endpoint(req: RedacaoRequest) -> dict: | |
| raw = corrigir(req.texto) | |
| # Mapeia underscores internos pra nomes publicos do schema | |
| out = { | |
| "C1": raw["C1"], "C2": raw["C2"], "C3": raw["C3"], | |
| "C4": raw["C4"], "C5": raw["C5"], "total": raw["total"], | |
| "modelo_usado": raw.get("_modelo_usado"), | |
| "jbcs_total": raw.get("_jbcs_total"), | |
| "local_total": raw.get("_local_total"), | |
| } | |
| boost = raw.get("_c5_heuristica_boost") | |
| if boost: | |
| out["c5_boost"] = { | |
| "de": boost["de"], "para": boost["para"], | |
| "elementos": boost["elementos"], | |
| } | |
| return out | |
| def debug_endpoint(req: RedacaoRequest) -> dict: | |
| """Diagnostico completo: logits, softmax, e varias estrategias de decoding.""" | |
| return diagnosticar(req.texto) | |