Skip to content

Commit 26ae5fc

Browse files
authored
feat: migrate from poetry to uv (#377)
1 parent 0720cc9 commit 26ae5fc

File tree

16 files changed

+1182
-1136
lines changed

16 files changed

+1182
-1136
lines changed

.github/workflows/analysis.yml

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -102,29 +102,23 @@ jobs:
102102
with:
103103
python-version: "3.13"
104104

105-
- name: cache poetry install
106-
uses: actions/cache@v4
107-
with:
108-
path: ~/.local
109-
key: poetry-${{ hashFiles('**/pyproject.toml') }}
105+
- name: Install UV
106+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
110107

111-
- uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a # v1.4.1
112-
with:
113-
version: 1.2.2
114-
virtualenvs-create: true
115-
virtualenvs-in-project: true
116-
installer-parallel: true
108+
- name: Add UV to PATH
109+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
117110

118-
- id: cache-deps
111+
- name: Cache UV dependencies
119112
uses: actions/cache@v4
120113
with:
121114
path: .venv
122-
key: pydeps-${{ hashFiles('**/poetry.lock') }}
115+
key: uv-${{ hashFiles('**/uv.lock') }}
123116

124-
- run: poetry install --no-interaction --no-root
125-
if: steps.cache-deps.outputs.cache-hit != 'true'
117+
- name: Install dependencies
118+
run: uv sync --group dev
126119

127-
- run: poetry run pytest
120+
- name: Run tests
121+
run: uv run pytest
128122

129123
results:
130124
name: Analysis Results

backend-py/Dockerfile

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,59 @@
1-
FROM python:3.13.7 AS build
1+
# Use the official Python image with UV pre-installed
2+
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS build
23

3-
# Disable cache dir, disable upgrade message, create .venv in project dir
4-
ARG PIP_NO_CACHE_DIR=off \
5-
PIP_DISABLE_PIP_VERSION_CHECK=on \
6-
POETRY_VIRTUALENVS_IN_PROJECT=1
4+
# Set environment variables for UV
5+
ENV UV_COMPILE_BYTECODE=1 \
6+
UV_LINK_MODE=copy \
7+
UV_PYTHON_DOWNLOADS=never
78

8-
# Install poetry, then dependencies
9+
# Install system dependencies
10+
RUN apt-get update && \
11+
apt-get install -y --no-install-recommends libpq-dev && \
12+
rm -rf /var/lib/apt/lists/*
13+
14+
# Set working directory
915
WORKDIR /app
10-
COPY pyproject.toml poetry.lock ./
11-
RUN pip install poetry==1.6.1
12-
RUN poetry install --no-root -vvv --without dev --sync
1316

14-
# Deploy
15-
FROM python:3.13.7-slim AS deploy
17+
# Copy dependency files
18+
COPY pyproject.toml uv.lock ./
19+
20+
# Install dependencies
21+
RUN uv sync --frozen --no-install-project --no-dev
22+
23+
# Copy source code
24+
COPY src ./src
1625

17-
# Output to stdout/stderr, don't create .pyc files, etc.
26+
# Install the project
27+
RUN uv sync --frozen --no-dev
28+
29+
# Production stage
30+
FROM python:3.13.7-slim-bookworm AS deploy
31+
32+
# Set environment variables
1833
ENV PYTHONUNBUFFERED=1 \
1934
PYTHONDONTWRITEBYTECODE=1 \
2035
PATH="/app/.venv/bin:$PATH" \
21-
PORT=3000
36+
PORT=3000 \
37+
LOG_LEVEL=INFO \
38+
ENVIRONMENT=production
2239

23-
# Packages
24-
RUN apt update && \
25-
apt install -y --no-install-recommends libpq-dev
40+
# Install runtime dependencies
41+
RUN apt-get update && \
42+
apt-get install -y --no-install-recommends libpq-dev && \
43+
rm -rf /var/lib/apt/lists/*
2644

27-
# Dependencies, config and app
45+
# Copy virtual environment and application
2846
COPY --from=build /app/.venv /app/.venv
29-
COPY logger.conf ./
30-
COPY ./src ./src
47+
COPY --from=build /app/src ./src
48+
COPY start-server.sh ./
49+
50+
# Make the script executable
51+
RUN chmod +x start-server.sh
3152

53+
# Health check
3254
HEALTHCHECK --interval=300s --timeout=10s CMD timeout 10s sh -c 'true > http://localhost:${PORT} || exit 1'
3355

34-
# Start with non-privileged user
56+
# Run as non-privileged user
3557
USER 1001
3658
SHELL ["/bin/bash", "-c"]
37-
ENTRYPOINT uvicorn src.main:app --host 0.0.0.0 --port ${PORT} --workers 1 --server-header --date-header --limit-concurrency 1000 --log-config ./logger.conf
59+
CMD ["./start-server.sh"]

backend-py/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
### Features
33
- [x] FastAPI
44
- [x] SQLAlchemy
5-
- [x] Poetry
5+
- [x] UV Package Manager
66
- [x] Ruff
77
- [x] Flyway
88
- [x] Docker

backend-py/generate-models.sh

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ set -eu
44
# Change to script dir
55
cd $(dirname ${BASH_SOURCE[0]})
66

7-
# setup
8-
python3 -m venv venv-py
9-
source venv-py/bin/activate
10-
pip install --upgrade pip
11-
pip install sqlalchemy sqlacodegen psycopg2-binary sqlacodegen[citext]
7+
# Install UV if not available
8+
if ! command -v uv &> /dev/null; then
9+
curl -LsSf https://astral.sh/uv/install.sh | sh
10+
export PATH="$HOME/.local/bin:$PATH"
11+
fi
1212

13+
# Use uvx to run sqlacodegen with temporary environment
1314
# Envars
1415
POSTGRES_HOST=${POSTGRES_HOST:-database}
1516
POSTGRES_USER=${POSTGRES_USER:-postgres}
1617
POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-default}
1718
POSTGRES_DATABASE=${POSTGRES_DATABASE:-postgres}
1819

19-
# Generate
20-
sqlacodegen --schema py_api postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:5432/postgres > ./models/model.py
20+
# Generate using uvx (UV's tool runner)
21+
uvx --from sqlacodegen --with psycopg2-binary --with "sqlacodegen[citext]" sqlacodegen --schema py_api postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:5432/postgres > ./models/model.py

backend-py/logger.conf

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

0 commit comments

Comments
 (0)