Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to uv python tool #579

Open
wants to merge 12 commits into
base: jeremy/refactor-dockerfiles
Choose a base branch
from
Open
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
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
**/build
.git
**/.mypy_cache
.venv*
**/.pytest_cache
**/.ruff_cache
**/__pycache__
35 changes: 18 additions & 17 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,22 +56,23 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4

- name: Init Python
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "0.5.10"
python-version: "3.11"
cache: "pip"
enable-cache: true


- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install -e pytest-pixl/
pip install -e pixl_core/[test]
pip install -e ${{ matrix.package_dir }}/[test]
uv sync --all-extras --all-packages

- name: Run tests and generate coverage report
working-directory: ${{ matrix.package_dir }}
run: COV_CORE_SOURCE=src COV_CORE_CONFIG=.coveragerc COV_CORE_DATAFILE=.coverage.eager pytest --cov=src --cov-append --cov-report=xml --cov-report=term-missing
run: |
source ../.venv/bin/activate
COV_CORE_SOURCE=src COV_CORE_CONFIG=.coveragerc COV_CORE_DATAFILE=.coverage.eager pytest --cov=src --cov-append --cov-report=xml --cov-report=term-missing
env:
ENV: test
AZURE_KEY_VAULT_NAME: test
Expand All @@ -91,19 +92,19 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3
- name: Init Python
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "0.5.10"
python-version: "3.11"
cache: "pip"
enable-cache: true

- name: Install Python dependencies
# The -e option is required here due to the way the
# Editable install required here due to the way the
# code determines the export directory. See issue #318.
run: |
pip install -e pytest-pixl/
pip install -e pixl_core/[test]
pip install -e cli/[test]
uv sync --all-extras --all-packages

- name: Create .secrets.env
run: touch test/.secrets.env
Expand All @@ -129,7 +130,7 @@ jobs:
HASHER_API_AZ_TENANT_ID: ${{ secrets.EXPORT_AZ_TENANT_ID }}
HASHER_API_AZ_KEY_VAULT_NAME: ${{ secrets.EXPORT_AZ_KEY_VAULT_NAME }}
run: |
./run-system-test.sh coverage
uv run ./run-system-test.sh coverage
echo FINISHED SYSTEM TEST SCRIPT

- name: Dump queue docker logs for debugging
Expand Down Expand Up @@ -183,4 +184,4 @@ jobs:
with:
directory: test
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
9 changes: 7 additions & 2 deletions cli/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@ dev = [
pixl = "pixl_cli.main:cli"

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
requires = ["hatchling>=1.0.0"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
dev-mode-dirs = [
"src"
]

[tool.coverage.report]
exclude_also = [
Expand Down
2 changes: 0 additions & 2 deletions docker/.dockerignore

This file was deleted.

39 changes: 20 additions & 19 deletions docker/orthanc/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,28 @@ SHELL ["/bin/bash", "-o", "pipefail", "-e", "-u", "-x", "-c"]
# where you get a warning when installing system-wide packages.
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install --yes --no-install-recommends python3-venv tzdata
RUN python3 -m venv /.venv
apt-get install --yes --no-install-recommends curl tzdata && \
apt-get autoremove --yes && apt-get clean --yes && rm -rf /var/lib/apt/lists/*

# Install curl for now, but try to remove this dependency
RUN apt-get --assume-yes install curl
# install uv
COPY --from=ghcr.io/astral-sh/uv:0.5.10 /uv /uvx /bin/

# Install requirements before copying modules
COPY ./pixl_core/pyproject.toml /pixl_core/pyproject.toml
COPY ./pixl_dcmd/pyproject.toml /pixl_dcmd/pyproject.toml

RUN --mount=type=cache,target=/root/.cache \
/.venv/bin/pip install pixl_core/ \
&& /.venv/bin/pip install pixl_dcmd/

COPY ./pixl_core/ /pixl_core
RUN --mount=type=cache,target=/root/.cache \
/.venv/bin/pip install --no-cache-dir --force-reinstall --no-deps ./pixl_core

COPY ./pixl_dcmd/ /pixl_dcmd
RUN --mount=type=cache,target=/root/.cache \
/.venv/bin/pip install --no-cache-dir --force-reinstall --no-deps ./pixl_dcmd
# Install our code
# The workspace project file
COPY pyproject.toml .
# All pyproject.toml files referenced by the root one must exist or uv will error
COPY ./pixl_imaging/pyproject.toml pixl_imaging/pyproject.toml
COPY ./pixl_export/pyproject.toml pixl_export/pyproject.toml
COPY ./cli/pyproject.toml cli/pyproject.toml
COPY ./hasher/pyproject.toml hasher/pyproject.toml
# prereqs for dcmd
COPY ./pytest-pixl/ pytest-pixl/
COPY ./pixl_core/ pixl_core/
COPY ./pixl_dcmd/ pixl_dcmd
RUN uv venv
# Need --no-editable so that our packages are in
# site-packages, so orthanc plugin manager can find them
RUN uv sync --no-editable --package pixl-dcmd

ARG ORTHANC_DIR
COPY ./orthanc/${ORTHANC_DIR}/plugin/pixl.py /etc/orthanc/pixl.py
Expand Down
47 changes: 31 additions & 16 deletions docker/pixl-python/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ SHELL ["/bin/bash", "-o", "pipefail", "-e", "-u", "-x", "-c"]

ARG TEST="false"

RUN export DEBIAN_FRONTEND=noninteractive && \
RUN <<EOF
export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install --yes --no-install-recommends \
procps \
Expand All @@ -26,30 +27,44 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
curl \
gnupg \
locales \
tzdata

RUN sed -i '/en_GB.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
RUN apt-get autoremove && apt-get clean && rm -rf /var/lib/apt/lists/*
tzdata && \
sed -i '/en_GB.UTF-8/s/^# //g' /etc/locale.gen && locale-gen && \
apt-get autoremove --yes && apt-get clean --yes && rm -rf /var/lib/apt/lists/*
EOF

HEALTHCHECK CMD /usr/bin/curl -f http://0.0.0.0:8000/heart-beat || exit 1

# install uv
COPY --from=ghcr.io/astral-sh/uv:0.5.10 /uv /uvx /bin/

WORKDIR /app
# specify what we're installing using build time arg
ARG PIXL_PACKAGE_DIR

# Install requirements before copying modules
COPY ./pixl_core/pyproject.toml ./pixl_core/pyproject.toml
COPY ./$PIXL_PACKAGE_DIR/pyproject.toml ./$PIXL_PACKAGE_DIR/pyproject.toml
RUN pip3 install --no-cache-dir pixl_core/ \
&& pip3 install --no-cache-dir $PIXL_PACKAGE_DIR/
# Install our code:

# COPY doesn't support a wildcard copy which also preserves directory structure,
# so we have to specify everything separately. We could have copied everything, but
# then every change would trigger a rebuild of all containers.

# Install our code
# The workspace project file
COPY pyproject.toml .
# All pyproject.toml files referenced by the root one must exist or uv will error
COPY ./pixl_imaging/pyproject.toml pixl_imaging/pyproject.toml
COPY ./pixl_export/pyproject.toml pixl_export/pyproject.toml
COPY ./pixl_dcmd/pyproject.toml pixl_dcmd/pyproject.toml
COPY ./cli/pyproject.toml cli/pyproject.toml
COPY ./hasher/pyproject.toml hasher/pyproject.toml
# prereqs for all projects
COPY ./pytest-pixl/ pytest-pixl/
COPY ./pixl_core/ pixl_core/
COPY ./$PIXL_PACKAGE_DIR/ .
RUN pip install --no-cache-dir --force-reinstall --no-deps pixl_core/ \
--no-cache-dir --force-reinstall --no-deps . && \
if [ "$TEST" = "true" ]; then pip install --no-cache-dir pixl_core/[test] .[test]; fi
# the actual thing we are building
COPY ./$PIXL_PACKAGE_DIR/ $PIXL_PACKAGE_DIR/
RUN uv venv
RUN uv sync --package "$PIXL_PACKAGE_DIR"

# make uvicorn etc available
ENV PATH="/app/.venv/bin:$PATH"

# Each container should be run with a different entry point
FROM pixl_python_base AS export_api
Expand All @@ -59,4 +74,4 @@ FROM pixl_python_base AS hasher_api
ENTRYPOINT ["uvicorn", "hasher.main:app", "--host", "0.0.0.0", "--port", "8000"]

FROM pixl_python_base AS imaging_api
ENTRYPOINT ["/app/scripts/migrate_and_run.sh"]
ENTRYPOINT ["/app/pixl_imaging/scripts/migrate_and_run.sh"]
4 changes: 2 additions & 2 deletions hasher/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ dev = [
]

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.ruff]
extend = "../ruff.toml"
Expand Down
10 changes: 8 additions & 2 deletions pixl_core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,14 @@ dev = [
]

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
requires = ["hatchling>=1.0.0"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
dev-mode-dirs = [
"src"
]


[tool.pytest.ini_options]
markers = ["pika"]
Expand Down
5 changes: 3 additions & 2 deletions pixl_dcmd/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dependencies = [
"pydicom-data",
"python-decouple==3.8",
"requests==2.32.3",
"setuptools", # pydicom needs this
"types-requests~=2.28",
]

Expand All @@ -30,8 +31,8 @@ dev = [
]

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.coverage.report]
exclude_also = [
Expand Down
4 changes: 2 additions & 2 deletions pixl_export/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ dev = [
]

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.coverage.report]
exclude_also = [
Expand Down
4 changes: 2 additions & 2 deletions pixl_imaging/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ dev = [
]

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.coverage.report]
exclude_also = [
Expand Down
4 changes: 2 additions & 2 deletions pixl_imaging/scripts/migrate_and_run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
# Run migrations (unless SKIP_ALEMBIC is true) then run the app.

set -eux -o pipefail
cd /app/alembic
cd /app/pixl_imaging/alembic
if [ "${SKIP_ALEMBIC:-false}" = false ]; then
echo "Running alembic migrations"
alembic upgrade head
else
echo "Skipping alembic migrations"
fi

uvicorn pixl_imaging.main:app --host "0.0.0.0" --port 8000
uvicorn pixl_imaging.main:app --host "0.0.0.0" --port 8000
52 changes: 52 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
[project]
name = "pixl"
version = "0.2.0rc0"
description = "Top-level PIXL project"
readme = "README.md"
requires-python = ">=3.9"
dependencies = [
'core',
'pixl_cli',
'pytest-pixl',
"hasher",
"pixl_dcmd",
"pixl_export",
"pixl_imaging",
]


[tool.uv.sources]
pixl_cli = { workspace = true }
core = { workspace = true }
pytest-pixl = { workspace = true }
hasher = { workspace = true }
pixl_dcmd = { workspace = true }
pixl_export = { workspace = true }
pixl_imaging = { workspace = true }

[tool.uv.workspace]
members = [
"cli",
"pixl_core",
"pytest-pixl",
"hasher",
"pixl_dcmd",
"pixl_export",
"pixl_imaging",
]

[tool.hatch.build.targets.wheel]
dev-mode-dirs = [
"cli",
"pixl_core",
"pytest-pixl",
"hasher",
"pixl_dcmd",
"pixl_export",
"pixl_imaging",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

12 changes: 9 additions & 3 deletions pytest-pixl/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ dev = [
]

[build-system]
requires = ["setuptools>=61.0", "setuptools-scm>=8.0"]
build-backend = "setuptools.build_meta"
requires = ["hatchling>=1.0.0"]
build-backend = "hatchling.build"


[tool.hatch.build.targets.wheel]
dev-mode-dirs = [
"src"
]


[tool.coverage.report]
Expand Down Expand Up @@ -66,4 +72,4 @@ extend = "../ruff.toml"
"./tests/**" = ["D100"]

[project.entry-points.pytest11]
pytest_pixl = "pytest_pixl.plugin"
pytest_pixl = "pytest_pixl.plugin"
Loading