FastAPI_App / app.py
Kr-Adarsh
FastAPI application files for Hugging Face Space deployment
42f12bd
"""
Main FastAPI application for LLM Code Deployment Project
Receives task requests, generates code with LLM, deploys to GitHub, notifies evaluation API
"""
from fastapi import FastAPI, HTTPException, BackgroundTasks
from pydantic import BaseModel
from typing import List, Dict, Optional
import os
from dotenv import load_dotenv
import logging
# Import our custom modules
from llm_generator import generate_app_code, generate_readme
from github_deployer import deploy_to_github
from notifier import notify_evaluation_api
# Load environment variables
load_dotenv()
# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Initialize FastAPI app
app = FastAPI(title="LLM Code Deployment API")
# Pydantic models for request validation
class Attachment(BaseModel):
name: str
url: str # data URI format
class TaskRequest(BaseModel):
email: str
secret: str
task: str
round: int
nonce: str
brief: str
checks: List[str]
evaluation_url: str
attachments: Optional[List[Attachment]] = []
class TaskResponse(BaseModel):
status: str
message: str
# Background task processor
async def process_task(request: TaskRequest):
"""
Background task to process the entire workflow:
1. Generate code with LLM
2. Deploy to GitHub
3. Notify evaluation API
"""
try:
logger.info(f"Processing task: {request.task}, Round: {request.round}")
# Step 1: Generate HTML code and README using LLM
logger.info("Generating code with LLM...")
html_content = generate_app_code(
brief=request.brief,
checks=request.checks,
attachments=request.attachments
)
readme_content = generate_readme(
task_name=request.task,
brief=request.brief,
checks=request.checks
)
logger.info("βœ“ Code generation complete")
# Step 2: Deploy to GitHub
logger.info("Deploying to GitHub...")
repo_url, commit_sha, pages_url = deploy_to_github(
task_name=request.task,
html_content=html_content,
readme_content=readme_content,
round_num=request.round
)
logger.info(f"βœ“ Deployed to GitHub: {repo_url}")
logger.info(f"βœ“ Pages URL: {pages_url}")
# Step 3: Notify evaluation API
logger.info("Notifying evaluation API...")
success = notify_evaluation_api(
evaluation_url=request.evaluation_url,
email=request.email,
task=request.task,
round=request.round,
nonce=request.nonce,
repo_url=repo_url,
commit_sha=commit_sha,
pages_url=pages_url
)
if success:
logger.info("βœ“ Evaluation API notified successfully")
else:
logger.error("βœ— Failed to notify evaluation API")
except Exception as e:
logger.error(f"βœ— Error processing task: {str(e)}")
raise
@app.get("/")
async def root():
"""Health check endpoint"""
return {
"status": "online",
"message": "LLM Code Deployment API is running",
"endpoints": {
"build": "/build (POST)"
}
}
@app.post("/build", response_model=TaskResponse)
async def build_app(request: TaskRequest, background_tasks: BackgroundTasks):
"""
Main endpoint that receives task requests and processes them
Flow:
1. Verify secret
2. Return HTTP 200 immediately
3. Process task in background
"""
# CRITICAL: Verify secret
expected_secret = os.getenv("MY_SECRET")
if request.secret != expected_secret:
logger.warning(f"Invalid secret attempt for task: {request.task}")
raise HTTPException(status_code=401, detail="Invalid secret")
logger.info(f"βœ“ Secret verified for task: {request.task}")
# Add background task to process asynchronously
background_tasks.add_task(process_task, request)
# Return HTTP 200 immediately (as required)
return TaskResponse(
status="accepted",
message=f"Task {request.task} accepted and processing in background"
)
# Run with: uvicorn main:app --reload --port 8000
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)