|
import gradio as gr |
|
import requests |
|
import re |
|
|
|
|
|
|
|
|
|
groq_api_key = "" |
|
groq_model = "llama3-groq-70b-8192-tool-use-preview" |
|
huggingface_ti_endpoint = "https://huggingface.co/spaces/USER/YOUR_TEXT_TO_IMAGE/queue/predict" |
|
|
|
|
|
|
|
|
|
|
|
def set_groq_key(key): |
|
""" |
|
Salva a chave do Groq informada pelo usuário. |
|
""" |
|
global groq_api_key |
|
groq_api_key = key.strip() |
|
return f"Chave Groq salva: {groq_api_key[:6]}******" |
|
|
|
def ask_groq(prompt): |
|
""" |
|
Faz chamada à API Groq, retornando string com a resposta. |
|
Necessita de groq_api_key global. |
|
""" |
|
if not groq_api_key: |
|
return "ERRO: sem chave Groq. Insira primeiro." |
|
|
|
payload = { |
|
"messages": [{"role": "user", "content": prompt}], |
|
"model": groq_model, |
|
"temperature": 1, |
|
"max_tokens": 1024, |
|
"top_p": 1, |
|
"stream": False, |
|
} |
|
headers = { |
|
"Content-Type": "application/json", |
|
"Authorization": f"Bearer {groq_api_key}" |
|
} |
|
try: |
|
resp = requests.post("https://api.groq.com/openai/v1/chat/completions", |
|
json=payload, headers=headers, timeout=60) |
|
resp.raise_for_status() |
|
data = resp.json() |
|
content = data.get("choices",[{}])[0].get("message",{}).get("content","") |
|
return content |
|
except Exception as e: |
|
return f"Erro ao chamar Groq: {e}" |
|
|
|
def generate_suggestions(style, custom_theme): |
|
""" |
|
Gera 3 sugestões de histórias no estilo/style, usando Groq. |
|
""" |
|
if style == "Tema Personalizado": |
|
if not custom_theme.strip(): |
|
return ["Digite algo em 'Tema Personalizado'..."] |
|
tema = custom_theme |
|
else: |
|
tema = style |
|
|
|
prompt = f""" |
|
Gere 3 ideias de histórias no gênero/tema: '{tema}'. |
|
Responda no formato: |
|
1) ... |
|
2) ... |
|
3) ... |
|
""" |
|
resp = ask_groq(prompt) |
|
|
|
|
|
lines = re.split(r"\d\)|\d\.", resp) |
|
ideas = [] |
|
for line in lines: |
|
line = line.strip() |
|
if len(line) > 5: |
|
ideas.append(line) |
|
if not ideas: |
|
ideas = [resp] |
|
return ideas |
|
|
|
def call_text_to_image_api(description): |
|
""" |
|
Chama seu endpoint Hugging Face (exemplo 'queue/predict') para gerar imagem com base no `description`. |
|
Ajuste conforme a doc do seu Space. |
|
""" |
|
try: |
|
|
|
payload = {"data": [description]} |
|
r = requests.post(huggingface_ti_endpoint, json=payload, timeout=120) |
|
r.raise_for_status() |
|
data = r.json() |
|
|
|
|
|
base64_img = data["data"][0] |
|
return f"data:image/png;base64,{base64_img}" |
|
except Exception as e: |
|
return None |
|
|
|
def expand_story(idea): |
|
""" |
|
Gera uma história com várias cenas (CENA 1:, CENA 2:, etc.) dada uma ideia curta. |
|
""" |
|
if not idea or len(idea) < 5: |
|
return "Nenhuma ideia selecionada." |
|
prompt = f""" |
|
Crie uma história detalhada a partir da seguinte ideia: |
|
'{idea}' |
|
Separe cada cena como 'CENA X:' e descreva cada cena em poucas frases. |
|
""" |
|
story_text = ask_groq(prompt) |
|
|
|
splitted = re.split(r"(CENA\s*\d+:)", story_text, flags=re.IGNORECASE) |
|
|
|
|
|
scenes = [] |
|
buffer_title = "" |
|
buffer_text = "" |
|
for chunk in splitted: |
|
chunk = chunk.strip() |
|
if re.match(r"(?i)cena\s*\d+:", chunk): |
|
|
|
if buffer_title and buffer_text: |
|
scenes.append(f"{buffer_title}\n{buffer_text}") |
|
buffer_title = chunk |
|
buffer_text = "" |
|
else: |
|
|
|
if buffer_text: |
|
buffer_text += " " + chunk |
|
else: |
|
buffer_text = chunk |
|
|
|
if buffer_title and buffer_text: |
|
scenes.append(f"{buffer_title}\n{buffer_text}") |
|
if not scenes: |
|
|
|
scenes = [story_text] |
|
return scenes |
|
|
|
def run_story(idea): |
|
""" |
|
Gera as cenas da história e para cada cena gera a imagem e retorna tudo. |
|
Retorna uma lista de dicts: [{image, text}, ...]. |
|
""" |
|
scenes = expand_story(idea) |
|
output = [] |
|
for scene in scenes: |
|
|
|
img_data = call_text_to_image_api(scene) |
|
if not img_data: |
|
|
|
img_data = "https://via.placeholder.com/600x400?text=Falha+Gerar+Imagem" |
|
output.append({"text": scene, "image": img_data}) |
|
return output |
|
|
|
|
|
|
|
|
|
def ui_set_key(key): |
|
return set_groq_key(key) |
|
|
|
def ui_generate_suggs(style, custom_theme): |
|
return generate_suggestions(style, custom_theme) |
|
|
|
def ui_run_story(idea): |
|
|
|
all_scenes = run_story(idea) |
|
|
|
|
|
|
|
|
|
|
|
|
|
html_content = "" |
|
for i, sc in enumerate(all_scenes, start=1): |
|
html_content += f"<h4> Cena {i} </h4>" |
|
html_content += f"<p>{sc['text']}</p>" |
|
html_content += f"<img src='{sc['image']}' alt='cena {i}' style='max-width:400px; margin-bottom:10px;'/>" |
|
html_content += "<hr/>" |
|
|
|
return html_content |
|
|
|
import gradio as gr |
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("# IAFlix: Exemplo em Gradio\nInsira a chave Groq, gere sugestões e expanda em cenas + imagens.") |
|
with gr.Row(): |
|
groq_key_box = gr.Textbox(label="Sua Groq API Key", type="password", value="") |
|
btn_save_key = gr.Button("Salvar Chave") |
|
key_status = gr.Textbox(label="Status da Chave", interactive=False) |
|
|
|
with gr.Accordion("Passo 1: Gerar sugestões", open=True): |
|
style_dd = gr.Dropdown( |
|
label="Estilo/Gênero", |
|
choices=["Fantasia", "Ficção Científica", "Surreal", "Romance", "Tema Personalizado"], |
|
value="Fantasia" |
|
) |
|
custom_theme_box = gr.Textbox(label="Tema Personalizado (se selecionado)") |
|
|
|
btn_suggs = gr.Button("Gerar Sugestões") |
|
suggestions_output = gr.State() |
|
|
|
suggestions_display = gr.Radio( |
|
label="Sugestões Geradas", |
|
choices=[], |
|
interactive=True |
|
) |
|
|
|
with gr.Accordion("Passo 2: Expandir e gerar cenas", open=False): |
|
btn_run_story = gr.Button("Iniciar História da Sugestão Selecionada") |
|
story_html = gr.HTML(label="Resultado das Cenas") |
|
|
|
|
|
btn_save_key.click(fn=ui_set_key, inputs=[groq_key_box], outputs=[key_status]) |
|
|
|
btn_suggs.click(fn=ui_generate_suggs, |
|
inputs=[style_dd, custom_theme_box], |
|
outputs=[suggestions_output]) |
|
|
|
|
|
suggestions_output.change( |
|
fn=lambda arr: gr.update(choices=arr), |
|
inputs=[suggestions_output], |
|
outputs=[suggestions_display] |
|
) |
|
|
|
|
|
btn_run_story.click(fn=ui_run_story, |
|
inputs=[suggestions_display], |
|
outputs=[story_html]) |
|
|
|
demo.launch(server_name="0.0.0.0", server_port=7860) |
|
|