import gradio as gr
import os
import subprocess
import sys
import shutil
import uuid
import platform
import time
from pathlib import Path
import tempfile
import glob
import traceback
def ensure_dir(dir_path):
"""Ensure directory exists"""
Path(dir_path).mkdir(parents=True, exist_ok=True)
def check_dependencies():
"""Check if required dependencies are available"""
missing_deps = []
# Check for nuitka first
try:
result = subprocess.run([sys.executable, "-m", "nuitka", "--version"], capture_output=True, text=True)
if result.returncode != 0:
missing_deps.append("nuitka")
except:
missing_deps.append("nuitka")
# Check for patchelf (usually available in HF Spaces)
result = subprocess.run(["which", "patchelf"], capture_output=True)
if result.returncode != 0:
missing_deps.append("patchelf")
# Check for gcc (usually available in HF Spaces)
result = subprocess.run(["which", "gcc"], capture_output=True)
if result.returncode != 0:
missing_deps.append("gcc")
return missing_deps
def check_static_libpython():
"""Check if static libpython is available"""
try:
# Try to find static libpython
result = subprocess.run(
[sys.executable, "-c", "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))"],
capture_output=True, text=True
)
if result.returncode == 0:
libdir = result.stdout.strip()
# Look for libpython.a files
static_libs = glob.glob(os.path.join(libdir, "libpython*.a"))
return len(static_libs) > 0
except:
pass
return False
def get_current_python_version():
"""Get the current Python version for compatibility notes"""
return f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
def get_nuitka_version():
"""Get the current Nuitka version to handle different command line options"""
try:
result = subprocess.run([sys.executable, "-m", "nuitka", "--version"],
capture_output=True, text=True)
if result.returncode == 0:
version_line = result.stdout.strip().split('\n')[0]
# Extract version number from output like "Nuitka 2.5.0"
version = version_line.split()[-1]
return version
return "not installed"
except:
return "not installed"
def create_progress_bar(progress, status_text="", show_percentage=True):
"""Create an HTML progress bar"""
percentage = max(0, min(100, progress * 100))
color = "bg-green-500" if percentage == 100 else ("bg-yellow-500" if percentage > 50 else "bg-blue-500")
html = f"""
{f'{percentage:.1f}%' if show_percentage else ''}
{status_text}
"""
return html
def install_system_packages(packages_content, progress_callback=None):
"""Note about system packages in HF Spaces - they cannot be installed"""
if not packages_content.strip():
return "No system packages specified."
# In HF Spaces, we can't install system packages
packages_list = [line.strip() for line in packages_content.strip().split('\n')
if line.strip() and not line.strip().startswith('#')]
if packages_list:
return f"❌ System packages cannot be installed in Hugging Face Spaces:\n{', '.join(packages_list)}\n\nℹ️ HF Spaces runs in a containerized environment without sudo access.\nThese packages need to be pre-installed in the Docker image or available as Python packages."
return "No system packages specified."
def install_nuitka_if_missing():
"""Try to install Nuitka if it's missing"""
try:
# Check if nuitka is already installed
result = subprocess.run([sys.executable, "-m", "nuitka", "--version"], capture_output=True)
if result.returncode == 0:
return True, "Nuitka is already installed"
# Try to install nuitka
print("Installing Nuitka...")
result = subprocess.run([sys.executable, "-m", "pip", "install", "nuitka"],
capture_output=True, text=True)
if result.returncode == 0:
return True, "Nuitka installed successfully"
else:
return False, f"Failed to install Nuitka: {result.stderr}"
except Exception as e:
return False, f"Error installing Nuitka: {str(e)}"
def find_compiled_binary(output_dir, output_filename):
"""Find the compiled binary, checking different possible paths"""
# Try direct path first
direct_path = os.path.join(output_dir, output_filename)
if os.path.exists(direct_path):
return direct_path
# Try in .dist folder (standalone builds)
dist_path = os.path.join(output_dir, "user_script.dist", output_filename)
if os.path.exists(dist_path):
return dist_path
# Try using glob to find any executable
patterns = [
os.path.join(output_dir, "**", output_filename),
os.path.join(output_dir, "**", "user_script"),
os.path.join(output_dir, "**", "*.bin"),
os.path.join(output_dir, "**", "*.exe")
]
for pattern in patterns:
matches = glob.glob(pattern, recursive=True)
if matches:
return matches[0]
return None
def compile_with_nuitka(code, requirements, packages, compilation_mode, output_extension, progress_callback=None):
"""Compile Python code with Nuitka"""
try:
# Initialize progress
if progress_callback:
progress_callback(0, "Starting compilation process...")
# Check if Nuitka is installed
nuitka_installed, nuitka_msg = install_nuitka_if_missing()
if not nuitka_installed:
error_summary = f"""# ❌ Nuitka Not Available
## Error:
{nuitka_msg}
## Solution:
Nuitka needs to be installed first. In Hugging Face Spaces, this should be done in the requirements.txt file:
```
nuitka
```
Add this to your requirements.txt and redeploy the space."""
return error_summary, None, nuitka_msg, False
if progress_callback:
progress_callback(0.05, "Checking environment...")
# Check Nuitka version
nuitka_version = get_nuitka_version()
# Check if static libpython is available
has_static_libpython = check_static_libpython()
# Check dependencies first
missing_deps = check_dependencies()
if progress_callback:
progress_callback(0.1, "Setting up compilation directories...")
# Create unique ID for this compilation
job_id = str(uuid.uuid4())
base_dir = os.path.join(os.getcwd(), "user_code")
job_dir = os.path.join(base_dir, job_id)
output_dir = os.path.join(os.getcwd(), "compiled_output", job_id)
# Create directories
ensure_dir(job_dir)
ensure_dir(output_dir)
if progress_callback:
progress_callback(0.15, "Processing packages...")
# Handle system packages (just log them, can't install in HF Spaces)
packages_result = install_system_packages(packages)
# Write code to a Python file
script_path = os.path.join(job_dir, "user_script.py")
with open(script_path, "w") as f:
f.write(code)
if progress_callback:
progress_callback(0.2, "Installing Python requirements...")
# Handle requirements
install_result = "No Python requirements specified."
if requirements.strip():
req_path = os.path.join(job_dir, "requirements.txt")
with open(req_path, "w") as f:
f.write(requirements)
try:
install_process = subprocess.run(
[sys.executable, "-m", "pip", "install", "--no-cache-dir", "-r", req_path],
capture_output=True,
text=True
)
if install_process.returncode == 0:
install_result = "✅ Python requirements installed successfully."
else:
install_result = f"⚠️ Installation completed with warnings. Return code: {install_process.returncode}\n{install_process.stderr}"
except Exception as e:
install_result = f"❌ Error installing requirements: {str(e)}"
return install_result, None, f"Error: {str(e)}", False
if progress_callback:
progress_callback(0.3, "Building compilation command...")
# Build compilation command based on mode
if compilation_mode == "Maximum Compatibility (Recommended)":
cmd = [
sys.executable, "-m", "nuitka",
"--standalone",
"--onefile", # Single portable file
"--show-progress",
"--remove-output",
"--follow-imports",
"--assume-yes-for-downloads", # Auto-download missing dependencies
"--python-flag=no_site", # Reduce dependencies
"--python-flag=no_warnings", # Reduce warnings
script_path,
f"--output-dir={output_dir}"
]
# Add static linking if available
if has_static_libpython:
cmd.append("--static-libpython=yes")
mode_name = "Maximum Compatibility Binary"
elif compilation_mode == "Portable Binary":
cmd = [
sys.executable, "-m", "nuitka",
"--show-progress",
"--remove-output",
"--assume-yes-for-downloads",
"--python-flag=no_site",
"--python-flag=no_warnings",
script_path,
f"--output-dir={output_dir}"
]
mode_name = "Portable Non-Standalone"
else: # Standalone Binary
cmd = [
sys.executable, "-m", "nuitka",
"--standalone",
"--onefile",
"--show-progress",
"--remove-output",
"--assume-yes-for-downloads",
"--python-flag=no_site",
"--python-flag=no_warnings",
script_path,
f"--output-dir={output_dir}"
]
mode_name = "Standalone Binary"
# Run compilation
if progress_callback:
progress_callback(0.4, "Executing Nuitka compilation...")
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
bufsize=1,
universal_newlines=True
)
# Progress tracking
compile_output = ""
line_count = 0
# Real-time progress display
for line in iter(process.stdout.readline, ''):
compile_output += line
line_count += 1
# Update progress
progress_val = 0.4 + (min(line_count / 200, 0.55) * 0.5)
status_text = "Compiling..."
if "INFO:" in line:
status_text = f"INFO: {line.strip()[:60]}..."
elif "PROCESSING" in line:
status_text = f"Processing: {line.strip()[:60]}..."
elif "Optimizing" in line:
status_text = f"Optimizing: {line.strip()[:60]}..."
elif "Creating" in line:
status_text = f"Creating: {line.strip()[:60]}..."
if progress_callback:
progress_callback(progress_val, status_text)
process.wait()
if progress_callback:
progress_callback(0.9, "Finalizing compilation...")
# Find the compiled binary
output_filename = f"user_script{output_extension}"
binary_path = find_compiled_binary(output_dir, output_filename)
# If not found with expected extension, try finding any executable
if not binary_path:
# Try common executable patterns for onefile
patterns = [
os.path.join(output_dir, "user_script"),
os.path.join(output_dir, "user_script.bin"),
os.path.join(output_dir, "**", "user_script"),
os.path.join(output_dir, "**", "*.bin"),
]
for pattern in patterns:
matches = glob.glob(pattern, recursive=True)
if matches:
binary_path = matches[0]
break
if process.returncode == 0 and binary_path:
# Check if it's really a binary file
try:
file_process = subprocess.run(["file", binary_path], capture_output=True, text=True)
binary_info = file_process.stdout
except:
binary_info = "Binary file (unable to get detailed info)"
# Check linking type
try:
ldd_process = subprocess.run(["ldd", binary_path], capture_output=True, text=True)
if "not a dynamic executable" in ldd_process.stderr or "statically linked" in ldd_process.stdout:
linking_info = "✅ Statically linked - fully portable!"
else:
# Check what dynamic libraries are required
if ldd_process.returncode == 0:
libs = ldd_process.stdout.count("=>")
linking_info = f"🔗 Dynamically linked ({libs} libraries) - designed for maximum compatibility"
else:
linking_info = "ℹ️ Compiled binary - should work on compatible systems"
except:
linking_info = "ℹ️ Compiled binary created successfully"
# Rename to desired extension
if output_extension in ['.bin', '.sh'] and not binary_path.endswith(output_extension):
new_binary_path = binary_path + output_extension
shutil.move(binary_path, new_binary_path)
binary_path = new_binary_path
# Make executable
os.chmod(binary_path, 0o755)
# Current Python version info
current_python = get_current_python_version()
# Build the result summary string
static_status = "Yes" if has_static_libpython else "No"
file_size = os.path.getsize(binary_path) / 1024
binary_basename = os.path.basename(binary_path)
# Create result summary
result_summary = f"""# ✅ Compilation Successful!
## Compilation Details:
- **Mode**: {mode_name}
- **Nuitka Version**: {nuitka_version}
- **Exit Code**: {process.returncode}
- **Output Path**: {binary_path}
- **File Size**: {file_size:.2f} KB
- **Compiled with Python**: {current_python}
- **Static Libpython Available**: {static_status}
- **Linking**: {linking_info}
## Environment Results:
**System Packages**: {packages_result}
**Python Requirements**: {install_result}
## Binary Information:
{binary_info}
## 🚀 Portability Notes:
- This binary was compiled with maximum compatibility settings
- Using --onefile for single-file distribution
- Added --assume-yes-for-downloads for automatic dependency resolution
- Used --python-flag=no_site to reduce system dependencies
- Should work on most compatible Linux systems
## 📋 Usage Instructions:
```bash
chmod +x {binary_basename}
./{binary_basename}
```
## ⚠️ HF Spaces Notice:
This binary was compiled in a Hugging Face Spaces environment. For best results:
1. Download the binary to your local system
2. Make it executable: `chmod +x filename`
3. Run it in a compatible Linux environment"""
if progress_callback:
progress_callback(1.0, "Compilation successful! 🎉")
return result_summary, binary_path, compile_output, True
else:
# Add more detailed error information
error_summary = f"""# ❌ Compilation Failed
## Error Details:
- **Exit Code**: {process.returncode}
- **Mode Attempted**: {mode_name}
## Environment Results:
**System Packages**: {packages_result}
**Python Requirements**: {install_result}
## Compilation Output:
```
{compile_output}
```
## Possible Solutions:
1. Check your code for syntax errors
2. Ensure all imports are available in requirements.txt
3. Try a different compilation mode
4. Review the compilation logs above
## Missing Dependencies:
{', '.join(missing_deps) if missing_deps else 'None detected'}
## Environment Info:
- **Nuitka Version**: {nuitka_version}
- **Python Version**: {current_python}
- **Platform**: {platform.platform()}"""
if progress_callback:
progress_callback(1.0, "Compilation failed ❌")
return error_summary, None, compile_output, False
except Exception as e:
# Provide detailed error information
error_trace = traceback.format_exc()
error_summary = f"""# ❌ Compilation Error
## Error:
{str(e)}
## Full Error Trace:
```
{error_trace}
```
## Environment Status:
- **Nuitka Version**: {get_nuitka_version()}
- **Python Version**: {get_current_python_version()}
- **Working Directory**: {os.getcwd()}
## Troubleshooting Steps:
1. Check if Nuitka is properly installed
2. Verify your code syntax
3. Check available disk space
4. Try with simpler code first"""
if progress_callback:
progress_callback(1.0, "Error occurred ❌")
return error_summary, None, f"Error: {str(e)}\n\n{error_trace}", False
def run_compiled_binary(binary_path):
"""Run the compiled binary and return the output"""
if not binary_path or not os.path.exists(binary_path):
return "❌ No binary available to run."
try:
# Make the binary executable
os.chmod(binary_path, 0o755)
# Run the binary with timeout
process = subprocess.run(
[binary_path],
capture_output=True,
text=True,
timeout=30, # Increased timeout for HF Spaces
cwd=os.path.dirname(binary_path) # Run in binary's directory
)
output = ""
if process.stdout:
output += f"## [STDOUT]\n```\n{process.stdout}\n```\n"
if process.stderr:
output += f"## [STDERR]\n```\n{process.stderr}\n```\n"
if process.returncode != 0:
output += f"## [EXIT CODE]\n{process.returncode}\n"
if not output:
output = "✅ Binary executed successfully with no output."
else:
output = "## 🧪 Execution Results\n" + output
return output
except subprocess.TimeoutExpired:
return "⏱️ **Execution timed out after 30 seconds.**\n\nThis might indicate:\n- The program is waiting for input\n- An infinite loop\n- Long-running computation"
except Exception as e:
return f"❌ **Error running the binary:**\n\n```\n{str(e)}\n```"
# Create Gradio interface
with gr.Blocks(title="Nuitka Python Compiler for HF Spaces", theme=gr.themes.Soft()) as app:
gr.Markdown("# 🚀 Nuitka Python Compiler (HF Spaces Edition)")
gr.Markdown("Convert your Python code into portable executables using Nuitka, optimized for Hugging Face Spaces.")
# Check environment status
has_static = check_static_libpython()
missing_deps = check_dependencies()
if "nuitka" in missing_deps:
gr.Markdown("⚠️ **Nuitka is not installed!** Add 'nuitka' to your requirements.txt file.")
if has_static:
gr.Markdown("🎯 **Static Libpython Available!** Maximum portability enabled.")
else:
gr.Markdown("🔧 **Using alternative portable options.** Static libpython not available.")
if [dep for dep in missing_deps if dep != "nuitka"]:
gr.Markdown(f"⚠️ **Missing dependencies:** {', '.join([dep for dep in missing_deps if dep != 'nuitka'])}")
else:
gr.Markdown("✅ **All required dependencies available!**")
# HF Spaces specific notice
gr.Markdown("""
> ℹ️ **Running in Hugging Face Spaces**: System packages cannot be installed.
> All required dependencies should be pre-installed in the environment.
""")
with gr.Tabs():
with gr.TabItem("🔧 Compiler"):
with gr.Row():
with gr.Column(scale=2):
code_input = gr.Code(
value="""# Your Python code here
print('Hello from compiled Python!')
print('This is a smart-compiled binary!')
# This will work with automatic compatibility detection
import os, sys
print(f'Running from: {os.getcwd()}')
print(f'Python executable: {sys.executable}')
print('Compilation was optimized for your environment!')
# Simple example with user input
name = input('What is your name? ')
print(f'Hello, {name}!')""",
language="python",
label="Your Python Code",
lines=20
)
with gr.Column(scale=1):
with gr.Tabs():
with gr.TabItem("Python Requirements"):
requirements_input = gr.Textbox(
placeholder="""# Add your Python dependencies here
# Example:
# numpy==1.24.0
# pandas==2.0.0
# requests>=2.28.0
# matplotlib
# pillow""",
lines=8,
label="requirements.txt content"
)
with gr.TabItem("System Packages"):
gr.Markdown("⚠️ **System packages cannot be installed in HF Spaces**")
packages_input = gr.Textbox(
placeholder="""# System packages (for reference only)
# These cannot be installed in HF Spaces
# build-essential
# libssl-dev
# ffmpeg""",
lines=8,
label="packages.txt content (Reference Only)",
interactive=True
)
# Fixed dropdown choices
compilation_mode = gr.Dropdown(
choices=[
"Maximum Compatibility (Recommended)",
"Portable Binary",
"Standalone Binary"
],
value="Maximum Compatibility (Recommended)",
label="Compilation Mode"
)
output_extension = gr.Dropdown(
choices=[".bin", ".sh"],
value=".bin",
label="Output File Extension"
)
gr.Markdown(f"📍 **Compiling with Python {get_current_python_version()}**")
gr.Markdown(f"🔧 **Nuitka Version**: {get_nuitka_version()}")
if check_static_libpython():
gr.Markdown("🔗 **Static libpython will be used!**")
else:
gr.Markdown("🔧 **Using portable compilation flags**")
compile_btn = gr.Button("🚀 Compile with Nuitka", variant="primary")
# Progress Bar Section
with gr.Column(visible=False) as progress_section:
gr.Markdown("### 📊 Compilation Progress")
progress_bar = gr.HTML(create_progress_bar(0, "Ready to compile..."))
# Results section
with gr.Column(visible=False) as results_section:
with gr.Accordion("📊 Compilation Results", open=True):
result_summary = gr.Markdown()
with gr.Accordion("📜 Compilation Logs", open=False):
compile_logs = gr.Textbox(label="Detailed Compilation Output", lines=15)
download_file = gr.File(label="📥 Download Compiled Binary")
# Test run section
with gr.Row():
run_btn = gr.Button("🧪 Test Run Binary", variant="secondary")
run_output = gr.Markdown(label="Execution Output")
# Variables to store state
current_binary_path = gr.State(None)
compilation_success = gr.State(False)
def update_progress_display(progress, status):
"""Update the progress bar display"""
return gr.update(value=create_progress_bar(progress, status))
def handle_compilation(code, requirements, packages, mode, extension):
try:
# Show progress section
yield (
gr.update(visible=True), # progress_section
gr.update(value=create_progress_bar(0, "Initializing compilation...")), # progress_bar
gr.update(visible=False), # results_section (hide initially)
gr.update(), # result_summary
gr.update(), # compile_logs
gr.update(visible=False), # download_file
None, # current_binary_path
False # compilation_success
)
# Define progress callback
def progress_callback(progress, status):
# This will be called by compile_with_nuitka to update progress
pass
# Start compilation with manual progress updates
compilation_started = False
# Step 1: Initial checks
yield (
gr.update(visible=True), # progress_section
gr.update(value=create_progress_bar(0.1, "Checking Nuitka installation...")), # progress_bar
gr.update(visible=False), # results_section
gr.update(), # result_summary
gr.update(), # compile_logs
gr.update(visible=False), # download_file
None, # current_binary_path
False # compilation_success
)
# Step 2: Environment setup
yield (
gr.update(visible=True), # progress_section
gr.update(value=create_progress_bar(0.2, "Setting up environment...")), # progress_bar
gr.update(visible=False), # results_section
gr.update(), # result_summary
gr.update(), # compile_logs
gr.update(visible=False), # download_file
None, # current_binary_path
False # compilation_success
)
# Step 3: Installing requirements
yield (
gr.update(visible=True), # progress_section
gr.update(value=create_progress_bar(0.3, "Installing requirements...")), # progress_bar
gr.update(visible=False), # results_section
gr.update(), # result_summary
gr.update(), # compile_logs
gr.update(visible=False), # download_file
None, # current_binary_path
False # compilation_success
)
# Step 4: Compilation in progress
for i in range(4, 9):
yield (
gr.update(visible=True), # progress_section
gr.update(value=create_progress_bar(i/10, "Compiling with Nuitka...")), # progress_bar
gr.update(visible=False), # results_section
gr.update(), # result_summary
gr.update(), # compile_logs
gr.update(visible=False), # download_file
None, # current_binary_path
False # compilation_success
)
time.sleep(0.5) # Small delay to show progress
# Run the actual compilation
summary, binary_path, logs, success = compile_with_nuitka(
code, requirements, packages, mode, extension
)
# Final progress update
yield (
gr.update(visible=True), # progress_section
gr.update(value=create_progress_bar(1.0, "Compilation complete!" if success else "Compilation failed")), # progress_bar
gr.update(visible=True), # results_section
gr.update(value=summary), # result_summary
gr.update(value=logs), # compile_logs
gr.update(visible=False), # download_file (initially hidden)
None, # current_binary_path
False # compilation_success
)
if success and binary_path:
# Create download file
download_filename = f"compiled_program{extension}"
download_path = os.path.join(os.path.dirname(binary_path), download_filename)
shutil.copy2(binary_path, download_path)
# Final update with download file
yield (
gr.update(visible=True), # progress_section
gr.update(value=create_progress_bar(1.0, "✅ Compilation successful! Ready to download.")), # progress_bar
gr.update(visible=True), # results_section
gr.update(value=summary), # result_summary
gr.update(value=logs), # compile_logs
gr.update(value=download_path, visible=True), # download_file
binary_path, # current_binary_path
True # compilation_success
)
else:
# Final update for failure
yield (
gr.update(visible=True), # progress_section
gr.update(value=create_progress_bar(1.0, "❌ Compilation failed. Check logs for details.")), # progress_bar
gr.update(visible=True), # results_section
gr.update(value=summary), # result_summary
gr.update(value=logs), # compile_logs
gr.update(visible=False), # download_file
None, # current_binary_path
False # compilation_success
)
except Exception as e:
error_trace = traceback.format_exc()
error_summary = f"""# ❌ Unexpected Error in Compilation Handler
## Error:
{str(e)}
## Full Trace:
```
{error_trace}
```"""
yield (
gr.update(visible=True), # progress_section
gr.update(value=create_progress_bar(1.0, "❌ Error occurred during compilation")), # progress_bar
gr.update(visible=True), # results_section
gr.update(value=error_summary), # result_summary
gr.update(value=f"Error: {str(e)}"), # compile_logs
gr.update(visible=False), # download_file
None, # current_binary_path
False # compilation_success
)
def handle_run(binary_path):
if binary_path:
output = run_compiled_binary(binary_path)
return gr.update(value=output)
else:
return gr.update(value="❌ No binary available to run.")
compile_btn.click(
handle_compilation,
inputs=[code_input, requirements_input, packages_input, compilation_mode, output_extension],
outputs=[progress_section, progress_bar, results_section, result_summary, compile_logs, download_file, current_binary_path, compilation_success]
)
run_btn.click(
handle_run,
inputs=[current_binary_path],
outputs=[run_output]
)
with gr.TabItem("📖 How to Use"):
gr.Markdown("""
## 🎯 Smart Compilation in HF Spaces
**Automatic Environment Detection**
This app automatically detects your Python environment and chooses the best compilation strategy:
- Uses static libpython if available (maximum portability)
- Falls back to highly portable alternatives if not
- Automatically handles missing dependencies
- Optimized specifically for Hugging Face Spaces environment
## 📋 Usage Instructions
### 1. Write Your Code
- Enter your Python code in the code editor
- Add any Python package requirements in the requirements tab
### 2. Choose Compilation Mode
- **Maximum Compatibility**: Best for most use cases (recommended)
- **Portable Binary**: Smaller size, may need Python runtime
- **Standalone Binary**: Includes all dependencies (larger)
### 3. Compile
- Click "Compile with Nuitka"
- Watch the progress bar for compilation status
- Wait for the compilation to complete
- Download the resulting binary
### 4. Run Your Binary
```bash
# On Linux (including WSL)
chmod +x compiled_program.bin
./compiled_program.bin
# In WSL, copy to Linux filesystem first
cp /mnt/c/Users/username/Downloads/compiled_program.bin ~/
cd ~
chmod +x compiled_program.bin
./compiled_program.bin
```
## ⚠️ HF Spaces Limitations
- **System packages cannot be installed** (no apt-get access)
- All required system dependencies must be pre-installed
- Compilation happens in a containerized environment
- Binary execution may have resource limits
## 📋 Important Requirements
For this app to work in HF Spaces, ensure your `requirements.txt` includes:
```
gradio
nuitka
```
## 📊 Compilation Modes Comparison
| Mode | Size | Portability | Speed | Best For |
|------|------|-------------|--------|----------|
| Maximum Compatibility | Medium | Highest | Fast | Distribution |
| Portable Binary | Small | High | Fastest | Quick testing |
| Standalone Binary | Large | Highest | Medium | Isolated deployment |
""")
with gr.TabItem("ℹ️ About"):
gr.Markdown(f"""
## 🧠 Smart Compilation Technology
**How it works:**
1. **Environment Detection**: Checks if static libpython is available
2. **Adaptive Options**: Uses the best available compilation flags
3. **Fallback Strategy**: Ensures compilation succeeds even without static linking
4. **Automatic Dependencies**: Resolves missing dependencies automatically
5. **HF Spaces Optimization**: Adapted for Hugging Face Spaces environment
6. **Real-time Progress**: Shows compilation progress with a visual progress bar
This approach maximizes compatibility across different Python environments while working within HF Spaces constraints.
## ✅ What This Solves
**Problems addressed:**
- ✅ Static libpython not available error
- ✅ Python version mismatches
- ✅ HF Spaces environment limitations
- ✅ WSL compatibility issues
- ✅ Dependency resolution
- ✅ Cross-environment portability
- ✅ Real-time compilation feedback
## ☁️ Current Environment Status
```
Platform: {platform.platform()}
Architecture: {platform.architecture()[0]}
Machine: {platform.machine()}
Python Version: {get_current_python_version()}
Nuitka Version: {get_nuitka_version()}
Static Libpython: {'✅ Available' if check_static_libpython() else '❌ Not Available'}
Environment: Hugging Face Spaces
```
## 📋 Best Practices
**Recommendations:**
1. ✅ Always use "Maximum Compatibility" mode
2. ✅ Test with simple scripts first
3. ✅ Copy binaries to Linux filesystem in WSL
4. ✅ Let the app automatically choose the best settings
5. ✅ Check the compilation details for specific optimizations used
6. ✅ Avoid system packages that require installation
7. ✅ Include 'nuitka' in your requirements.txt for HF Spaces
8. ✅ Watch the progress bar for compilation status
## 🔧 Troubleshooting
**Common Issues:**
- **Import errors**: Check that all packages are in requirements.txt
- **Binary won't run**: Ensure you're on a compatible Linux system
- **Permission denied**: Run `chmod +x filename` before execution
- **Missing libraries**: Try "Maximum Compatibility" mode
- **Nothing happens on click**: Check that Nuitka is installed in requirements.txt
- **Compilation stuck**: Check the progress bar and logs for details
## 🚀 Future Improvements
- Support for more compilation targets
- Better error messages and diagnostics
- Automatic dependency detection
- Cross-platform compilation support
- Enhanced progress tracking
""")
gr.Markdown("---")
gr.Markdown("🤖 Created by Claude 3.7 Sonnet | 🚀 Powered by Nuitka with Smart Compilation | ☁️ Optimized for HF Spaces")
if __name__ == "__main__":
# Create necessary directories on startup
ensure_dir("user_code")
ensure_dir("compiled_output")
# Check if Nuitka is available
if "nuitka" in check_dependencies():
print("WARNING: Nuitka is not installed. Please add 'nuitka' to your requirements.txt file.")
app.launch()