DecompAI / app.py
TaylorKaua's picture
Update app.py
bb9f5fd verified
# app.py - Gradio app (corrigido) para rodar DECOMPAI em Hugging Face Spaces
import os
import traceback
from typing import Optional
import gradio as gr
# Tenta carregar cliente da Hugging Face (para fallback via Inference API)
hf_token = os.environ.get("HF_TOKEN") or os.environ.get("HUGGINGFACE_TOKEN") or None
INFERENCE_MODEL = "tiiuae/falcon-40b-instruct" # exemplo: substitua por um modelo apropriado
try:
from huggingface_hub import InferenceClient
hf_client = InferenceClient(token=hf_token) if hf_token else None
except Exception:
hf_client = None
# Tenta importar função local do repositório (ajuste o caminho/nome conforme seu projeto)
LOCAL_DECOMPILE_FN = None
try:
# tente alguns caminhos comuns — ajuste para o nome real do seu projeto
try:
from decompai import decompile_text as _fn # ajuste conforme disponível
LOCAL_DECOMPILE_FN = _fn
except Exception:
try:
from src.decompai import decompile_text as _fn2
LOCAL_DECOMPILE_FN = _fn2
except Exception:
LOCAL_DECOMPILE_FN = None
except Exception:
LOCAL_DECOMPILE_FN = None
def run_local_decompile(text: str) -> str:
"""Chama a função local (se existir). Deve retornar string com resultado."""
if not LOCAL_DECOMPILE_FN:
raise RuntimeError("Função local decompiladora não encontrada.")
return LOCAL_DECOMPILE_FN(text)
def run_hf_inference(prompt: str, model_name: Optional[str] = None) -> str:
"""Fallback: usa Hugging Face Inference API para gerar uma resposta."""
model = model_name or INFERENCE_MODEL
if not hf_client:
raise RuntimeError("HF client não disponível — verifique HF_TOKEN nas Secrets do Space.")
try:
out = hf_client.text_generation(model=model, inputs=prompt, max_new_tokens=512)
if isinstance(out, list):
return out[0].get("generated_text", str(out[0]))
if isinstance(out, dict):
return out.get("generated_text") or str(out)
return str(out)
except Exception as e:
try:
resp = hf_client(model=model, inputs=prompt)
return str(resp)
except Exception as e2:
raise RuntimeError(f"Erro na Inference API: {e}\n{e2}")
def prepare_prompt_from_input(file_contents: Optional[str], text_input: Optional[str]) -> str:
prompt_parts = []
if file_contents:
prompt_parts.append("Input (arquivo/hex/binário):\n" + file_contents)
if text_input:
prompt_parts.append("Input (texto):\n" + text_input)
prompt = "\n\n".join(prompt_parts)
prompt = "Por favor, tente decompilar / traduzir o seguinte conteúdo para um código legível. Explique suposições e indique se algo não pôde ser recuperado.\n\n" + prompt
return prompt
def read_file_contents_from_path_or_obj(file_obj) -> str:
"""
Normaliza o conteúdo do arquivo:
- se file_obj for caminho (str) e existir -> lê bytes e tenta decodificar (utf-8, latin1) ou retorna hex
- se file_obj for bytes -> tenta decodificar ou retorna hex
- se file_obj for None -> retorna None
"""
if file_obj is None:
return None
# Se for string que representa caminho
if isinstance(file_obj, str):
path = file_obj
if os.path.exists(path):
with open(path, "rb") as f:
b = f.read()
try:
return b.decode("utf-8")
except Exception:
try:
return b.decode("latin-1")
except Exception:
return b.hex()
else:
# talvez seja conteúdo textual já
return file_obj
# se for bytes/bytearray
if isinstance(file_obj, (bytes, bytearray)):
try:
return file_obj.decode("utf-8")
except Exception:
try:
return file_obj.decode("latin-1")
except Exception:
return file_obj.hex()
# file-like object (quando Spaces envia um dict ou objeto)
try:
# many cases in HF Spaces pass a dict-like with "name" or a tempfile-like object
name = getattr(file_obj, "name", None)
if name and os.path.exists(name):
with open(name, "rb") as f:
b = f.read()
try:
return b.decode("utf-8")
except Exception:
try:
return b.decode("latin-1")
except Exception:
return b.hex()
except Exception:
pass
# fallback para str()
try:
return str(file_obj)
except Exception:
return "<ERRO lendo arquivo>"
def decompile_interface(file_obj, text_input, model_name):
try:
file_contents = read_file_contents_from_path_or_obj(file_obj)
prompt = prepare_prompt_from_input(file_contents, text_input)
if LOCAL_DECOMPILE_FN:
result = run_local_decompile(prompt)
return f"--- Resultado (função local) ---\n{result}"
if hf_client:
result = run_hf_inference(prompt, model_name=model_name or INFERENCE_MODEL)
return f"--- Resultado (Hugging Face Inference API) ---\n{result}"
return "Nenhuma função local disponível e HF client não está configurado. Defina HF_TOKEN nas Secrets do Space."
except Exception as e:
tb = traceback.format_exc()
return f"Erro durante a decompilação:\n{e}\n\nTraceback:\n{tb}"
with gr.Blocks(title="DECOMPAI - Decompiler (Spaces)") as demo:
gr.Markdown("# DECOMPAI (Exemplo de Space)\nEnvie um arquivo ou cole texto e escolha o modelo (opcional).")
with gr.Row():
with gr.Column(scale=2):
# <-- CORREÇÃO AQUI: usar type='filepath' ou 'binary'. Para ler do disco usamos 'filepath'
file_in = gr.File(label="Arquivo (binário/hex) — opcional", file_count="single", type="filepath")
text_in = gr.Textbox(label="Ou cole conteúdo / hex / texto aqui", lines=8)
model_in = gr.Textbox(label="Modelo HF (opcional, ex: 'tiiuae/falcon-40b-instruct')", placeholder=INFERENCE_MODEL)
run_btn = gr.Button("Decompilar")
with gr.Column(scale=3):
output = gr.Textbox(label="Resultado", lines=24)
run_btn.click(fn=decompile_interface, inputs=[file_in, text_in, model_in], outputs=[output])
if __name__ == "__main__":
demo.launch()