sapcedeploy / app /routes.py
Leeflour's picture
Upload folder using huggingface_hub
b7bd3ec verified
from fastapi import BackgroundTasks, FastAPI, HTTPException, Depends, Request, Form
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi.middleware.gzip import GZipMiddleware
import uuid
from app.models import DeployRequest, DeployStatus
from app.store import TaskStore
from app.deploy import deploy_space, SpaceDeployError
from app.auth import require_api_key
app = FastAPI(title="HF Space Deployer", version="1.0.0")
# Static files and templates
app.mount("/static", StaticFiles(directory="app/static"), name="static")
app.add_middleware(GZipMiddleware)
templates = Jinja2Templates(directory="app/templates")
# Web Interface Routes
@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
@app.post("/web/deploy")
async def web_deploy(
request: Request,
hf_token: str = Form(...),
git_repo_url: str = Form(...),
space_name: str = Form(...),
description: str = Form(""),
space_port: int = Form(7860),
private: bool = Form(False),
env_vars_text: str = Form(""),
deploy_path: str = Form("/"),
bg: BackgroundTasks = BackgroundTasks()
):
# Parse environment variables from textarea
env_vars = {}
if env_vars_text.strip():
for line in env_vars_text.strip().split('\n'):
if '=' in line:
key, value = line.split('=', 1)
env_vars[key.strip()] = value.strip()
deploy_req = DeployRequest(
hf_token=hf_token,
git_repo_url=git_repo_url,
space_name=space_name,
description=description,
space_port=space_port,
private=private,
env_vars=env_vars,
deploy_path=deploy_path
)
task_id = str(uuid.uuid4())
TaskStore.save(DeployStatus(task_id=task_id, status="PENDING"))
bg.add_task(_run_task, task_id, deploy_req)
# Redirect to status page instead of returning HTML
return RedirectResponse(url=f"/deploy/{task_id}", status_code=303)
@app.get("/deploy/{task_id}", response_class=HTMLResponse)
async def deploy_status_page(request: Request, task_id: str):
status = TaskStore.load(task_id)
if not status:
raise HTTPException(status_code=404, detail="Task not found")
return templates.TemplateResponse("deploy_status.html", {
"request": request,
"task_id": task_id,
"status": status.status
})
# API Routes
@app.post("/deploy", response_model=DeployStatus, status_code=202)
async def deploy(req: DeployRequest, bg: BackgroundTasks):
task_id = str(uuid.uuid4())
TaskStore.save(DeployStatus(task_id=task_id, status="PENDING"))
bg.add_task(_run_task, task_id, req)
return TaskStore.load(task_id)
@app.get("/deploy/status/{task_id}", response_model=DeployStatus)
async def status(task_id: str):
status = TaskStore.load(task_id)
if not status:
raise HTTPException(status_code=404, detail="Task not found")
return status
# ------------------------------------------------------------------ #
def _run_task(task_id: str, req: DeployRequest):
TaskStore.save(DeployStatus(task_id=task_id, status="IN_PROGRESS"))
try:
url = deploy_space(**req.dict())
TaskStore.save(DeployStatus(task_id=task_id, status="SUCCESS", detail={"space_url": url}))
except SpaceDeployError as exc:
TaskStore.save(DeployStatus(task_id=task_id, status="FAILED", detail={"error": str(exc)}))