Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import io | |
| from typing import Any, Dict, Literal, Optional | |
| from fastapi import FastAPI, HTTPException | |
| from fastapi.responses import HTMLResponse, RedirectResponse, StreamingResponse | |
| from pydantic import BaseModel, Field | |
| from .renderer import render_html, render_pdf_bytes | |
| app = FastAPI( | |
| title="Doc Compiler Service", | |
| version="1.0.0", | |
| description=( | |
| "Servicio de compilaci贸n que recibe JSON de documentaci贸n, " | |
| "renderiza plantillas Jinja2 y devuelve HTML o PDF." | |
| ), | |
| ) | |
| class CompileRequest(BaseModel): | |
| doc: Dict[str, Any] = Field( | |
| ..., | |
| description=( | |
| "JSON de documentaci贸n generado por la IA " | |
| "(incluyendo metadata.script_type)." | |
| ), | |
| ) | |
| job_id: Optional[str] = Field( | |
| None, | |
| description=( | |
| "Identificador opcional para el archivo " | |
| "(por ejemplo, nombre del script o job)." | |
| ), | |
| ) | |
| output: Literal["html", "pdf"] = Field( | |
| "pdf", | |
| description="Tipo de salida deseada. En estos endpoints se usa como referencia.", | |
| ) | |
| def root(): | |
| """Endpoint ra铆z que redirige autom谩ticamente a la documentaci贸n.""" | |
| return RedirectResponse(url="/docs") | |
| def health_check(): | |
| """Endpoint simple de healthcheck para monitoreo.""" | |
| return {"status": "ok"} | |
| def compile_html(req: CompileRequest): | |
| """ | |
| Recibe JSON y devuelve el HTML renderizado (煤til para depuraci贸n o previsualizaci贸n). | |
| """ | |
| if not req.doc: | |
| raise HTTPException(status_code=400, detail="Campo 'doc' es obligatorio") | |
| try: | |
| html = render_html(req.doc) | |
| except Exception as exc: | |
| raise HTTPException( | |
| status_code=500, | |
| detail=f"Error al renderizar HTML: {exc}", | |
| ) | |
| return HTMLResponse(content=html) | |
| def compile_pdf(req: CompileRequest): | |
| """ | |
| Recibe JSON y devuelve el PDF compilado (WeasyPrint). | |
| """ | |
| if not req.doc: | |
| raise HTTPException(status_code=400, detail="Campo 'doc' es obligatorio") | |
| job_id = req.job_id or "document" | |
| try: | |
| pdf_bytes = render_pdf_bytes(req.doc) | |
| except Exception as exc: | |
| raise HTTPException( | |
| status_code=500, | |
| detail=f"Error al generar PDF: {exc}", | |
| ) | |
| filename = f"{job_id}.pdf" | |
| return StreamingResponse( | |
| io.BytesIO(pdf_bytes), | |
| media_type="application/pdf", | |
| headers={"Content-Disposition": f'attachment; filename="{filename}"'}, | |
| ) | |