Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.git
.github
.venv
venv
__pycache__
*.pyc
*.pyo
.pytest_cache
.mypy_cache
.ruff_cache
.coverage
htmlcov
tests
docs
.claude
build
*.db
*.sqlite
.env
.env.*
!.env.example
README.md
docker-compose.yml
23 changes: 22 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
SECRET_KEY=""
# --- App ---
APP_NAME="FastAPI Boilerplate"
ENVIRONMENT=development # development | staging | production
DEBUG=true # never true in production

# --- Database ---
# Production: postgresql+asyncpg://user:pass@host:5432/dbname
# Local/dev/test (no server required): sqlite+aiosqlite:///./dev.db
DATABASE_URL=sqlite+aiosqlite:///./dev.db

# --- Auth / JWT ---
SECRET_KEY=change-me-to-a-random-64-char-string # openssl rand -hex 32
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=14

# --- CORS ---
CORS_ORIGINS=["http://localhost:3000"] # explicit allowlist, never "*" in production

# --- Rate limiting ---
RATE_LIMIT_DEFAULT="100/minute"
RATE_LIMIT_AUTH="5/minute"
62 changes: 62 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

env:
PYTHON_VERSION: "3.11"
# CI-only dummy values — never real secrets.
SECRET_KEY: "ci-only-dummy-secret-do-not-use-in-prod-00000000"
DATABASE_URL: "postgresql+asyncpg://app:app@localhost:5432/appdb"

jobs:
build-test:
name: Lint, type-check, test, build
runs-on: ubuntu-latest

services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: app
POSTGRES_PASSWORD: app
POSTGRES_DB: appdb
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U app -d appdb"
--health-interval 5s
--health-timeout 5s
--health-retries 10

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: "pip"
cache-dependency-path: requirements-dev.txt

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt

- name: Lint (ruff)
run: ruff check .

- name: Type-check (mypy)
run: mypy app --ignore-missing-imports

- name: Run migrations
run: alembic upgrade head

- name: Test with coverage (>=70% gate)
run: pytest --cov=app --cov-report=term-missing --cov-fail-under=70

- name: Build Docker image
run: docker build -t fastapi-initializer .
45 changes: 40 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
venv
# Python cache files
__pycache__/
.pytest_cache/
.mypy_cache/
.ruff_cache/
*.pyc
*.egg-info/
*.pyo

# python virtual environments
.venv/
venv/
.virtualenv/
virtualenv/

# Environment variables
.env
__pycache__
.env.*
!.env.example

#database files
instance/
*.sqlite
*.db

.python-version
.coverage
.coverage.*
htmlcov/

branch_structure.json
temp_auto_push.bat
temp_interactive_push.bat
.gitignore
*.bat

# Logs
logs/
*.log

# Internal artifacts
docs/superpowers/
CLAUDE.md
.claude/
build/
7 changes: 0 additions & 7 deletions .vscode/extensions.json

This file was deleted.

50 changes: 0 additions & 50 deletions .vscode/launch.json

This file was deleted.

23 changes: 0 additions & 23 deletions .vscode/settings.json

This file was deleted.

2 changes: 0 additions & 2 deletions .vscode/spellright.dict

This file was deleted.

33 changes: 0 additions & 33 deletions .vscode/tasks.json

This file was deleted.

25 changes: 25 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM python:3.11-slim

# Don't buffer stdout/stderr; no .pyc files in the image.
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1

WORKDIR /app

# Install dependencies first (layer-cache friendly — only busts when requirements change).
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application source + migrations.
COPY app/ app/
COPY alembic/ alembic/
COPY alembic.ini .

# Run as a non-root user.
RUN adduser --disabled-password --gecos "" appuser
USER appuser

EXPOSE 8000

# PORT is injected by most managed platforms (Render, Railway, Fly) at runtime.
CMD ["sh", "-c", "uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-8000}"]
Loading
Loading