habulaj commited on
Commit
2ce54f6
·
verified ·
1 Parent(s): 51eb27e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -38
app.py CHANGED
@@ -2,8 +2,10 @@ from fastapi import FastAPI, HTTPException
2
  from fastapi.responses import Response
3
  from fastapi.middleware.cors import CORSMiddleware
4
  from pydantic import BaseModel
 
5
  from typing import Optional
6
- import httpx
 
7
 
8
  app = FastAPI()
9
 
@@ -16,9 +18,6 @@ app.add_middleware(
16
  allow_headers=["*"],
17
  )
18
 
19
- # Endpoint da API externa
20
- EXTERNAL_API_URL = "https://habulaj-pdf-api.hf.space"
21
-
22
  # Modelo para criar posts (gerar imagem a partir de HTML)
23
  class PostRequest(BaseModel):
24
  html: str
@@ -34,7 +33,6 @@ async def create_post(request: PostRequest):
34
  """
35
  Cria uma imagem a partir de HTML para posts.
36
  Recebe HTML e retorna uma imagem PNG.
37
- Faz proxy para a API externa: https://habulaj-pdf-api.hf.space
38
 
39
  Exemplo de uso:
40
  {
@@ -43,49 +41,71 @@ async def create_post(request: PostRequest):
43
  "height": 1350
44
  }
45
  """
 
46
  try:
47
- # Prepara o payload para a API externa
48
- payload = {
49
- "html": request.html,
50
- "width": request.width,
51
- "height": request.height
52
- }
53
 
54
- # Faz requisição para a API externa
55
- async with httpx.AsyncClient(timeout=60.0) as client:
56
- response = await client.post(
57
- f"{EXTERNAL_API_URL}/create-post",
58
- json=payload,
59
- headers={"Content-Type": "application/json"}
60
- )
61
-
62
- if response.status_code != 200:
63
- error_message = f"Erro na API externa: {response.status_code}"
64
- try:
65
- error_data = response.json()
66
- if "detail" in error_data:
67
- error_message = error_data["detail"]
68
- elif "message" in error_data:
69
- error_message = error_data["message"]
70
- except:
71
- error_message = f"Erro na API externa: {response.status_code} {response.text}"
 
 
 
 
 
72
 
73
- raise HTTPException(status_code=response.status_code, detail=error_message)
 
 
 
 
 
 
 
 
 
74
 
75
- # Retorna a imagem recebida da API externa
 
 
 
 
 
76
  return Response(
77
- content=response.content,
78
  media_type="image/png",
79
  headers={
80
  "Content-Disposition": "attachment; filename=post.png"
81
  }
82
  )
 
 
 
 
 
 
83
 
84
- except httpx.TimeoutException:
85
- raise HTTPException(status_code=504, detail="Timeout ao comunicar com a API externa")
86
- except httpx.RequestError as e:
87
- raise HTTPException(status_code=502, detail=f"Erro ao comunicar com a API externa: {str(e)}")
88
- except HTTPException:
89
- raise
90
  except Exception as e:
 
 
 
 
 
 
91
  raise HTTPException(status_code=500, detail=f"Erro ao gerar imagem do post: {str(e)}")
 
2
  from fastapi.responses import Response
3
  from fastapi.middleware.cors import CORSMiddleware
4
  from pydantic import BaseModel
5
+ from playwright.sync_api import sync_playwright
6
  from typing import Optional
7
+ import tempfile
8
+ import os
9
 
10
  app = FastAPI()
11
 
 
18
  allow_headers=["*"],
19
  )
20
 
 
 
 
21
  # Modelo para criar posts (gerar imagem a partir de HTML)
22
  class PostRequest(BaseModel):
23
  html: str
 
33
  """
34
  Cria uma imagem a partir de HTML para posts.
35
  Recebe HTML e retorna uma imagem PNG.
 
36
 
37
  Exemplo de uso:
38
  {
 
41
  "height": 1350
42
  }
43
  """
44
+ html_file = None
45
  try:
46
+ # Garantir que o HTML está completo
47
+ html_content = request.html
 
 
 
 
48
 
49
+ # Se o HTML não tiver estrutura completa, adicionar
50
+ if "<!DOCTYPE" not in html_content and "<html" not in html_content:
51
+ html_content = f"""<!DOCTYPE html>
52
+ <html lang="pt-BR">
53
+ <head>
54
+ <meta charset="UTF-8">
55
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
56
+ </head>
57
+ <body>
58
+ {html_content}
59
+ </body>
60
+ </html>"""
61
+
62
+ # Criar arquivo temporário para o HTML
63
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.html', delete=False, encoding='utf-8') as f:
64
+ f.write(html_content)
65
+ html_file = f.name
66
+
67
+ try:
68
+ # Usar Playwright para renderizar HTML e gerar screenshot
69
+ with sync_playwright() as p:
70
+ browser = p.chromium.launch(headless=True)
71
+ page = browser.new_page(viewport={'width': request.width, 'height': request.height})
72
 
73
+ # Carrega o HTML do arquivo temporário
74
+ page.goto(f'file://{html_file}')
75
+
76
+ # Espera o conteúdo carregar (especialmente imagens base64)
77
+ page.wait_for_timeout(2000) # Aguarda 2 segundos para garantir que imagens e fontes carreguem
78
+
79
+ # Tira screenshot
80
+ screenshot_bytes = page.screenshot(full_page=True, type='png')
81
+
82
+ browser.close()
83
 
84
+ # Remove arquivo temporário
85
+ if os.path.exists(html_file):
86
+ os.unlink(html_file)
87
+ html_file = None
88
+
89
+ # Retorna a imagem
90
  return Response(
91
+ content=screenshot_bytes,
92
  media_type="image/png",
93
  headers={
94
  "Content-Disposition": "attachment; filename=post.png"
95
  }
96
  )
97
+
98
+ except Exception as e:
99
+ # Remove arquivo temporário em caso de erro
100
+ if html_file and os.path.exists(html_file):
101
+ os.unlink(html_file)
102
+ raise e
103
 
 
 
 
 
 
 
104
  except Exception as e:
105
+ # Garantir limpeza do arquivo temporário
106
+ if html_file and os.path.exists(html_file):
107
+ try:
108
+ os.unlink(html_file)
109
+ except:
110
+ pass
111
  raise HTTPException(status_code=500, detail=f"Erro ao gerar imagem do post: {str(e)}")