anycoder-d0ab5740 / index.html
00Boobs00's picture
Upload folder using huggingface_hub
365c40e verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gradio Context & Dockerizer</title>
<!-- Importing Phosphor Icons for modern UI iconography -->
<script src="https://unpkg.com/@phosphor-icons/web"></script>
<style>
/* --- CSS VARIABLES & RESET --- */
:root {
--bg-body: #0f1115;
--bg-panel: #161b22;
--bg-input: #0d1117;
--border-color: #30363d;
--primary: #238636;
--primary-hover: #2ea043;
--accent: #58a6ff;
--text-main: #c9d1d9;
--text-muted: #8b949e;
--font-stack: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
--font-mono: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
--radius-md: 8px;
--radius-lg: 12px;
--shadow: 0 4px 12px rgba(0,0,0,0.5);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-body);
color: var(--text-main);
font-family: var(--font-stack);
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* --- HEADER --- */
header {
height: 60px;
background-color: var(--bg-panel);
border-bottom: 1px solid var(--border-color);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
flex-shrink: 0;
}
.brand {
display: flex;
align-items: center;
gap: 10px;
font-weight: 600;
font-size: 1.1rem;
}
.brand i {
color: var(--accent);
font-size: 1.4rem;
}
.anycoder-link {
font-size: 0.85rem;
color: var(--text-muted);
text-decoration: none;
background: rgba(255,255,255,0.05);
padding: 6px 12px;
border-radius: 20px;
transition: all 0.2s;
border: 1px solid transparent;
}
.anycoder-link:hover {
color: var(--accent);
border-color: var(--border-color);
background: rgba(255,255,255,0.1);
}
/* --- LAYOUT --- */
.layout {
display: grid;
grid-template-columns: 320px 1fr;
flex: 1;
overflow: hidden;
}
/* --- SIDEBAR (CONFIGURATION) --- */
aside {
background-color: var(--bg-panel);
border-right: 1px solid var(--border-color);
padding: 20px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 24px;
}
.config-group h3 {
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-muted);
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 8px;
}
.form-control {
margin-bottom: 16px;
}
.form-control label {
display: block;
font-size: 0.9rem;
margin-bottom: 6px;
color: var(--text-main);
}
.form-control input[type="text"],
.form-control select,
.form-control textarea {
width: 100%;
background-color: var(--bg-input);
border: 1px solid var(--border-color);
color: var(--text-main);
padding: 8px 12px;
border-radius: var(--radius-md);
font-family: inherit;
font-size: 0.9rem;
transition: border-color 0.2s;
}
.form-control input:focus,
.form-control select:focus,
.form-control textarea:focus {
outline: none;
border-color: var(--accent);
}
.range-wrapper {
display: flex;
align-items: center;
gap: 10px;
}
.range-wrapper input {
flex: 1;
}
.range-value {
font-family: var(--font-mono);
font-size: 0.85rem;
color: var(--accent);
width: 30px;
text-align: right;
}
/* --- MAIN CONTENT AREA --- */
main {
padding: 20px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 20px;
background-image: radial-gradient(var(--border-color) 1px, transparent 1px);
background-size: 24px 24px;
}
.card {
background-color: var(--bg-panel);
border: 1px solid var(--border-color);
border-radius: var(--radius-lg);
padding: 20px;
box-shadow: var(--shadow);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
border-bottom: 1px solid var(--border-color);
padding-bottom: 12px;
}
.card-title {
font-weight: 600;
display: flex;
align-items: center;
gap: 8px;
}
/* --- DOCKERFILE PREVIEW --- */
.code-block {
background-color: #0d1117;
border-radius: var(--radius-md);
padding: 16px;
font-family: var(--font-mono);
font-size: 0.85rem;
color: #a5d6ff;
overflow-x: auto;
white-space: pre;
position: relative;
}
.copy-btn {
position: absolute;
top: 10px;
right: 10px;
background: rgba(255,255,255,0.1);
border: none;
color: var(--text-main);
padding: 4px 8px;
border-radius: 4px;
font-size: 0.75rem;
cursor: pointer;
opacity: 0;
transition: opacity 0.2s;
}
.code-block:hover .copy-btn {
opacity: 1;
}
/* --- TERMINAL / LOGS --- */
.terminal {
background-color: #000;
border: 1px solid var(--border-color);
border-radius: var(--radius-md);
padding: 12px;
font-family: var(--font-mono);
font-size: 0.85rem;
height: 200px;
overflow-y: auto;
color: #d2a8ff;
}
.log-line {
margin-bottom: 4px;
display: flex;
gap: 8px;
}
.log-time {
color: var(--text-muted);
}
.log-success { color: var(--primary); }
.log-info { color: var(--accent); }
.log-warn { color: #d29922; }
/* --- ACTION BUTTONS --- */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 10px 20px;
border-radius: var(--radius-md);
font-weight: 600;
cursor: pointer;
border: none;
transition: all 0.2s;
font-size: 0.95rem;
}
.btn-primary {
background-color: var(--primary);
color: white;
}
.btn-primary:hover {
background-color: var(--primary-hover);
}
.btn-primary:disabled {
background-color: #23863680;
cursor: not-allowed;
}
.btn-secondary {
background-color: transparent;
border: 1px solid var(--border-color);
color: var(--text-main);
}
.btn-secondary:hover {
border-color: var(--text-muted);
background-color: rgba(255,255,255,0.05);
}
/* --- GRADIO PREVIEW --- */
.gradio-sim {
border: 2px dashed var(--border-color);
border-radius: var(--radius-lg);
padding: 30px;
text-align: center;
color: var(--text-muted);
position: relative;
background: rgba(255,255,255,0.02);
}
.gradio-active {
border-style: solid;
border-color: var(--accent);
background: rgba(88, 166, 255, 0.05);
color: var(--text-main);
}
.status-badge {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border-radius: 12px;
font-size: 0.75rem;
font-weight: 600;
background: rgba(110, 118, 129, 0.2);
}
.status-running {
background: rgba(46, 160, 67, 0.2);
color: #3fb950;
}
/* --- RESPONSIVE --- */
@media (max-width: 768px) {
.layout {
grid-template-columns: 1fr;
grid-template-rows: auto 1fr;
}
aside {
border-right: none;
border-bottom: 1px solid var(--border-color);
max-height: 300px;
}
}
</style>
</head>
<body>
<header>
<div class="brand">
<i class="ph ph-cube-transparent"></i>
<span>AutoDockerizer</span>
</div>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">
Built with anycoder <i class="ph ph-arrow-up-right"></i>
</a>
</header>
<div class="layout">
<!-- SIDEBAR: CONFIGURATION -->
<aside>
<div class="config-group">
<h3><i class="ph ph-gear"></i> Environment</h3>
<div class="form-control">
<label>Python Version</label>
<select id="pythonVersion">
<option value="3.10">Python 3.10</option>
<option value="3.11" selected>Python 3.11</option>
<option value="3.12">Python 3.12</option>
</select>
</div>
<div class="form-control">
<label>Base Image</label>
<select id="baseImage">
<option value="python/slim">Python Slim</option>
<option value="nvidia/cuda">CUDA (GPU)</option>
<option value="ubuntu">Ubuntu Latest</option>
</select>
</div>
</div>
<div class="config-group">
<h3><i class="ph ph-brackets-curly"></i> Gradio Config</h3>
<div class="form-control">
<label>App Title</label>
<input type="text" id="appTitle" value="My AI Demo">
</div>
<div class="form-control">
<label>Model ID (Hugging Face)</label>
<input type="text" id="modelId" placeholder="e.g. gpt2">
</div>
</div>
<div class="config-group">
<h3><i class="ph ph-sliders"></i> Parameters</h3>
<div class="form-control">
<label>Max Tokens</label>
<div class="range-wrapper">
<input type="range" min="64" max="4096" value="512" id="maxTokens">
<span class="range-value" id="val-maxTokens">512</span>
</div>
</div>
<div class="form-control">
<label>Temperature</label>
<div class="range-wrapper">
<input type="range" min="0" max="1" step="0.1" value="0.7" id="temperature">
<span class="range-value" id="val-temperature">0.7</span>
</div>
</div>
</div>
<div class="config-group">
<h3><i class="ph ph-file-code"></i> Actions</h3>
<button class="btn btn-primary" style="width: 100%" onclick="runDeployment()">
<i class="ph ph-rocket-launch"></i> Build & Deploy
</button>
</div>
</aside>
<!-- MAIN CONTENT -->
<main>
<!-- Dockerfile Preview -->
<section class="card">
<div class="card-header">
<div class="card-title">
<i class="ph ph-docker-logo"></i> Generated Dockerfile
</div>
<div class="status-badge">Auto-generated</div>
</div>
<div class="code-block" id="dockerfileOutput">
<button class="copy-btn" onclick="copyDockerfile()">Copy</button>
<!-- Content injected via JS -->
</div>
</section>
<!-- Terminal & Status -->
<section class="card">
<div class="card-header">
<div class="card-title">
<i class="ph ph-terminal-window"></i> Build Terminal
</div>
<div id="buildStatus" class="status-badge">Waiting for input...</div>
</div>
<div class="terminal" id="terminalOutput">
<div class="log-line"><span class="log-time">[System]</span> Ready to initialize build process.</div>
</div>
</section>
<!-- Gradio Simulation -->
<section class="card">
<div class="card-header">
<div class="card-title">
<i class="ph ph-monitor-play"></i> Gradio Live Preview
</div>
</div>
<div class="gradio-sim" id="gradioPreview">
<i class="ph ph-cloud-arrow-up" style="font-size: 3rem; margin-bottom: 10px; display: block;"></i>
<p>Click "Build & Deploy" to start the container and launch the Gradio interface.</p>
<div style="margin-top: 15px; opacity: 0.5; font-size: 0.8rem;">
Running on http://127.0.0.1:7860
</div>
</div>
</section>
</main>
</div>
<script>
// --- DOM ELEMENTS ---
const inputs = {
python: document.getElementById('pythonVersion'),
base: document.getElementById('baseImage'),
title: document.getElementById('appTitle'),
model: document.getElementById('modelId'),
tokens: document.getElementById('maxTokens'),
temp: document.getElementById('temperature')
};
const displays = {
tokens: document.getElementById('val-maxTokens'),
temp: document.getElementById('val-temperature')
};
const outputs = {
dockerfile: document.getElementById('dockerfileOutput'),
terminal: document.getElementById('terminalOutput'),
status: document.getElementById('buildStatus'),
preview: document.getElementById('gradioPreview')
};
// --- EVENT LISTENERS FOR LIVE UPDATES ---
Object.values(inputs).forEach(input => {
input.addEventListener('input', updateDockerfile);
});
// Update slider values immediately
inputs.tokens.addEventListener('input', (e) => displays.tokens.textContent = e.target.value);
inputs.temp.addEventListener('input', (e) => displays.temp.textContent = e.target.value);
// --- CORE FUNCTIONS ---
function updateDockerfile() {
const pyVer = inputs.python.value;
const base = inputs.base.value;
const title = inputs.title.value || 'My AI Demo';
const model = inputs.model.value || 'gpt2';
// Logic to select appropriate base image string
let fromString = `python:${pyVer}-slim`;
if (base.includes('cuda')) fromString = `nvidia/cuda:11.8.0-runtime-ubuntu${pyVer > 11 ? '22.04' : '20.04'}`;
if (base.includes('ubuntu')) fromString = `ubuntu:latest`;
const dockerfileContent = `# Auto-generated Dockerfile for Gradio App
FROM ${fromString}
# Set working directory
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \\
git \\
git-lfs \\
&& rm -rf /var/lib/apt/lists/*
# Copy requirements file (simulated)
RUN pip install --no-cache-dir -U pip
RUN pip install gradio torch transformers accelerate
# Set environment variables
ENV MODEL_ID="${model}"
ENV MAX_TOKENS=${inputs.tokens.value}
ENV TEMPERATURE=${inputs.temp.value}
APP_TITLE="${title}"
# Copy application code
COPY app.py .
# Expose port
EXPOSE 7860
# Run Gradio app
CMD ["python", "app.py"]
`;
// Preserve the copy button, replace text content
const btn = outputs.dockerfile.querySelector('.copy-btn');
outputs.dockerfile.innerHTML = '';
outputs.dockerfile.appendChild(btn);
outputs.dockerfile.appendChild(document.createTextNode(dockerfileContent));
}
function copyDockerfile() {
const text = outputs.dockerfile.textContent.replace('Copy', '').trim();
navigator.clipboard.writeText(text).then(() => {
const btn = outputs.dockerfile.querySelector('.copy-btn');
const originalText = btn.textContent;
btn.textContent = 'Copied!';
setTimeout(() => btn.textContent = originalText, 2000);
});
}
function addLog(message, type = 'info') {
const line = document.createElement('div');
line.className = 'log-line';
const time = new Date().toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute:'2-digit', second:'2-digit' });
let typeClass = 'log-info';
if(type === 'success') typeClass = 'log-success';
if(type === 'warn') typeClass = 'log-warn';
line.innerHTML = `<span class="log-time">[${time}]</span> <span class="${typeClass}">${message}</span>`;
outputs.terminal.appendChild(line);
outputs.terminal.scrollTop = outputs.terminal.scrollHeight;
}
async function runDeployment() {
// Reset state
outputs.terminal.innerHTML = '';
outputs.status.textContent = 'Building...';
outputs.status.className = 'status-badge';
outputs.preview.classList.remove('gradio-active');
outputs.preview.innerHTML = `
<i class="ph ph-spinner ph-spin" style="font-size: 3rem; margin-bottom: 10px; display: block;"></i>
<p>Initializing Container...</p>
`;
const steps = [
{ msg: "Pulling base image...", delay: 800 },
{ msg: "Installing system dependencies (git, lfs)...", delay: 1500 },
{ msg: "Upgrading pip...", delay: 1000 },
{ msg: "Installing Python packages (gradio, torch)...", delay: 2500 },
{ msg: "Downloading model weights...", delay: 2000 },
{ msg: "Exposing port 7860...", delay: 500 },
{ msg: "Starting Gradio interface...", delay: 800, type: 'success' }
];
for (let step of steps) {
await new Promise(r => setTimeout(r, step.delay));
addLog(step.msg, step.type || 'info');
}
// Final State
outputs.status.textContent = 'Running';
outputs.status.className = 'status-badge status-running';
// Update Preview UI
const title = inputs.title.value;
outputs.preview.classList.add('gradio-active');
outputs.preview.innerHTML = `
<div style="text-align: left; max-width: 600px; margin: 0 auto;">
<h2 style="margin-bottom: 20px; color: var(--accent);">${title}</h2>
<div style="background: var(--bg-input); padding: 15px; border-radius: 8px; border: 1px solid var(--border-color); margin-bottom: 15px;">
<label style="display:block; margin-bottom:5px; font-size:0.8rem;">Input Prompt</label>
<input type="text" placeholder="Type something here..." style="width:100%; background:transparent; border:none; color:white; outline:none;">
</div>
<button class="btn btn-secondary" style="width:100%;">Submit</button>
<div style="margin-top: 20px; padding: 15px; background: rgba(46, 160, 67, 0.1); border: 1px solid var(--primary); border-radius: 8px; color: var(--primary);">
<i class="ph ph-check-circle"></i> Output will appear here.
</div>
</div>
<div style="margin-top: 20px; font-size: 0.8rem; color: var(--text-muted);">
<i class="ph ph-share-network"></i> Public URL: https://huggingface.co/spaces/user/${title.replace(/\s+/g, '-').toLowerCase()}
</div>
`;
addLog("Application successfully deployed.", "success");
}
// Initialize on load
updateDockerfile();
</script>
</body>
</html>