File size: 4,157 Bytes
c103760
 
 
 
 
efdde13
c103760
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
efdde13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import os
import subprocess
import uuid
import shutil
from fastapi import FastAPI, HTTPException, BackgroundTasks
from fastapi.responses import FileResponse, HTMLResponse
from pydantic import BaseModel

app = FastAPI(title="LaTeX to PDF API")

# Diretório temporário para processamento
TEMP_DIR = "/tmp/latex_processing"
os.makedirs(TEMP_DIR, exist_ok=True)

class LatexRequest(BaseModel):
    content: str

def cleanup(directory: str):
    """Remove o diretório temporário após o uso."""
    if os.path.exists(directory):
        shutil.rmtree(directory)

@app.post("/compile")
async def compile_latex(request: LatexRequest, background_tasks: BackgroundTasks):
    job_id = str(uuid.uuid4())
    job_dir = os.path.join(TEMP_DIR, job_id)
    os.makedirs(job_dir, exist_ok=True)
    
    tex_file = os.path.join(job_dir, "document.tex")
    pdf_file = os.path.join(job_dir, "document.pdf")
    
    # Salva o conteúdo LaTeX no arquivo
    with open(tex_file, "w") as f:
        f.write(request.content)
    
    try:
        # Executa o pdflatex
        # -interaction=nonstopmode evita que o processo pare em erros
        process = subprocess.run(
            ["pdflatex", "-interaction=nonstopmode", "-output-directory", job_dir, tex_file],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True
        )
        
        if not os.path.exists(pdf_file):
            # Se o PDF não foi gerado, houve um erro no LaTeX
            error_msg = process.stdout if process.stdout else process.stderr
            # cleanup(job_dir) # Removido para evitar conflito com FileResponse imediato
            raise HTTPException(status_code=400, detail=f"Erro na compilação LaTeX: {error_msg}")
        
        # Retorna o arquivo e agenda a limpeza
        response = FileResponse(pdf_file, media_type="application/pdf", filename="document.pdf")
        background_tasks.add_task(cleanup, job_dir)
        return response

    except Exception as e:
        cleanup(job_dir)
        if isinstance(e, HTTPException):
            raise e
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/health")
async def health_check():
    checks = {}

    # Verifica se o pdflatex está disponível
    try:
        proc = subprocess.run(
            ["pdflatex", "--version"],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            timeout=5,
        )
        checks["pdflatex"] = proc.returncode == 0
        if not checks["pdflatex"]:
            checks["pdflatex_error"] = (proc.stderr or proc.stdout).strip()
    except Exception as e:
        checks["pdflatex"] = False
        checks["pdflatex_error"] = str(e)

    # Verifica se é possível criar e remover arquivos em TEMP_DIR
    try:
        test_dir = os.path.join(TEMP_DIR, f"healthcheck_{uuid.uuid4().hex}")
        os.makedirs(test_dir, exist_ok=True)
        test_file = os.path.join(test_dir, "test.txt")
        with open(test_file, "w") as f:
            f.write("ok")
        os.remove(test_file)
        os.rmdir(test_dir)
        checks["temp_dir_writable"] = True
    except Exception as e:
        checks["temp_dir_writable"] = False
        checks["temp_dir_error"] = str(e)

    healthy = checks.get("pdflatex") and checks.get("temp_dir_writable")
    result = {"status": "healthy" if healthy else "unhealthy", "checks": checks}
    if healthy:
        return result
    raise HTTPException(status_code=503, detail=result)


@app.get("/", response_class=HTMLResponse)
async def root():
    html = """
<html>
    <head>
        <title>LaTeX to PDF API - Usage</title>
    </head>
    <body>
        <h1>LaTeX to PDF API</h1>
        <p>Exemplo de chamada usando <strong>curl</strong>:</p>
        <pre>curl -X POST "https://thigas88-latex-api.hf.space/compile" \
         -H "Content-Type: application/json" \
         -d '{"content": "\\documentclass{article}\\begin{document}Hello World!\\end{document}"}' \
         --output document.pdf</pre>
        <p>Substitua a URL pela do seu servidor quando necessário.</p>
    </body>
</html>
"""
    return HTMLResponse(content=html)