Spaces:
Build error
Build error
| # 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() |