Skip to content

Commit

Permalink
Merge pull request #186 from openradx/poetry-to-uv
Browse files Browse the repository at this point in the history
Switch from poetry to uv
  • Loading branch information
medihack authored Feb 15, 2025
2 parents 759503d + 7d216a3 commit 93fcfe4
Show file tree
Hide file tree
Showing 17 changed files with 2,698 additions and 4,142 deletions.
4 changes: 1 addition & 3 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ USER root
# - gettext for Django translations
# - postgresql-common for the apt.postgresql.org.sh script
# - postgresql-client-17 for a current version of psql
# Make sure to match the version of the postgres service in the compose file!
RUN sudo apt-get update \
&& apt-get install -y --no-install-recommends \
bash-completion \
Expand All @@ -17,6 +18,3 @@ RUN sudo apt-get update \
&& rm -rf /var/lib/apt/lists/*

USER vscode

RUN pipx install poetry \
&& poetry completions bash >> ~/.bash_completion
7 changes: 4 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/devcontainers/features/node:1": {}
},
// https://github.com/orgs/community/discussions/50403
// "initializeCommand": "docker system prune --all --force",
"postCreateCommand": "poetry install && poetry run ./cli.py init-workspace",
"remoteEnv": {
"UV_CACHE_DIR": "/workspaces/.cache"
},
"postCreateCommand": "uv sync && uv run ./cli.py init-workspace",
"customizations": {
"vscode": {
"extensions": [
Expand Down
6 changes: 3 additions & 3 deletions .github/renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@
"allowedVersions": "<=3.12"
},
{
"matchManagers": ["poetry"],
"matchManagers": ["pep621"],
"matchPackageNames": ["pydicom"],
"allowedVersions": "<=2"
},
{
"matchManagers": ["poetry"],
"matchManagers": ["pep621"],
"matchPackageNames": ["dicognito"],
"allowedVersions": "<=0.17"
},
{
"managers": ["poetry"],
"managers": ["pep621"],
"matchPackageNames": ["factory-boy"],
"allowedVersions": "<=3.3.2"
}
Expand Down
30 changes: 13 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,23 @@ jobs:
ci:
strategy:
fail-fast: false
matrix:
python-version: ["3.12"]
poetry-version: ["2.0.1"]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
runs-on: "ubuntu-latest"
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set up Poetry
uses: abatilo/actions-poetry@v4
version: "0.6.0"
- name: Setup Python
uses: actions/setup-python@v5
with:
poetry-version: ${{ matrix.poetry-version }}
python-version-file: ".python-version"
- name: Install dependencies
run: poetry install
run: uv sync
- name: Configure environment
run: poetry run ./cli.py init-workspace
run: uv run ./cli.py init-workspace
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and cache Docker images
Expand All @@ -41,14 +37,14 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Start Docker containers
run: poetry run ./cli.py compose-up --no-build
run: uv run ./cli.py compose-up --no-build
- name: Run linting
# https://github.com/actions/runner/issues/241#issuecomment-745902718
shell: 'script -q -e -c "bash {0}"'
run: poetry run ./cli.py lint
run: uv run ./cli.py lint
- name: Run tests
shell: 'script -q -e -c "bash {0}"'
run: poetry run ./cli.py test --cov
run: uv run ./cli.py test --cov
- name: Stop Docker containers
if: ${{ always() }}
run: poetry run ./cli.py compose-down
run: uv run ./cli.py compose-down
10 changes: 0 additions & 10 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,6 @@ target/
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

Expand Down
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"cSpell.diagnosticLevel": "Hint",
"docker.containers.label": "ContainerName",
"editor.formatOnSave": true,
"evenBetterToml.schema.enabled": false,
"javascript.validate.enable": true,
"js/ts.implicitProjectConfig.checkJs": true,
"notebook.formatOnSave.enabled": true,
Expand Down
7 changes: 3 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ We adhere to the Google Python Style [Guide](https://google.github.io/styleguide
```terminal
git clone https://github.com/openradx/adit.git
cd adit
poetry install
poetry shell
poetry run ./cli.py compose-up
uv sync
uv run ./cli.py compose-up
```

The development server of the example project will be started on <http://localhost:8000>

If a library dependency is changed, the containers need to be rebuilt (e.g. by running
`poetry run ./cli.py compose-down && poetry run ./cli.py compose-up`).
`uv run ./cli.py compose-down && uv run ./cli.py compose-up`).
101 changes: 34 additions & 67 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,38 +1,9 @@
FROM python:3.12-bullseye AS python-base
# Ideas from https://docs.astral.sh/uv/guides/integration/docker/

# python
# ENV variables are also available in the later build stages
ENV PYTHONUNBUFFERED=1 \
# prevents python creating .pyc files
PYTHONDONTWRITEBYTECODE=1 \
\
# pip
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
\
# poetry
# https://python-poetry.org/docs/#installing-with-the-official-installer
# https://python-poetry.org/docs/configuration/#using-environment-variables
POETRY_VERSION=2.0.1 \
# make poetry install to this location
POETRY_HOME="/opt/poetry" \
# make poetry create the virtual environment in the project's root
# it gets named `.venv`
POETRY_VIRTUALENVS_IN_PROJECT=true \
# do not ask any interactive question
POETRY_NO_INTERACTION=1 \
\
# paths
# this is where our requirements + virtual environment will live
PYSETUP_PATH="/opt/pysetup" \
VENV_PATH="/opt/pysetup/.venv"

# prepend poetry and venv to path
ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"

# deps for db management commands and transferring to an archive
# make sure to match the postgres version to the service in the compose file
FROM python:3.12-bullseye AS builder-base

# Install dependencies for the `psql` command and 7zip.
# Must match the version of the postgres service in the compose file!
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
postgresql-common \
Expand All @@ -42,51 +13,47 @@ RUN apt-get update \
p7zip-full \
&& rm -rf /var/lib/apt/lists/*

ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1

# `builder-base` stage is used to build deps + create our virtual environment
FROM python-base AS builder-base
COPY --from=ghcr.io/astral-sh/uv:0.6.0 /uv /uvx /bin/

RUN apt-get update \
&& apt-get install --no-install-recommends -y \
# deps for installing poetry
curl \
# deps for building python deps
build-essential \
&& rm -rf /var/lib/apt/lists/*
ENV UV_COMPILE_BYTECODE=1 \
UV_LINK_MODE=copy

# install poetry - respects $POETRY_VERSION & $POETRY_HOME
RUN curl -sSL https://install.python-poetry.org | python3 -
# There is no git during image build so we need to provide a fake version
ENV UV_DYNAMIC_VERSIONING_BYPASS=0.0.0

# copy project requirement files here to ensure they will be cached.
WORKDIR $PYSETUP_PATH
COPY poetry.lock pyproject.toml ./
ENV PATH="/app/.venv/bin:$PATH"

# install runtime deps - uses $POETRY_VIRTUALENVS_IN_PROJECT internally
RUN poetry install --without dev --no-root
WORKDIR /app


# `development` image is used during development / testing
FROM python-base AS development
# development image
FROM builder-base AS development

WORKDIR $PYSETUP_PATH
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-project

# copy in our built poetry + venv
COPY --from=builder-base $POETRY_HOME $POETRY_HOME
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH
RUN playwright install --with-deps chromium

# quicker install as runtime deps are already installed
RUN poetry install --no-root
ADD . /app

# Install requirements for end-to-end testing
RUN playwright install --with-deps chromium
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen

# will become mountpoint of our code
WORKDIR /app

# production image
FROM builder-base AS production

# `production` image used for runtime
FROM python-base AS production
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH
COPY . /app/
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-project --no-dev

WORKDIR /app
ADD . /app

RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
7 changes: 1 addition & 6 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ x-app: &default-app
image: adit_dev:latest
volumes:
- .:/app
- vscode-server:/root/.vscode-server/extensions
- vscode-server-insiders:/root/.vscode-server-insiders/extensions
- /app/.venv
environment:
DJANGO_INTERNAL_IPS: ${DJANGO_INTERNAL_IPS:?}
DJANGO_SETTINGS_MODULE: adit.settings.development
Expand Down Expand Up @@ -66,7 +65,3 @@ services:
POSTGRES_PASSWORD: postgres
ports:
- ${POSTGRES_DEV_PORT:-5432}:5432

volumes:
vscode-server:
vscode-server-insiders:
2 changes: 1 addition & 1 deletion docs/Backups.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Backups

For database backups django-dbbackup app is used. The backups are done every night at 3 am by a periodic task using the dbbackup management command and stored in the `backups` directory which is mounted as a volume. The dbbackup command can also be called manually with `poetry run ./cli.py backup-db`.
For database backups django-dbbackup app is used. The backups are done every night at 3 am by a periodic task using the dbbackup management command and stored in the `backups` directory which is mounted as a volume. The dbbackup command can also be called manually with `uv run ./cli.py backup-db`.
10 changes: 5 additions & 5 deletions docs/Maintenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
There are different things that can be upgraded:

- The python package dependencies (normal dependencies and dev dependencies)
- Check outdated Python packages: `poetry run ./cli.py show-outdated` (check Python section in output)
- `poetry update` will update packages according to their version range in `pyproject.toml`
- Other upgrades (e.g. major versions) must be upgraded by modifying the version range in `pyproject.toml` before calling `poetry update`
- Check outdated Python packages: `uv run ./cli.py show-outdated` (check Python section in output)
- `uv lock --upgrade` will update packages according to their version range in `pyproject.toml`
- Other upgrades (e.g. major versions) must be upgraded by modifying the version range in `pyproject.toml` before calling `uv lock --upgrade`
- Javascript dependencies
- Check outdated Javascript packages: `poetry run ./cli.py show-outdated` (check Javascript section in output)
- Check outdated Javascript packages: `uv run ./cli.py show-outdated` (check Javascript section in output)
- `npm update` will update packages according to their version range in `package.json`
- Other upgrades (e.g. major versions) must be upgraded by modifying the version range in `packages.json` before calling `npm update`
- After an upgrade make sure the files in `static/vendor` still link to the correct files in `node_modules`1
- Python and Poetry in `Dockerfile` that builds the container where ADIT runs in
- Python and uv in `Dockerfile` that builds the container where ADIT runs in
- Dependent services in `docker-compose.base.yml`, like PostgreSQL or Vespa database
- Gitpod development container dependencies in `.gitpod.Dockerfile`
- Github Codespaces development container dependencies in `.devcontainer/devcontainer.json` and `.devcontainer/Dockerfile`
Expand Down
2 changes: 1 addition & 1 deletion example.env
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ SITE_DOMAIN=localhost
# These variables are used to create a certificate key, self-signed certificate,
# and the corresponding certificate chain. If you have an existing certificate
# key and signed certificate from your CA, you can generate the corresponding
# certificate chain using 'poetry run ./cli.py generate-certificate-chain'.
# certificate chain using 'uv run ./cli.py generate-certificate-chain'.
SSL_HOSTNAME=localhost
SSL_IP_ADDRESSES=127.0.0.1
SSL_SERVER_CERT_FILE="./cert.pem"
Expand Down
Loading

0 comments on commit 93fcfe4

Please sign in to comment.