# 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 "" 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()