DHEIVER's picture
Update app.py
e9001d7 verified
import gradio as gr
from huggingface_hub import InferenceClient
from PIL import Image
import io
import base64
from functools import lru_cache
import tempfile
import hashlib
# Variável global para armazenar o token da API (padrão vazio)
API_TOKEN = ""
# Função para atualizar o token da API
def update_api_token(new_token):
global API_TOKEN
API_TOKEN = new_token.strip()
return f"✅ Token atualizado com sucesso: {API_TOKEN[:8]}... (ocultado)"
# Função para criar uma instância da API com o token atualizado usando InferenceClient
def get_inference_client(model):
return InferenceClient(model=model, token=API_TOKEN)
# Função para interpretar a imagem com cache utilizando InferenceClient (captioning)
@lru_cache(maxsize=128)
def interpret_image_cached(image_hash):
# Instanciar o client para o modelo de captioning
client = get_inference_client("Salesforce/blip2-opt-2.7b")
# Chamada da API usando método post para gerar a descrição da imagem
response = client.post(data=image_hash, task="image-to-text")
description = response.get("generated_text", "").strip().capitalize()
if not description.endswith("."):
description += "."
return description
# Função para análise nutricional com cache utilizando InferenceClient e método post
@lru_cache(maxsize=128)
def nutritional_analysis_cached(description):
client = get_inference_client("google/flan-t5-large")
prompt = (
f"Com base na descrição do prato de comida abaixo, forneça uma análise nutricional detalhada.\n\n"
f"Descrição do prato: {description}\n\n"
f"Siga este formato:\n"
f"- Calorias totais estimadas: [valor]\n"
f"- Macronutrientes (em gramas):\n"
f" - Carboidratos: [valor]\n"
f" - Proteínas: [valor]\n"
f" - Gorduras: [valor]\n"
f"- Recomendações para melhorar o prato: [sugestões]\n\n"
f"Análise nutricional:"
)
response = client.post(json={"inputs": prompt})
analysis = response.get("generated_text", "").replace("Análise nutricional:", "").strip()
return analysis
# Função para gerar dicas de saúde com cache utilizando InferenceClient e método post
@lru_cache(maxsize=128)
def health_tips_cached(description):
client = get_inference_client("google/flan-t5-large")
prompt = (
f"Com base na descrição do prato de comida abaixo, forneça dicas de saúde e sugestões "
f"para melhorar o prato, tornando-o mais equilibrado e nutritivo. Liste as dicas em tópicos.\n\n"
f"Descrição do prato: {description}\n\n"
f"Dicas de saúde:"
)
response = client.post(json={"inputs": prompt})
tips = response.get("generated_text", "").replace("Dicas de saúde:", "").strip()
return tips
# Função principal para processar a imagem e gerar resultados
def process_image(image):
try:
# Converter imagem para bytes e gerar um hash
buffered = io.BytesIO()
image.save(buffered, format="JPEG")
image_bytes = buffered.getvalue()
image_hash = hashlib.md5(image_bytes).hexdigest()
description = interpret_image_cached(image_hash)
analysis = nutritional_analysis_cached(description)
tips = health_tips_cached(description)
complete_result = (
f"Descrição do Prato:\n{description}\n\n"
f"Análise Nutricional:\n{analysis}\n\n"
f"Dicas de Saúde:\n{tips}"
)
feedback_message = "✅ Análise concluída com sucesso!"
return description, analysis, tips, complete_result, complete_result, feedback_message
except Exception as e:
feedback_message = f"❌ Erro ao processar a imagem: {str(e)}"
return "", "", "", "", "", feedback_message
# Função para gerar um arquivo de download com o resultado completo
def generate_download(complete_result):
try:
with tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode="w", encoding="utf-8") as tmp:
tmp.write(complete_result)
tmp_path = tmp.name
return tmp_path
except Exception:
return None
# Interface Gradio com aba Settings para configurar o token da API
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="cyan")) as demo:
with gr.Row():
gr.Markdown("""
# �️ Agente Nutricionista Inteligente Avançado
### Revolucione a análise de suas refeições com IA de última geração!
- **[Descrição automática](pplx://action/followup)** de pratos a partir de imagens.
- **[Análise nutricional detalhada](pplx://action/followup)** com estimativas precisas de calorias e macronutrientes.
- **[Dicas de saúde personalizadas](pplx://action/followup)** para aprimorar sua alimentação.
- **[Resultado completo para download](pplx://action/followup)** em formato TXT.
""")
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### 📸 Carregue uma Imagem")
image_input = gr.Image(type="pil", label="Upload de Imagem", height=300)
with gr.Column(scale=2):
gr.Markdown("### 🔍 Resultados")
with gr.Tabs():
with gr.TabItem("Descrição do Prato"):
description_output = gr.Textbox(label="Descrição Gerada", lines=3, interactive=False)
with gr.TabItem("Análise Nutricional"):
analysis_output = gr.Textbox(label="Análise Nutricional", lines=8, interactive=False)
with gr.TabItem("Dicas de Saúde"):
tips_output = gr.Textbox(label="Dicas de Saúde", lines=6, interactive=False)
with gr.TabItem("Resultado Completo"):
complete_result_output = gr.Textbox(label="Resultado Completo", lines=15, interactive=False)
with gr.TabItem("Settings"):
api_token_input = gr.Textbox(label="Token da API Hugging Face", placeholder="Insira seu token aqui...")
update_button = gr.Button("Atualizar Token")
update_feedback = gr.Markdown("")
with gr.Row():
submit_button = gr.Button("✨ Analisar Prato", variant="primary")
download_button = gr.Button("💾 Baixar Resultado", variant="secondary")
# Estado oculto para armazenar o resultado completo para o download
result_state = gr.State("")
feedback = gr.Markdown("")
submit_button.click(
process_image,
inputs=image_input,
outputs=[description_output, analysis_output, tips_output, complete_result_output, result_state, feedback]
)
download_button.click(
generate_download,
inputs=result_state,
outputs=gr.File(label="Seu Resultado")
)
update_button.click(
update_api_token,
inputs=api_token_input,
outputs=update_feedback
)
demo.launch()