Ajedrel commited on
Commit
8b88f33
·
verified ·
1 Parent(s): 022691b

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile +29 -20
  2. app.py +152 -0
  3. requirements.txt +4 -3
Dockerfile CHANGED
@@ -1,20 +1,29 @@
1
- FROM python:3.13.5-slim
2
-
3
- WORKDIR /app
4
-
5
- RUN apt-get update && apt-get install -y \
6
- build-essential \
7
- curl \
8
- git \
9
- && rm -rf /var/lib/apt/lists/*
10
-
11
- COPY requirements.txt ./
12
- COPY src/ ./src/
13
-
14
- RUN pip3 install -r requirements.txt
15
-
16
- EXPOSE 8501
17
-
18
- HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
19
-
20
- ENTRYPOINT ["streamlit", "run", "src/streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
 
 
 
 
 
 
 
 
 
 
1
+ # Usar una imagen oficial de Python ligera
2
+ FROM python:3.10-slim
3
+
4
+ # Instalar g++ y herramientas de compilación para C++
5
+ RUN apt-get update && apt-get install -y \
6
+ g++ \
7
+ build-essential \
8
+ && rm -rf /var/lib/apt/lists/*
9
+
10
+ # Configurar un usuario no root (Requisito de seguridad en Hugging Face Spaces)
11
+ RUN useradd -m -u 1000 user
12
+ USER user
13
+ ENV PATH="/home/user/.local/bin:$PATH"
14
+
15
+ # Establecer el directorio de trabajo
16
+ WORKDIR /app
17
+
18
+ # Copiar el archivo de requerimientos e instalar dependencias
19
+ COPY --chown=user requirements.txt .
20
+ RUN pip install --no-cache-dir -r requirements.txt
21
+
22
+ # Copiar el resto del código de la aplicación
23
+ COPY --chown=user . .
24
+
25
+ # Exponer el puerto de Streamlit
26
+ EXPOSE 8501
27
+
28
+ # Comando para iniciar la aplicación
29
+ CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]
app.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import tempfile
3
+ import subprocess
4
+ import streamlit as st
5
+ from transformers import AutoTokenizer
6
+ from huggingface_hub import InferenceClient
7
+
8
+ st.set_page_config(page_title="Python to C++17 Translator", layout="wide")
9
+
10
+ if "messages" not in st.session_state:
11
+ st.session_state.messages = []
12
+
13
+ with st.sidebar:
14
+ st.header("Configuracion del Modelo")
15
+ selected_model = st.selectbox(
16
+ "Selecciona el modelo de Hugging Face:",
17
+ [
18
+ "Qwen/CodeQwen1.5-7B-Chat",
19
+ "meta-llama/CodeLlama-13b-Instruct-hf",
20
+ "bigcode/starcoder2-15b"
21
+ ],
22
+ index=0
23
+ )
24
+
25
+ st.markdown("---")
26
+ st.markdown("### Entorno de Ejecucion")
27
+ st.code("g++ -O3 -std=c++17", language="bash")
28
+
29
+ if st.button("Limpiar Historial"):
30
+ st.session_state.messages = []
31
+ st.rerun()
32
+
33
+ def get_system_prompt() -> str:
34
+ return (
35
+ "You are an expert compiler and AI engineer specializing in migrating Python code to high-performance C++17. "
36
+ "Your task is to provide direct, efficient, and thread-safe C++17 code. "
37
+ "Include all necessary headers (<iostream>, <vector>, <memory>, etc.). "
38
+ "Ensure strict type safety and prevent integer overflows. "
39
+ "Respond ONLY with the raw C++ code enclosed in ```cpp block. Do not add explanations."
40
+ )
41
+
42
+ def extract_cpp_code(response_text: str) -> str:
43
+ """Extrae el codigo C++ limpiando los bloques de markdown."""
44
+ if "```cpp" in response_text:
45
+ code = response_text.split("```cpp")[1].split("```")[0]
46
+ elif "```c++" in response_text:
47
+ code = response_text.split("```c++")[1].split("```")[0]
48
+ elif "```" in response_text:
49
+ code = response_text.split("```")[1].split("```")[0]
50
+ else:
51
+ code = response_text
52
+ return code.strip()
53
+
54
+ def compile_and_run_cpp(cpp_code: str) -> str:
55
+ """Compila y ejecuta el codigo C++ en el entorno Linux de HF Spaces."""
56
+ with tempfile.TemporaryDirectory() as tmpdir:
57
+ cpp_file = os.path.join(tmpdir, "optimized.cpp")
58
+ exe_file = os.path.join(tmpdir, "optimized_bin")
59
+
60
+ with open(cpp_file, "w") as f:
61
+ f.write(cpp_code)
62
+
63
+ # Compilacion estricta con C++17 (HF Spaces usa Debian/Ubuntu con g++ disponible)
64
+ compile_cmd = ["g++", "-O3", "-std=c++17", cpp_file, "-o", exe_file]
65
+
66
+ try:
67
+ # Compilar
68
+ comp_process = subprocess.run(compile_cmd, capture_output=True, text=True, check=True)
69
+
70
+ # Ejecutar
71
+ run_process = subprocess.run([exe_file], capture_output=True, text=True, timeout=10)
72
+
73
+ output = run_process.stdout
74
+ if run_process.stderr:
75
+ output += f"\nWarnings/Errors:\n{run_process.stderr}"
76
+ return output if output else "Ejecucion completada sin salida (stdout vacío)."
77
+
78
+ except subprocess.CalledProcessError as e:
79
+ return f"Error de Compilacion:\n{e.stderr}"
80
+ except subprocess.TimeoutExpired:
81
+ return "Timeout: La ejecucion excedio los 10 segundos."
82
+
83
+ st.title("Python ➔ C++ Auto-Translator")
84
+ st.markdown("Pega tu codigo de Python en el chat. El sistema generarala traduccion a C++17 y la ejecutara automaticamente.")
85
+
86
+ for msg in st.session_state.messages:
87
+ with st.chat_message(msg["role"]):
88
+ if msg["role"] == "user":
89
+ st.code(msg["content"], language="python")
90
+ else:
91
+ st.code(msg["content"]["code"], language="cpp")
92
+ with st.expander("Ver salida de ejecucion"):
93
+ st.text(msg["content"]["output"])
94
+
95
+ if prompt := st.chat_input("Escribe o pega tu codigo Python aqui..."):
96
+ # Añadir input del usuario al estado y mostrarlo
97
+ st.session_state.messages.append({"role": "user", "content": prompt})
98
+ with st.chat_message("user"):
99
+ st.code(prompt, language="python")
100
+
101
+ # Preparar el cliente de Hugging Face
102
+ hf_token = os.getenv("HF_TOKEN")
103
+ client = InferenceClient(model=selected_model, token=hf_token)
104
+ tokenizer = AutoTokenizer.from_pretrained(selected_model)
105
+
106
+ messages_for_hf = [
107
+ {"role": "system", "content": get_system_prompt()},
108
+ {"role": "user", "content": f"Translate this Python code to C++:\n\n{prompt}"}
109
+ ]
110
+
111
+ # Convertir al formato de chat específico del modelo
112
+ try:
113
+ formatted_prompt = tokenizer.apply_chat_template(messages_for_hf, tokenize=False, add_generation_prompt=True)
114
+ except Exception:
115
+ # Fallback por si el tokenizador no soporta apply_chat_template directamente
116
+ formatted_prompt = f"{get_system_prompt()}\n\nUser: Translate this Python code to C++:\n{prompt}\n\nAssistant:"
117
+
118
+ # Generar respuesta del asistente
119
+ with st.chat_message("assistant"):
120
+ with st.spinner("Traduciendo a C++17..."):
121
+ try:
122
+ # Generacion (sin streaming complejo en UI para facilitar la extraccion y compilacion inmediata)
123
+ response = client.text_generation(
124
+ formatted_prompt,
125
+ max_new_tokens=3000,
126
+ temperature=0.1, # Baja temperatura para codigo más determinista
127
+ return_full_text=False
128
+ )
129
+
130
+ clean_cpp = extract_cpp_code(response)
131
+ st.code(clean_cpp, language="cpp")
132
+
133
+ st.markdown("---")
134
+ st.markdown("**Ejecutando binario...**")
135
+
136
+ with st.spinner("Compilando y ejecutando..."):
137
+ execution_output = compile_and_run_cpp(clean_cpp)
138
+
139
+ with st.expander("Salida de ejecucion (stdout)", expanded=True):
140
+ st.text(execution_output)
141
+
142
+ # Guardar en el historial
143
+ st.session_state.messages.append({
144
+ "role": "assistant",
145
+ "content": {
146
+ "code": clean_cpp,
147
+ "output": execution_output
148
+ }
149
+ })
150
+
151
+ except Exception as e:
152
+ st.error(f"Error al conectar con Hugging Face API: {str(e)}")
requirements.txt CHANGED
@@ -1,3 +1,4 @@
1
- altair
2
- pandas
3
- streamlit
 
 
1
+ streamlit==1.32.2
2
+ transformers==4.39.3
3
+ huggingface-hub==0.22.2
4
+ python-dotenv==1.0.1