Skip to content
This repository was archived by the owner on May 19, 2026. It is now read-only.

Commit ea894c5

Browse files
build(backend): manage dependencies with uv and pyproject.toml (#13)
Replace requirements.txt with a uv project (pyproject.toml + uv.lock), following Astral uv Docker guidance: copy the uv binary, sync from the lockfile in a cache-friendly layer, and run the app from .venv. Declare Alembic, psycopg, and redis explicitly; use python -m alembic in the entrypoint. Set tool.uv.package=false for a flat FastAPI app layout. CI runs pytest via uv with --extra dev so production images stay slim; Docker Compose build still validates the image. Add backend/.dockerignore so local .venv is not sent as build context. Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Jakub Doboš <kubo6472@users.noreply.github.com>
1 parent 259251e commit ea894c5

7 files changed

Lines changed: 1268 additions & 24 deletions

File tree

.github/workflows/ci.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,18 @@ jobs:
2323
steps:
2424
- uses: actions/checkout@v4
2525

26+
- uses: astral-sh/setup-uv@v6
27+
with:
28+
version: "0.11.14"
29+
enable-cache: true
30+
cache-dependency-glob: "backend/uv.lock"
31+
32+
- name: Run backend tests
33+
working-directory: backend
34+
run: uv sync --locked --extra dev && uv run pytest
35+
2636
- name: Set up Docker Buildx
2737
uses: docker/setup-buildx-action@v3
2838

2939
- name: Build Compose images
3040
run: docker compose build
31-
32-
- name: Run backend tests (backend image)
33-
run: docker compose run --rm --no-deps backend python -m pytest

AGENTS.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ Copy `.env.example` to `.env` if you want to override defaults locally. Compose
1010

1111
**Backend (from `backend/`)**
1212

13-
- `python3 -m pip install -r requirements.txt` — install dependencies
14-
- `python3 -m pytest` — run tests (vMix tally parsing + rundown engine DB logic)
15-
- `python3 -m uvicorn main:app --reload --host 0.0.0.0 --port 8000` — local API (requires Postgres + Redis + env)
13+
Install [uv](https://docs.astral.sh/uv/) once (see upstream install instructions), then:
14+
15+
- `uv sync --extra dev` — create `.venv` and install dependencies from `uv.lock` (omit `--extra dev` for runtime-only installs)
16+
- `uv run pytest` — run tests (vMix tally parsing + rundown engine DB logic)
17+
- `uv run uvicorn main:app --reload --host 0.0.0.0 --port 8000` — local API (requires Postgres + Redis + env)
18+
19+
After changing dependencies in `pyproject.toml`, run `uv lock` and commit the updated `uv.lock`.
1620

1721
**Database migrations**
1822

19-
- `POSTGRES_URL=... python3 -m alembic upgrade head` — apply migrations (also runs automatically in the backend container entrypoint)
23+
- `POSTGRES_URL=... uv run alembic upgrade head` — apply migrations (also runs automatically in the backend container entrypoint)
2024

2125
**Frontends**
2226

backend/.dockerignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.venv/
2+
__pycache__/
3+
*.py[cod]
4+
.pytest_cache/
5+
.git/

backend/Dockerfile

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,26 @@ FROM python:3.12-slim
22
WORKDIR /app
33
RUN apt-get update && apt-get install -y --no-install-recommends libpq5 \
44
&& rm -rf /var/lib/apt/lists/*
5-
COPY requirements.txt .
6-
RUN pip install --no-cache-dir -r requirements.txt
7-
RUN addgroup --system app && adduser --system --ingroup app app
5+
6+
COPY --from=ghcr.io/astral-sh/uv:0.11.14 /uv /uvx /bin/
7+
8+
ENV UV_COMPILE_BYTECODE=1 \
9+
UV_LINK_MODE=copy \
10+
UV_PYTHON_DOWNLOADS=0
11+
12+
RUN --mount=type=cache,target=/root/.cache/uv \
13+
--mount=type=bind,source=uv.lock,target=uv.lock \
14+
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
15+
uv sync --locked
16+
817
COPY . .
9-
RUN chmod +x /app/entrypoint.sh && chown -R app:app /app
10-
ENV PYTHONUNBUFFERED=1
18+
RUN chmod +x /app/entrypoint.sh \
19+
&& addgroup --system app && adduser --system --ingroup app app \
20+
&& chown -R app:app /app
21+
22+
ENV PATH="/app/.venv/bin:$PATH" \
23+
VIRTUAL_ENV=/app/.venv \
24+
PYTHONUNBUFFERED=1
1125
EXPOSE 8000
1226
USER app
1327
CMD ["/app/entrypoint.sh"]

backend/pyproject.toml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
[project]
2+
name = "duopus-backend"
3+
version = "0.1.0"
4+
description = "Duopus NRCS FastAPI backend"
5+
requires-python = ">=3.12"
6+
dependencies = [
7+
"fastapi>=0.115.0",
8+
"uvicorn[standard]>=0.32.0",
9+
"alembic>=1.13.0",
10+
"psycopg[binary]>=3.2.0",
11+
"sqlmodel>=0.0.22",
12+
"aiosqlite>=0.20.0",
13+
"fastapi-users>=14.0.0",
14+
"fastapi-users-db-sqlalchemy>=7.0.0",
15+
"python-multipart>=0.0.9",
16+
"python-dotenv>=1.0.0",
17+
"redis>=5.0.0",
18+
]
19+
20+
[project.optional-dependencies]
21+
dev = [
22+
"pytest>=8.3.0",
23+
"pytest-asyncio>=0.24.0",
24+
]
25+
26+
[tool.uv]
27+
package = false
28+
29+
[tool.pytest.ini_options]
30+
pythonpath = ["."]
31+
asyncio_mode = "auto"
32+
asyncio_default_fixture_loop_scope = "function"

backend/requirements.txt

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)