File size: 8,354 Bytes
7687a98 f38792f 762671d f38792f 762671d f38792f e406699 f38792f 3c51c8e f38792f 3c51c8e f38792f 3c51c8e f38792f 3c51c8e f38792f 7687a98 f38792f 7687a98 f38792f 7687a98 f38792f b4da423 f38792f |
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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
import gradio as gr
import requests
import re
# --------------------------------------------
# Variáveis globais (poderíamos usar State)
# --------------------------------------------
groq_api_key = "" # será preenchido ao usuário inserir
groq_model = "llama3-groq-70b-8192-tool-use-preview"
huggingface_ti_endpoint = "https://huggingface.co/spaces/USER/YOUR_TEXT_TO_IMAGE/queue/predict"
# ^ Ajuste conforme seu Space de Text-to-Image.
# --------------------------------------------
# Funções auxiliares
# --------------------------------------------
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."
# Monta body:
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)
# Faz parse simples para separar 3 linhas
# Caso a Groq retorne outro formato, ajuste aqui
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] # fallback: mostra a string toda
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:
# Exemplo de payload que alguns Spaces usam:
payload = {"data": [description]}
r = requests.post(huggingface_ti_endpoint, json=payload, timeout=120)
r.raise_for_status()
data = r.json()
# Exemplo: supor que a imagem retorne em data["data"][0] (base64)
# Precisaria ver doc exata do Space
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)
# Quebrar a string pelas cenas
splitted = re.split(r"(CENA\s*\d+:)", story_text, flags=re.IGNORECASE)
# splitted vira algo como ["", "CENA 1:", "texto da cena1", "CENA 2:", "texto da cena2", ...]
# Precisamos remontar pares
scenes = []
buffer_title = ""
buffer_text = ""
for chunk in splitted:
chunk = chunk.strip()
if re.match(r"(?i)cena\s*\d+:", chunk):
# se já houver buffer_text e buffer_title, finaliza
if buffer_title and buffer_text:
scenes.append(f"{buffer_title}\n{buffer_text}")
buffer_title = chunk
buffer_text = ""
else:
# é corpo da cena
if buffer_text:
buffer_text += " " + chunk
else:
buffer_text = chunk
# Adiciona o último
if buffer_title and buffer_text:
scenes.append(f"{buffer_title}\n{buffer_text}")
if not scenes:
# fallback: sem 'CENA x:' => 1 bloco só
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:
# Chama text2img
img_data = call_text_to_image_api(scene)
if not img_data:
# se falhar, placeholder
img_data = "https://via.placeholder.com/600x400?text=Falha+Gerar+Imagem"
output.append({"text": scene, "image": img_data})
return output
# --------------------------------------------
# Montando interface com Gradio
# --------------------------------------------
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):
# Gera as cenas e retorna a lista
all_scenes = run_story(idea)
# Queremos exibir "carousel"? Ou gerar uma lista?
# No Gradio, podemos retornar algo como (list of images, ou HTML).
# Exemplo simples: retornamos uma tupla (primeira imagem, e todo o texto).
# Mas se quisermos exibir cada cena isoladamente, podemos usar "Gallery" etc.
# Para simplicidade, vamos juntar tudo em HTML:
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() # armazena array de sugestões
suggestions_display = gr.Radio(
label="Sugestões Geradas",
choices=[], # será populado dinâmicamente
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")
# Lógica de Botões
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]) # array de strings
# Quando suggestions_output mudar, atualizamos o Radio
suggestions_output.change(
fn=lambda arr: gr.update(choices=arr),
inputs=[suggestions_output],
outputs=[suggestions_display]
)
# Ao clicar em "Iniciar História", chamamos run_story com a ideia selecionada
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)
|