TaylorKaua commited on
Commit
bb9f5fd
·
verified ·
1 Parent(s): ccf8856

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -57
app.py CHANGED
@@ -1,6 +1,4 @@
1
- # app.py - Gradio app para rodar DECOMPAI em Hugging Face Spaces
2
- # Ajuste os nomes de funções locais conforme o seu repositório (ex.: decompai.decompile_text)
3
-
4
  import os
5
  import traceback
6
  from typing import Optional
@@ -18,16 +16,13 @@ except Exception:
18
  hf_client = None
19
 
20
  # Tenta importar função local do repositório (ajuste o caminho/nome conforme seu projeto)
21
- # Ex.: seu repositório pode expor `decompai.api.decompile_text` ou similar.
22
  LOCAL_DECOMPILE_FN = None
23
  try:
24
- # tente alguns caminhos comuns — ajuste para o nome real
25
  try:
26
- # se o pacote for instalado como editable e expuser decompile_text
27
- from decompai import decompile_text as _fn # exemplo
28
  LOCAL_DECOMPILE_FN = _fn
29
  except Exception:
30
- # outro palpite: src.decompai.api.decompile_text
31
  try:
32
  from src.decompai import decompile_text as _fn2
33
  LOCAL_DECOMPILE_FN = _fn2
@@ -36,97 +31,110 @@ try:
36
  except Exception:
37
  LOCAL_DECOMPILE_FN = None
38
 
 
39
  def run_local_decompile(text: str) -> str:
40
  """Chama a função local (se existir). Deve retornar string com resultado."""
41
  if not LOCAL_DECOMPILE_FN:
42
  raise RuntimeError("Função local decompiladora não encontrada.")
43
  return LOCAL_DECOMPILE_FN(text)
44
 
 
45
  def run_hf_inference(prompt: str, model_name: Optional[str] = None) -> str:
46
  """Fallback: usa Hugging Face Inference API para gerar uma resposta."""
47
  model = model_name or INFERENCE_MODEL
48
  if not hf_client:
49
  raise RuntimeError("HF client não disponível — verifique HF_TOKEN nas Secrets do Space.")
50
- # Text generation via InferenceClient
51
- # Nota: dependendo do modelo, a API pode expor métodos diferentes (text_generation, generate, etc.)
52
  try:
53
- # método genérico text_generation
54
  out = hf_client.text_generation(model=model, inputs=prompt, max_new_tokens=512)
55
- # InferenceClient pode retornar dict/list — normalize
56
  if isinstance(out, list):
57
  return out[0].get("generated_text", str(out[0]))
58
  if isinstance(out, dict):
59
  return out.get("generated_text") or str(out)
60
  return str(out)
61
  except Exception as e:
62
- # tentativa alternativa: chamar o endpoint genérico
63
  try:
64
  resp = hf_client(model=model, inputs=prompt)
65
  return str(resp)
66
  except Exception as e2:
67
  raise RuntimeError(f"Erro na Inference API: {e}\n{e2}")
68
 
 
69
  def prepare_prompt_from_input(file_contents: Optional[str], text_input: Optional[str]) -> str:
70
- """
71
- Compose um prompt razoável para o modelo/função local.
72
- Se o usuário subiu um binário/hex, a interface já deve pré-processar; aqui assumimos texto.
73
- """
74
  prompt_parts = []
75
  if file_contents:
76
  prompt_parts.append("Input (arquivo/hex/binário):\n" + file_contents)
77
  if text_input:
78
  prompt_parts.append("Input (texto):\n" + text_input)
79
  prompt = "\n\n".join(prompt_parts)
80
- # instrução para decompilar
81
  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
82
  return prompt
83
 
84
- def decompile_interface(file_obj, text_input, model_name):
 
85
  """
86
- Handler chamado pelo Gradio.
87
- file_obj can be None or uploaded file (gr.File)
88
- text_input is string
 
89
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  try:
91
- file_contents = None
92
- if file_obj is not None:
93
- # file_obj pode ser um caminho/local file object (gr.File produz um dict em Spaces)
94
- # Normalizamos: se for path, leia como binário e tentamos decodificar (utf-8/latin1/hex)
 
95
  try:
96
- # file_obj in Spaces is a dictionary with "name" and "data" occasionally; handle common cases:
97
- path = getattr(file_obj, "name", None) or (file_obj if isinstance(file_obj, str) else None)
98
- if path and os.path.exists(path):
99
- with open(path, "rb") as f:
100
- b = f.read()
101
- # tenta decodificar, se falhar, representa em hex
102
- try:
103
- file_contents = b.decode("utf-8")
104
- except Exception:
105
- try:
106
- file_contents = b.decode("latin-1")
107
- except Exception:
108
- file_contents = b.hex()
109
- else:
110
- # talvez file_obj já seja string contents
111
- if isinstance(file_obj, (bytes, bytearray)):
112
- try:
113
- file_contents = file_obj.decode("utf-8")
114
- except Exception:
115
- file_contents = file_obj.hex()
116
- elif isinstance(file_obj, str):
117
- file_contents = file_obj
118
- else:
119
- file_contents = str(file_obj)
120
  except Exception:
121
- file_contents = f"<ERRO lendo arquivo: {traceback.format_exc()}>"
 
 
 
 
 
 
 
 
 
 
 
122
 
 
 
 
123
  prompt = prepare_prompt_from_input(file_contents, text_input)
124
 
125
- # Prioridade: função local (rápida e preferível)
126
  if LOCAL_DECOMPILE_FN:
127
  result = run_local_decompile(prompt)
128
  return f"--- Resultado (função local) ---\n{result}"
129
- # Fallback: HF inference
130
  if hf_client:
131
  result = run_hf_inference(prompt, model_name=model_name or INFERENCE_MODEL)
132
  return f"--- Resultado (Hugging Face Inference API) ---\n{result}"
@@ -135,12 +143,13 @@ def decompile_interface(file_obj, text_input, model_name):
135
  tb = traceback.format_exc()
136
  return f"Erro durante a decompilação:\n{e}\n\nTraceback:\n{tb}"
137
 
138
- # Construção da interface Gradio
139
- with gr.Blocks(title="DECOMPAI - Decompiler") as demo:
140
  gr.Markdown("# DECOMPAI (Exemplo de Space)\nEnvie um arquivo ou cole texto e escolha o modelo (opcional).")
141
  with gr.Row():
142
  with gr.Column(scale=2):
143
- file_in = gr.File(label="Arquivo (binário/hex) opcional", file_count="single", type="file")
 
144
  text_in = gr.Textbox(label="Ou cole conteúdo / hex / texto aqui", lines=8)
145
  model_in = gr.Textbox(label="Modelo HF (opcional, ex: 'tiiuae/falcon-40b-instruct')", placeholder=INFERENCE_MODEL)
146
  run_btn = gr.Button("Decompilar")
@@ -149,4 +158,4 @@ with gr.Blocks(title="DECOMPAI - Decompiler") as demo:
149
  run_btn.click(fn=decompile_interface, inputs=[file_in, text_in, model_in], outputs=[output])
150
 
151
  if __name__ == "__main__":
152
- demo.launch()
 
1
+ # app.py - Gradio app (corrigido) para rodar DECOMPAI em Hugging Face Spaces
 
 
2
  import os
3
  import traceback
4
  from typing import Optional
 
16
  hf_client = None
17
 
18
  # Tenta importar função local do repositório (ajuste o caminho/nome conforme seu projeto)
 
19
  LOCAL_DECOMPILE_FN = None
20
  try:
21
+ # tente alguns caminhos comuns — ajuste para o nome real do seu projeto
22
  try:
23
+ from decompai import decompile_text as _fn # ajuste conforme disponível
 
24
  LOCAL_DECOMPILE_FN = _fn
25
  except Exception:
 
26
  try:
27
  from src.decompai import decompile_text as _fn2
28
  LOCAL_DECOMPILE_FN = _fn2
 
31
  except Exception:
32
  LOCAL_DECOMPILE_FN = None
33
 
34
+
35
  def run_local_decompile(text: str) -> str:
36
  """Chama a função local (se existir). Deve retornar string com resultado."""
37
  if not LOCAL_DECOMPILE_FN:
38
  raise RuntimeError("Função local decompiladora não encontrada.")
39
  return LOCAL_DECOMPILE_FN(text)
40
 
41
+
42
  def run_hf_inference(prompt: str, model_name: Optional[str] = None) -> str:
43
  """Fallback: usa Hugging Face Inference API para gerar uma resposta."""
44
  model = model_name or INFERENCE_MODEL
45
  if not hf_client:
46
  raise RuntimeError("HF client não disponível — verifique HF_TOKEN nas Secrets do Space.")
 
 
47
  try:
 
48
  out = hf_client.text_generation(model=model, inputs=prompt, max_new_tokens=512)
 
49
  if isinstance(out, list):
50
  return out[0].get("generated_text", str(out[0]))
51
  if isinstance(out, dict):
52
  return out.get("generated_text") or str(out)
53
  return str(out)
54
  except Exception as e:
 
55
  try:
56
  resp = hf_client(model=model, inputs=prompt)
57
  return str(resp)
58
  except Exception as e2:
59
  raise RuntimeError(f"Erro na Inference API: {e}\n{e2}")
60
 
61
+
62
  def prepare_prompt_from_input(file_contents: Optional[str], text_input: Optional[str]) -> str:
 
 
 
 
63
  prompt_parts = []
64
  if file_contents:
65
  prompt_parts.append("Input (arquivo/hex/binário):\n" + file_contents)
66
  if text_input:
67
  prompt_parts.append("Input (texto):\n" + text_input)
68
  prompt = "\n\n".join(prompt_parts)
 
69
  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
70
  return prompt
71
 
72
+
73
+ def read_file_contents_from_path_or_obj(file_obj) -> str:
74
  """
75
+ Normaliza o conteúdo do arquivo:
76
+ - se file_obj for caminho (str) e existir -> lê bytes e tenta decodificar (utf-8, latin1) ou retorna hex
77
+ - se file_obj for bytes -> tenta decodificar ou retorna hex
78
+ - se file_obj for None -> retorna None
79
  """
80
+ if file_obj is None:
81
+ return None
82
+ # Se for string que representa caminho
83
+ if isinstance(file_obj, str):
84
+ path = file_obj
85
+ if os.path.exists(path):
86
+ with open(path, "rb") as f:
87
+ b = f.read()
88
+ try:
89
+ return b.decode("utf-8")
90
+ except Exception:
91
+ try:
92
+ return b.decode("latin-1")
93
+ except Exception:
94
+ return b.hex()
95
+ else:
96
+ # talvez seja conteúdo textual já
97
+ return file_obj
98
+ # se for bytes/bytearray
99
+ if isinstance(file_obj, (bytes, bytearray)):
100
+ try:
101
+ return file_obj.decode("utf-8")
102
+ except Exception:
103
+ try:
104
+ return file_obj.decode("latin-1")
105
+ except Exception:
106
+ return file_obj.hex()
107
+ # file-like object (quando Spaces envia um dict ou objeto)
108
  try:
109
+ # many cases in HF Spaces pass a dict-like with "name" or a tempfile-like object
110
+ name = getattr(file_obj, "name", None)
111
+ if name and os.path.exists(name):
112
+ with open(name, "rb") as f:
113
+ b = f.read()
114
  try:
115
+ return b.decode("utf-8")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  except Exception:
117
+ try:
118
+ return b.decode("latin-1")
119
+ except Exception:
120
+ return b.hex()
121
+ except Exception:
122
+ pass
123
+ # fallback para str()
124
+ try:
125
+ return str(file_obj)
126
+ except Exception:
127
+ return "<ERRO lendo arquivo>"
128
+
129
 
130
+ def decompile_interface(file_obj, text_input, model_name):
131
+ try:
132
+ file_contents = read_file_contents_from_path_or_obj(file_obj)
133
  prompt = prepare_prompt_from_input(file_contents, text_input)
134
 
 
135
  if LOCAL_DECOMPILE_FN:
136
  result = run_local_decompile(prompt)
137
  return f"--- Resultado (função local) ---\n{result}"
 
138
  if hf_client:
139
  result = run_hf_inference(prompt, model_name=model_name or INFERENCE_MODEL)
140
  return f"--- Resultado (Hugging Face Inference API) ---\n{result}"
 
143
  tb = traceback.format_exc()
144
  return f"Erro durante a decompilação:\n{e}\n\nTraceback:\n{tb}"
145
 
146
+
147
+ with gr.Blocks(title="DECOMPAI - Decompiler (Spaces)") as demo:
148
  gr.Markdown("# DECOMPAI (Exemplo de Space)\nEnvie um arquivo ou cole texto e escolha o modelo (opcional).")
149
  with gr.Row():
150
  with gr.Column(scale=2):
151
+ # <-- CORREÇÃO AQUI: usar type='filepath' ou 'binary'. Para ler do disco usamos 'filepath'
152
+ file_in = gr.File(label="Arquivo (binário/hex) — opcional", file_count="single", type="filepath")
153
  text_in = gr.Textbox(label="Ou cole conteúdo / hex / texto aqui", lines=8)
154
  model_in = gr.Textbox(label="Modelo HF (opcional, ex: 'tiiuae/falcon-40b-instruct')", placeholder=INFERENCE_MODEL)
155
  run_btn = gr.Button("Decompilar")
 
158
  run_btn.click(fn=decompile_interface, inputs=[file_in, text_in, model_in], outputs=[output])
159
 
160
  if __name__ == "__main__":
161
+ demo.launch()