Skip to content

Commit 7fd1fbe

Browse files
committed
Initial FastAPI hello-world app with uv + Docker
0 parents  commit 7fd1fbe

8 files changed

Lines changed: 601 additions & 0 deletions

File tree

.dockerignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
__pycache__
2+
*.pyc
3+
*.pyo
4+
.venv
5+
venv
6+
.env
7+
.git
8+
.gitignore
9+
.DS_Store
10+
.python-version
11+
.claude

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Python-generated files
2+
__pycache__/
3+
*.py[oc]
4+
build/
5+
dist/
6+
wheels/
7+
*.egg-info
8+
9+
# Virtual environments
10+
.venv
11+
12+
# Editor / tool state
13+
.claude/
14+
.DS_Store

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.13

Dockerfile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
FROM python:3.13-slim
2+
3+
COPY --from=ghcr.io/astral-sh/uv:0.5.11 /uv /uvx /bin/
4+
5+
ENV PYTHONUNBUFFERED=1 \
6+
PYTHONDONTWRITEBYTECODE=1 \
7+
UV_COMPILE_BYTECODE=1 \
8+
UV_LINK_MODE=copy \
9+
UV_PROJECT_ENVIRONMENT=/app/.venv \
10+
PATH="/app/.venv/bin:$PATH" \
11+
PORT=8080
12+
13+
WORKDIR /app
14+
15+
COPY pyproject.toml uv.lock ./
16+
RUN uv sync --frozen --no-install-project --no-dev
17+
18+
COPY main.py ./
19+
20+
EXPOSE 8080
21+
22+
CMD exec uvicorn main:app --host 0.0.0.0 --port ${PORT}

README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# fastapi-basic
2+
3+
A minimal FastAPI "Hello, World!" service, managed with [uv](https://docs.astral.sh/uv/).
4+
5+
This `main` branch contains only the app and local dev setup. Deployment is demonstrated on two separate branches:
6+
7+
- **[`deploy-script`](../../tree/deploy-script)** — deploy with a local `gcloud` script ([deploy.sh](deploy.sh)).
8+
- **[`deploy-github`](../../tree/deploy-github)** — deploy from GitHub via a GitHub Actions workflow.
9+
10+
## Stack
11+
12+
- Python 3.13
13+
- FastAPI + Uvicorn (standard)
14+
- uv for dependency / venv management
15+
- Docker (python:3.13-slim + uv binary from `ghcr.io/astral-sh/uv`)
16+
17+
## Project layout
18+
19+
```
20+
.
21+
├── main.py # FastAPI app (/, /healthz)
22+
├── pyproject.toml # project metadata + deps
23+
├── uv.lock # locked dependency graph
24+
├── .python-version # pins Python 3.13 for uv
25+
├── Dockerfile # uv-based container build
26+
└── .dockerignore
27+
```
28+
29+
## Endpoints
30+
31+
| Method | Path | Response |
32+
| ------ | ----------- | ------------------------------ |
33+
| GET | `/` | `{"message": "Hello, World!"}` |
34+
| GET | `/healthz` | `{"status": "ok"}` |
35+
| GET | `/docs` | Swagger UI |
36+
| GET | `/redoc` | ReDoc UI |
37+
38+
## Prerequisites
39+
40+
- [uv](https://docs.astral.sh/uv/getting-started/installation/) (`brew install uv`)
41+
- Docker (only if you want to build/run the container locally)
42+
43+
## Local development
44+
45+
```bash
46+
uv sync
47+
uv run uvicorn main:app --reload --port 8080
48+
```
49+
50+
Then:
51+
52+
```bash
53+
curl http://localhost:8080/
54+
curl http://localhost:8080/healthz
55+
open http://localhost:8080/docs
56+
```
57+
58+
### Managing dependencies
59+
60+
```bash
61+
uv add <package> # add a runtime dep
62+
uv add --dev <package> # add a dev-only dep
63+
uv remove <package> # remove a dep
64+
uv lock --upgrade # refresh uv.lock
65+
```
66+
67+
## Run with Docker
68+
69+
```bash
70+
docker build -t fastapi-basic .
71+
docker run --rm -p 8080:8080 fastapi-basic
72+
```
73+
74+
The image installs deps with `uv sync --frozen --no-dev` against `uv.lock`, so the container matches local exactly.
75+
76+
## Deploying
77+
78+
Check out one of the deploy branches:
79+
80+
```bash
81+
git checkout deploy-script # local gcloud-based deploy
82+
# or
83+
git checkout deploy-github # GitHub Actions deploy
84+
```

main.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import os
2+
3+
from fastapi import FastAPI
4+
5+
app = FastAPI()
6+
7+
8+
@app.get("/")
9+
def read_root():
10+
return {"message": "Hello, World!"}
11+
12+
13+
@app.get("/healthz")
14+
def healthz():
15+
return {"status": "ok"}
16+
17+
18+
if __name__ == "__main__":
19+
import uvicorn
20+
21+
uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

pyproject.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[project]
2+
name = "fastapi-basic"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
requires-python = ">=3.13"
6+
dependencies = [
7+
"fastapi>=0.136.3",
8+
"uvicorn[standard]>=0.49.0",
9+
]

uv.lock

Lines changed: 439 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)