wpbcpaz commited on
Commit
f3fda97
·
verified ·
1 Parent(s): c3619dc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +357 -36
app.py CHANGED
@@ -1,54 +1,375 @@
1
  """
2
- Meu Primeiro Space - Teste
3
- Aula 9: Hugging Face Spaces e Gradio
 
 
4
  """
5
 
6
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
- def gerar_mensagem(nome, tema):
 
 
 
 
 
 
 
 
 
 
9
  """
10
- Função simples para testar o Gradio
11
 
12
- Parâmetros:
13
- nome: nome do usuário
14
- tema: tema do post
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
- Retorna:
17
- mensagem: string formatada
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  """
19
- mensagem = f"""
20
- 🎉 Olá, {nome}!
21
 
22
- Em breve vamos gerar um post incrível sobre: {tema}
 
 
 
23
 
24
- Por enquanto, estamos testando se o Space funciona corretamente.
 
 
 
 
 
 
 
25
 
26
- Se você está vendo esta mensagem, está tudo funcionando!
 
 
 
 
 
 
 
 
 
 
 
27
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
- return mensagem
30
-
31
- # Criar interface Gradio
32
- interface = gr.Interface(
33
- fn=gerar_mensagem,
34
- inputs=[
35
- gr.Textbox(
36
- label="Seu Nome",
37
- placeholder="Digite seu nome aqui"
38
- ),
39
- gr.Textbox(
40
- label="Tema do Post",
41
- placeholder="Ex: motivação para treinar"
 
 
 
 
 
 
42
  )
43
- ],
44
- outputs=gr.Textbox(
45
- label="Mensagem Gerada",
46
- lines=10
47
- ),
48
- title="🚀 Gerador de Posts - Versão Teste",
49
- description="Esta é uma versão de teste. Digite seu nome e um tema para ver a mensagem."
50
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  # Lançar aplicação
53
  if __name__ == "__main__":
54
- interface.launch()
 
1
  """
2
+ GERADOR DE POSTS PARA REDES SOCIAIS
3
+ Aula 9: Versão Web com Hugging Face Spaces + Gradio
4
+
5
+ Transforma o código da Aula 8 (Google Colab) em aplicação web
6
  """
7
 
8
  import gradio as gr
9
+ import requests
10
+ import os
11
+ from datetime import datetime
12
+ from PIL import Image
13
+ from io import BytesIO
14
+
15
+ # API Key vem dos Secrets (configurado em Settings)
16
+ HUGGINGFACE_API_KEY = os.environ.get("HF_TOKEN")
17
+
18
+ # Verificar se API key existe
19
+ if not HUGGINGFACE_API_KEY:
20
+ raise ValueError("⚠️ API Key não configurada! Configure HF_TOKEN nos Secrets")
21
+
22
+ # URLs e modelos (SEM símbolos < >)
23
+ BASE_URL = "https://router.huggingface.co/v1"
24
+ MODELO_TEXTO = "meta-llama/Llama-3.1-8B-Instruct"
25
+ MODELO_IMAGEM = "black-forest-labs/FLUX.1-schnell"
26
+
27
+ # Headers para requisições
28
+ headers = {
29
+ "Authorization": f"Bearer {HUGGINGFACE_API_KEY}",
30
+ "Content-Type": "application/json"
31
+ }
32
+
33
+ # Opções da interface
34
+ NICHOS_DISPONIVEIS = [
35
+ "Fitness e Vida Saudável",
36
+ "Alimentação e Nutrição",
37
+ "Motivação e Desenvolvimento Pessoal",
38
+ "Negócios e Empreendedorismo",
39
+ "Viagens e Turismo",
40
+ "Tecnologia e Inovação"
41
+ ]
42
+
43
+ ESTILOS_DISPONIVEIS = [
44
+ "Inspirador e motivacional",
45
+ "Educativo e informativo",
46
+ "Divertido e descontraído",
47
+ "Profissional e técnico"
48
+ ]
49
+
50
 
51
+ # ============================================
52
+ # FUNÇÕES DE GERAÇÃO (adaptadas da Aula 8)
53
+ # ============================================
54
+
55
+ def gerar_texto(tema, nicho, estilo):
56
+ """
57
+ Gera texto usando API do Hugging Face
58
+
59
+ Diferença da Aula 8:
60
+ - Aula 8: função imprimia no console
61
+ - Aula 9: função retorna string (para o Gradio)
62
  """
 
63
 
64
+ url = f"{BASE_URL}/chat/completions"
65
+
66
+ payload = {
67
+ "model": MODELO_TEXTO,
68
+ "messages": [
69
+ {
70
+ "role": "system",
71
+ "content": f"Você é um criador de conteúdo especializado em {nicho}."
72
+ },
73
+ {
74
+ "role": "user",
75
+ "content": f"""Crie uma legenda criativa para Instagram sobre: {tema}
76
+
77
+ Requisitos:
78
+ - Estilo: {estilo}
79
+ - Tamanho: 100-150 palavras
80
+ - Estrutura: gancho inicial + desenvolvimento + call-to-action
81
+ - Incluir 4-5 hashtags relevantes no final
82
+ - Tom: próximo, empático e motivador
83
+ - Usar no máximo 3 emojis
84
+
85
+ Escreva apenas a legenda, sem introduções ou explicações."""
86
+ }
87
+ ],
88
+ "max_tokens": 350,
89
+ "temperature": 0.7,
90
+ "stream": False
91
+ }
92
+
93
+ try:
94
+ response = requests.post(url, headers=headers, json=payload, timeout=60)
95
 
96
+ if response.status_code == 200:
97
+ resultado = response.json()
98
+ texto = resultado['choices'][0]['message']['content'].strip()
99
+ return texto
100
+ else:
101
+ return f"❌ Erro ao gerar texto: {response.status_code}\\n{response.text}"
102
+
103
+ except Exception as e:
104
+ return f"❌ Erro: {str(e)}"
105
+
106
+
107
+ def gerar_imagem(descricao):
108
+ """
109
+ Gera imagem usando API do Hugging Face
110
+
111
+ Diferença da Aula 8:
112
+ - Aula 8: salvava arquivo .png
113
+ - Aula 9: retorna objeto PIL Image (Gradio mostra automaticamente)
114
  """
 
 
115
 
116
+ try:
117
+ from huggingface_hub import InferenceClient
118
+
119
+ client = InferenceClient(api_key=HUGGINGFACE_API_KEY)
120
 
121
+ # Adicionar prompt engineering para melhor qualidade
122
+ prompt = f"{descricao}, professional photography, vibrant colors, high quality, 4k"
123
+
124
+ # Gerar imagem
125
+ image = client.text_to_image(
126
+ prompt=prompt,
127
+ model=MODELO_IMAGEM
128
+ )
129
 
130
+ return image # Retorna objeto PIL Image
131
+
132
+ except Exception as e:
133
+ print(f"Erro ao gerar imagem: {str(e)}")
134
+ return None
135
+
136
+
137
+ # ============================================
138
+ # FUNÇÃO PRINCIPAL PARA O GRADIO
139
+ # ============================================
140
+
141
+ def gerar_post_interface(tema, nicho, estilo, descricao_imagem, gerar_img):
142
  """
143
+ Função principal que o Gradio chama quando usuário clica no botão.
144
+
145
+ IMPORTANTE: Esta função é diferente da Aula 8!
146
+
147
+ Aula 8 (Colab):
148
+ - Função imprimia resultados
149
+ - Salvava arquivos
150
+ - Usávamos print()
151
+
152
+ Aula 9 (Spaces):
153
+ - Função RETORNA valores
154
+ - Gradio mostra automaticamente
155
+ - Usamos return
156
 
157
+ Parâmetros (vindos dos campos da interface):
158
+ tema: str - tema digitado pelo usuário
159
+ nicho: str - dropdown selecionado
160
+ estilo: str - radio button selecionado
161
+ descricao_imagem: str - descrição para imagem
162
+ gerar_img: bool - checkbox (True/False)
163
+
164
+ Retorna (para o Gradio mostrar):
165
+ texto: str - legenda gerada
166
+ imagem: PIL.Image ou None - imagem gerada
167
+ status: str - mensagem de status
168
+ """
169
+
170
+ # Validação de entrada
171
+ if not tema or len(tema.strip()) < 3:
172
+ return (
173
+ "⚠️ Por favor, digite um tema válido (mínimo 3 caracteres).",
174
+ None,
175
+ "❌ Validação falhou"
176
  )
177
+
178
+ # Etapa 1: Gerar texto
179
+ status_atual = " Gerando texto..."
180
+ texto = gerar_texto(tema, nicho, estilo)
181
+
182
+ # Verificar se houve erro
183
+ if texto.startswith("❌"):
184
+ return texto, None, "❌ Erro ao gerar texto"
185
+
186
+ # Etapa 2: Gerar imagem (se solicitado)
187
+ imagem = None
188
+ if gerar_img:
189
+ # Validar descrição da imagem
190
+ if not descricao_imagem or len(descricao_imagem.strip()) < 3:
191
+ descricao_imagem = f"{tema} related image, professional photography"
192
+
193
+ status_atual = "⏳ Gerando imagem..."
194
+ imagem = gerar_imagem(descricao_imagem)
195
+
196
+ if imagem is None:
197
+ status_final = "⚠️ Texto gerado, mas houve erro na imagem"
198
+ else:
199
+ status_final = "✅ Post completo gerado com sucesso!"
200
+ else:
201
+ status_final = "✅ Texto gerado com sucesso!"
202
+
203
+ # Retornar 3 valores (um para cada output do Gradio)
204
+ return texto, imagem, status_final
205
+
206
+
207
+ # ============================================
208
+ # INTERFACE GRADIO
209
+ # ============================================
210
+
211
+ # Usar gr.Blocks para layout customizado
212
+ with gr.Blocks(theme=gr.themes.Soft(), title="Gerador de Posts") as demo:
213
+
214
+ # Cabeçalho
215
+ gr.Markdown("""
216
+ # 🚀 Gerador de Posts para Redes Sociais
217
+ ### Crie legendas profissionais e imagens com IA em segundos!
218
+
219
+ **Como usar:**
220
+ 1. Escolha seu nicho e estilo
221
+ 2. Digite o tema do post
222
+ 3. (Opcional) Adicione descrição para imagem
223
+ 4. Clique em **Gerar Post**
224
+ """)
225
+
226
+ # Dividir em 2 colunas
227
+ with gr.Row():
228
+ # COLUNA ESQUERDA: Inputs
229
+ with gr.Column(scale=1):
230
+ gr.Markdown("### ⚙️ Configurações do Post")
231
+
232
+ # Dropdown para nicho
233
+ nicho_input = gr.Dropdown(
234
+ choices=NICHOS_DISPONIVEIS,
235
+ value=NICHOS_DISPONIVEIS[0],
236
+ label="Nicho",
237
+ info="Escolha a área de atuação do seu conteúdo"
238
+ )
239
+
240
+ # Radio buttons para estilo
241
+ estilo_input = gr.Radio(
242
+ choices=ESTILOS_DISPONIVEIS,
243
+ value=ESTILOS_DISPONIVEIS[0],
244
+ label="Estilo de Escrita",
245
+ info="Tom e abordagem da sua legenda"
246
+ )
247
+
248
+ # Campo de texto para tema
249
+ tema_input = gr.Textbox(
250
+ label="Tema do Post",
251
+ placeholder="Ex: motivação para treinar no inverno",
252
+ lines=2,
253
+ info="Seja específico para melhores resultados"
254
+ )
255
+
256
+ gr.Markdown("### 🎨 Imagem (Opcional)")
257
+
258
+ # Checkbox para gerar imagem
259
+ gerar_img_checkbox = gr.Checkbox(
260
+ label="Gerar imagem junto com o texto",
261
+ value=True,
262
+ info="Desmarque para gerar apenas texto (mais rápido)"
263
+ )
264
+
265
+ # Campo para descrição da imagem
266
+ descricao_img_input = gr.Textbox(
267
+ label="Descrição da Imagem (em inglês)",
268
+ placeholder="Ex: person exercising at gym, motivated",
269
+ lines=2,
270
+ info="Descreva o que deve aparecer na imagem"
271
+ )
272
+
273
+ # Botão de gerar
274
+ gerar_btn = gr.Button(
275
+ "✨ Gerar Post",
276
+ variant="primary",
277
+ size="lg"
278
+ )
279
+
280
+ # COLUNA DIREITA: Outputs
281
+ with gr.Column(scale=1):
282
+ gr.Markdown("### 📋 Resultado")
283
+
284
+ # Status da geração
285
+ status_output = gr.Textbox(
286
+ label="Status",
287
+ value="Aguardando...",
288
+ interactive=False,
289
+ max_lines=1
290
+ )
291
+
292
+ # Texto gerado
293
+ texto_output = gr.Textbox(
294
+ label="Legenda Gerada",
295
+ lines=12,
296
+ show_copy_button=True,
297
+ info="Clique no ícone para copiar!"
298
+ )
299
+
300
+ # Imagem gerada
301
+ imagem_output = gr.Image(
302
+ label="Imagem Gerada",
303
+ type="pil",
304
+ height=400
305
+ )
306
+
307
+ # Exemplos prontos (aparecem abaixo)
308
+ gr.Markdown("### 💡 Experimente estes exemplos:")
309
+ gr.Examples(
310
+ examples=[
311
+ [
312
+ "motivação para treinar no frio",
313
+ "Fitness e Vida Saudável",
314
+ "Inspirador e motivacional",
315
+ "person exercising outdoors in winter, motivated, energetic",
316
+ True
317
+ ],
318
+ [
319
+ "receita saudável de café da manhã",
320
+ "Alimentação e Nutrição",
321
+ "Educativo e informativo",
322
+ "healthy breakfast bowl, colorful fruits, wooden table",
323
+ True
324
+ ],
325
+ [
326
+ "dicas de produtividade para empreendedores",
327
+ "Negócios e Empreendedorismo",
328
+ "Profissional e técnico",
329
+ "productive workspace, organized desk, laptop",
330
+ False
331
+ ]
332
+ ],
333
+ inputs=[
334
+ tema_input,
335
+ nicho_input,
336
+ estilo_input,
337
+ descricao_img_input,
338
+ gerar_img_checkbox
339
+ ]
340
+ )
341
+
342
+ # Conectar botão com função
343
+ # Quando botão é clicado:
344
+ # 1. Gradio pega valores dos inputs
345
+ # 2. Chama gerar_post_interface()
346
+ # 3. Recebe os 3 retornos
347
+ # 4. Mostra nos outputs correspondentes
348
+ gerar_btn.click(
349
+ fn=gerar_post_interface,
350
+ inputs=[
351
+ tema_input,
352
+ nicho_input,
353
+ estilo_input,
354
+ descricao_img_input,
355
+ gerar_img_checkbox
356
+ ],
357
+ outputs=[
358
+ texto_output,
359
+ imagem_output,
360
+ status_output
361
+ ],
362
+ show_progress="full"
363
+ )
364
+
365
+ # Footer
366
+ gr.Markdown("""
367
+ ---
368
+ **Desenvolvido no Curso de Python com IA** |
369
+ 🤖 Powered by Llama 3.1 & FLUX |
370
+ ⚡ Hugging Face Spaces + Gradio
371
+ """)
372
 
373
  # Lançar aplicação
374
  if __name__ == "__main__":
375
+ demo.launch()