FastAPI
✨ How to use: Copy this entire spec and paste it into your AI assistant (Claude, ChatGPT, etc.) when asking it to prepare your project for Niblit.ai deployment.
# Niblit.ai Deployment Spec: Python + FastAPI
You are deploying a Python FastAPI application to Niblit.ai.
Follow these instructions EXACTLY. Do not deviate.
## Requirements
- Python 3.11 or 3.12
- FastAPI as the web framework
- Uvicorn as the ASGI server
- SQLite for any database needs (no Postgres, no MySQL)
- App must listen on port 8080
- All persistent data must be stored in /data/ directory
## Required Project Structure
```
your-project/
├── Dockerfile ← REQUIRED (use the template below exactly)
├── requirements.txt ← REQUIRED (must include fastapi and uvicorn)
├── main.py ← REQUIRED (your FastAPI application entry point)
└── ... other files
```
## Dockerfile (use this EXACTLY)
```dockerfile
FROM python:3.12-slim
WORKDIR /app
# Install dependencies first (better caching)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Create data directory for persistent storage
RUN mkdir -p /data
# Environment variables
ENV PORT=8080
ENV DATABASE_PATH=/data/app.db
EXPOSE 8080
# Run with uvicorn for production
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]
```
## requirements.txt must include
```
fastapi
uvicorn[standard]
```
Add any other dependencies your app needs.
## FastAPI App Structure (main.py)
Your main.py MUST have a FastAPI app instance named `app` at the module level:
```python
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def home():
return {"message": "Hello from Niblit.ai!"}
@app.get("/health")
def health():
return {"status": "ok"}
```
## Database Rules
- Use SQLite ONLY
- Database file MUST be stored at: `/data/app.db`
- The /data directory is persistent storage — it survives restarts and redeploys
- Everything outside /data is ephemeral and will be reset on redeploy
Example database setup with SQLite:
```python
import os
import sqlite3
from contextlib import contextmanager
DATABASE_PATH = os.environ.get('DATABASE_PATH', '/data/app.db')
@contextmanager
def get_db():
conn = sqlite3.connect(DATABASE_PATH)
conn.row_factory = sqlite3.Row
try:
yield conn
finally:
conn.close()
def init_db():
with get_db() as db:
db.execute('''
CREATE TABLE IF NOT EXISTS items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
db.commit()
# Call init_db() on startup
@app.on_event("startup")
def startup():
init_db()
```
## Serving Static Files
If you need to serve static files (HTML, CSS, JS):
```python
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse
# Mount static files directory
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/", response_class=HTMLResponse)
def home():
with open("static/index.html") as f:
return f.read()
```
## File Storage
If your app handles file uploads:
- Store files in `/data/uploads/`
- Create the directory if it doesn't exist
```python
import os
from fastapi import UploadFile
UPLOAD_FOLDER = '/data/uploads'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
@app.post("/upload")
async def upload_file(file: UploadFile):
path = os.path.join(UPLOAD_FOLDER, file.filename)
with open(path, "wb") as f:
f.write(await file.read())
return {"filename": file.filename}
```
## Environment Variables
These are available to your app:
- `PORT` - Always 8080
- `DATABASE_PATH` - Path to SQLite database (/data/app.db)
## What NOT to Include
- No `.env` files (will be rejected)
- No `node_modules/` directory
- No `__pycache__/` directories
- No `.git/` directory
- No `venv/` or `.venv/` directories
- No secret keys or API tokens in code
- No external database connections
## Testing Locally Before Upload
1. Build and run with Docker:
```bash
docker build -t my-app .
docker run -p 8080:8080 -v $(pwd)/data:/data my-app
```
2. Visit http://localhost:8080
3. Check the API docs at http://localhost:8080/docs
4. If it works, create the zip and upload to Niblit.ai.
## Creating the Upload Zip
```bash
# From your project root:
zip -r my-app.zip . -x "*.git*" -x "__pycache__/*" -x "*.pyc" -x ".env" -x "venv/*" -x ".venv/*" -x "data/*"
```
## Common Errors and Fixes
| Error | Fix |
|-------|-----|
| "Missing Dockerfile" | Add Dockerfile using template above |
| "Port mismatch" | Ensure Dockerfile has `EXPOSE 8080` and uvicorn uses port 8080 |
| "Missing requirements.txt" | Create file with fastapi and uvicorn[standard] |
| "Database not persisting" | Store DB at `/data/app.db`, not `./app.db` |
| "App crashes on start" | Ensure main.py has `app = FastAPI()` at module level |
| "uvicorn not found" | Add `uvicorn[standard]` to requirements.txt |
## Resource Limits
- **Free tier**: 256MB RAM, shared CPU, 1GB storage
- **Pro tier**: 512MB RAM, shared CPU, 1GB storage
- **Team tier**: 1GB RAM, 2 shared CPUs, 5GB storage
Free tier apps sleep after 5 minutes of no traffic and wake automatically (3-5 second cold start).
## Example App
See the `example/` directory for a complete working example.