adrija93 commited on
Commit
8902ef0
·
verified ·
1 Parent(s): d444a43

Upload project files

Browse files
Files changed (3) hide show
  1. Dockerfile +35 -0
  2. README.md +109 -12
  3. requirements.txt +14 -0
Dockerfile ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use a slim Python base image
2
+ FROM python:3.12-slim
3
+
4
+ ENV PYTHONDONTWRITEBYTECODE=1 \
5
+ PYTHONUNBUFFERED=1
6
+
7
+ # Create non-root user (optional but good practice)
8
+ RUN useradd -m -u 1000 appuser
9
+ WORKDIR /app
10
+
11
+ # System deps (kept minimal since psycopg2-binary is used)
12
+ RUN apt-get update && apt-get install -y --no-install-recommends \
13
+ curl ca-certificates && \
14
+ rm -rf /var/lib/apt/lists/*
15
+
16
+ # Install Python deps first (better layer caching)
17
+ COPY requirements.txt ./
18
+ RUN pip install --no-cache-dir -r requirements.txt
19
+
20
+ # Copy application code
21
+ COPY app ./app
22
+ COPY README.md ./
23
+
24
+ # Ensure the non-root user can write to /app (for ./data sqlite, logs, etc.)
25
+ RUN chown -R appuser:appuser /app
26
+
27
+ # Hugging Face Spaces exposes $PORT; default to 7860 if not set
28
+ ENV PORT=7860
29
+ EXPOSE 7860
30
+
31
+ # Ensure we run as non-root
32
+ USER appuser
33
+
34
+ SHELL ["/bin/bash", "-lc"]
35
+ CMD uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-7860}
README.md CHANGED
@@ -1,12 +1,109 @@
1
- ---
2
- title: TDS Project1 API
3
- emoji: 📉
4
- colorFrom: blue
5
- colorTo: yellow
6
- sdk: docker
7
- pinned: false
8
- license: mit
9
- short_description: FastAPI service to generate static, minimal GitHub repos
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # LLM Code Deployment Builder (FastAPI + GitHub Pages)
2
+
3
+ A FastAPI service that:
4
+ - In round 1: generates a minimal static app with an LLM, creates a GitHub repo, sets up Pages on the `gh-pages` branch, deploys, then notifies the evaluation URL.
5
+ - In round 2: fetches current repo files, requests minimal changes from the LLM, updates the repo, waits for Pages to be live again, then notifies the evaluation URL.
6
+
7
+ Built for IITM BS Tools in Data Science course. Uses an OpenAI-compatible endpoint (e.g., AIpipe) for LLM calls and PyGithub for GitHub automation.
8
+
9
+ ## Requirements
10
+
11
+ - Python 3.10+
12
+ - A GitHub personal access token with repo scopes
13
+ - An OpenAI-compatible LLM endpoint and API key (AIpipe or similar)
14
+
15
+ ## Setup
16
+
17
+ 1) Create a virtual environment and install deps
18
+
19
+ - Using pip and `requirements.txt`:
20
+ - python -m venv .venv && source .venv/bin/activate
21
+ - pip install -r requirements.txt
22
+
23
+ 2) Copy `.env.example` to `.env` and fill values
24
+
25
+ 3) Run the server
26
+
27
+ - or: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
28
+
29
+ ## Configuration
30
+
31
+ Required environment variables:
32
+ - APP_SECRET: Shared secret required in requests
33
+ - GITHUB_TOKEN: GitHub token with repo permissions
34
+ - GITHUB_USERNAME: Your GitHub username
35
+ - GITHUB_EMAIL: Email used for commits
36
+ - OPENAI_API_KEY: LLM provider API key (e.g., AIpipe token)
37
+
38
+ Recommended/Optional:
39
+ - OPENAI_BASE_URL: OpenAI-compatible base URL (default: https://aipipe.org/openai/v1)
40
+ - AIPIPE_MODEL: Model ID (default: qwen/qwen3-coder-30b-a3b-instruct)
41
+ - APP_DB_PATH: Override path for local SQLite file (default: ./data/state.db)
42
+
43
+ See `.env.example` for a complete template.
44
+
45
+ ## API
46
+
47
+ ### POST /tasks
48
+
49
+ Accepts a task request for either round 1 (initial build) or round 2 (revision).
50
+
51
+ Request schema (simplified):
52
+ - email: string
53
+ - secret: string (must match APP_SECRET)
54
+ - task: string (task name; used to key round-2 revisions)
55
+ - round: 1 or 2
56
+ - nonce: unique string per request
57
+ - brief: short description of what to build/change
58
+ - checks: list of acceptance checks
59
+ - evaluation_url: URL to notify upon completion
60
+ - attachments: optional list of { name, url } where url may be a data: URI or https URL
61
+
62
+ Immediate response (always returned right away if inputs are valid):
63
+ - { status: "accepted", task, round, message }
64
+
65
+ Background processing then:
66
+ - Round 1: Generates files, creates repo, configures GitHub Pages (gh-pages), waits for 200 OK, then POSTs to evaluation_url with {status, task, round, nonce, repo_url, commit_sha, pages_url}.
67
+ - Round 2: Verifies a prior repo exists for the same task, fetches current files, requests minimal changes, updates repo, waits for Pages 200 OK, then POSTs to evaluation_url with the same payload.
68
+
69
+ Important behaviors:
70
+ - Evaluation notify requires a strict 200 OK; redirects are followed.
71
+ - Pages readiness is polled until 200 OK or timeout, using internal defaults (no env required).
72
+ - For round 2, the HTTP 200 response from this service is returned immediately after validating the secret and the existence of a prior round-1 repo for the task; all network work runs in the background.
73
+
74
+ ### GET /healthz
75
+
76
+ Returns {"status": "ok"} for simple liveness checks.
77
+
78
+ ## How it works
79
+
80
+ - LLM: Uses an OpenAI-compatible API. Prompts enforce an “attachment handling contract” ensuring data: URIs and base64 content aren’t truncated or modified.
81
+ - GitHub: Creates a repo, commits workflow and files to `main`, deploys to `gh-pages` via JamesIves/github-pages-deploy-action. Pages is configured to `gh-pages` before the first content push to reduce noisy “Pages failed for main” entries.
82
+ - Persistence: Stores task→repo mapping in local SQLite so the app can survive restarts (e.g., on Hugging Face Spaces).
83
+ - Notifications: Exponential backoff with strict 200 OK requirement; redirects followed.
84
+
85
+ ## Deploying on Hugging Face Spaces (Docker)
86
+
87
+ This repo includes a `Dockerfile` for Spaces (type: Docker).
88
+
89
+ 1) Create the Space and add Secrets (see `.env.example`).
90
+
91
+ 2) Push this repo to the Space; the app will bind to the provided `PORT`.
92
+
93
+ 3) Health check: GET /healthz
94
+
95
+ Notes:
96
+ - Ensure outbound internet is allowed to reach GitHub and the LLM provider.
97
+ - Keep generation modest; Pages can take time to turn green.
98
+
99
+ ## Troubleshooting
100
+
101
+ - Invalid secret: The service returns HTTP 400.
102
+ - Round 2 without round 1: The service returns HTTP 400 indicating no prior repo for the task.
103
+ - Pages never reaches 200 OK: Verify GitHub Pages is configured to the `gh-pages` branch and the action ran successfully. Check repo Settings → Pages.
104
+ - Evaluation URL not accepting: The notifier retries with backoff and follows redirects, but requires a final 200 OK.
105
+ - Data URLs truncated or modified: Prompts include an attachment handling contract; ensure your inputs use proper data: URIs or https links.
106
+
107
+ ## License
108
+
109
+ MIT
requirements.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn[standard]
3
+ pydantic
4
+ pydantic-settings
5
+ httpx
6
+ tenacity
7
+ sqlalchemy
8
+ psycopg2-binary
9
+ PyGithub
10
+ python-dotenv
11
+ pytest
12
+ pytest-asyncio
13
+ ruff
14
+ mypy