"""
Orchestrate full repository generation by delegating to SDK-specific generators.
"""
from app.codegen.gradio_generator import GradioGenerator
from app.codegen.docker_generator import DockerGenerator
from app.codegen.readme_generator import ReadmeGenerator
STATIC_TEMPLATE = """
{title}
Projects
Project Alpha
A cutting-edge machine learning project that pushes the boundaries of what's possible.
Project Beta
An innovative data pipeline that processes millions of records in real-time.
Project Gamma
A beautiful visualization dashboard that makes complex data accessible.
Skills
Python
Machine Learning
Deep Learning
NLP
Computer Vision
Data Science
FastAPI
Docker
"""
class RepoGenerator:
"""Orchestrate full repo generation for any SDK type."""
def __init__(self):
self.gradio_gen = GradioGenerator()
self.docker_gen = DockerGenerator()
self.readme_gen = ReadmeGenerator()
def generate(self, plan: dict, prompt: str) -> dict:
"""
Generate all files for a complete HF Space repo.
Returns dict of {filepath: content}.
"""
sdk = plan.get("sdk", "gradio")
if sdk == "gradio":
return self._generate_gradio_repo(plan, prompt)
elif sdk == "docker":
return self._generate_docker_repo(plan, prompt)
else:
return self._generate_static_repo(plan, prompt)
def _generate_gradio_repo(self, plan: dict, prompt: str) -> dict:
"""Generate a complete Gradio Space repo."""
files = {}
# README.md
files["README.md"] = self.readme_gen.generate(plan, "gradio")
# app.py - the main Gradio application
files["app.py"] = self.gradio_gen.generate(plan, prompt)
# requirements.txt
files["requirements.txt"] = self._gradio_requirements(plan)
# .gitignore
files[".gitignore"] = self._gitignore()
return files
def _generate_docker_repo(self, plan: dict, prompt: str) -> dict:
"""Generate a complete Docker Space repo."""
# Get docker-specific files from the generator
docker_files = self.docker_gen.generate(plan, prompt)
files = {}
# README.md (always generate our own)
files["README.md"] = self.readme_gen.generate(plan, "docker")
# Merge docker-generated files
for name, content in docker_files.items():
files[name] = content
# .gitignore
files[".gitignore"] = self._gitignore()
return files
def _generate_static_repo(self, plan: dict, prompt: str) -> dict:
"""Generate a complete Static Space repo."""
title = plan.get("title", "My Site")
description = plan.get("description", "A static website")
files = {}
# README.md
files["README.md"] = self.readme_gen.generate(plan, "static")
# index.html
files["index.html"] = STATIC_TEMPLATE.format(
title=title,
description=description,
)
# style.css (additional styles)
files["style.css"] = """/* Additional custom styles */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');
body {
font-family: 'Inter', system-ui, sans-serif;
}
/* Smooth scrolling */
html {
scroll-behavior: smooth;
}
/* Animated gradient background */
@keyframes gradient-shift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.hero {
background-size: 200% 200%;
animation: gradient-shift 8s ease infinite;
}
/* Fade-in animation */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.card {
animation: fadeInUp 0.5s ease forwards;
}
"""
files[".gitignore"] = self._gitignore()
return files
def _gradio_requirements(self, plan: dict) -> str:
"""Generate requirements.txt for Gradio apps."""
deps = [
"gradio>=5.9.1",
"huggingface-hub>=0.27.1",
]
# Add task-specific dependencies
task = plan.get("model_task", "")
if task in ("text-to-image", "image-classification", "object-detection"):
deps.append("Pillow>=10.0.0")
if "chart_output" in plan.get("components", []):
deps.append("matplotlib>=3.8.0")
deps.append("numpy>=1.26.0")
return "\n".join(deps) + "\n"
def _gitignore(self) -> str:
return """__pycache__/
*.py[cod]
*$py.class
*.egg-info/
dist/
build/
.env
.venv/
venv/
.DS_Store
*.log
"""
def edit(self, plan: dict, current_files: dict, edit_prompt: str) -> dict:
"""Edit an existing repo based on user instructions."""
sdk = plan.get("sdk", "gradio")
updated = dict(current_files)
if sdk == "gradio" and "app.py" in current_files:
updated["app.py"] = self.gradio_gen.edit(plan, current_files["app.py"], edit_prompt)
elif sdk == "docker":
docker_updated = self.docker_gen.edit(plan, current_files, edit_prompt)
updated.update(docker_updated)
# Static sites: for now return unchanged (could add LLM-based HTML editing)
return updated