build: migrate CI and service images from Poetry to uv (#2152)

* ci: use uv for test dependency installation + add timeout safety net

The analyzer test job runs `poetry install --all-extras` with no committed
lock, so Poetry performs a universal resolve of the full optional-dependencies
graph on every run. That resolve backtracks for many minutes — effectively
hanging — driven by the langextract extra's deep, loosely-bounded transitive
tree. Reproduced locally: Poetry >6 min (never completed); uv ~2s for the same
158-package resolution.

Switch the test jobs to uv:
- Install uv via astral-sh/setup-uv.
- Create a per-component venv with `uv venv --seed` (seed keeps pip for the
  wheel-build step) and expose it via $GITHUB_PATH / $VIRTUAL_ENV.
- `uv pip install -e '.<extras>'` plus the test tooling that previously came
  from the Poetry dev group (uv does not read that group).
- Add a job-level `timeout-minutes: 60` (and 30 on the install step) so a bad
  resolve fails fast instead of hanging.

No package metadata changed — pyproject.toml is untouched; this only swaps the
CI install tooling.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: run tests via uv run inside the uv-managed venv

Use "uv run --no-sync" for spaCy model downloads, pytest, and diff-cover
instead of exposing the venv on $GITHUB_PATH. "uv sync" builds the
project's .venv (resolving the analyzer --all-extras graph in seconds
where Poetry's lockless universal resolve hangs), and the subsequent
steps execute inside it idiomatically. The --all-extras selection stays
in the job matrix, unchanged from main. Wheel-build keeps using the
system interpreter, matching the previous Poetry behaviour.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: install uv via pip instead of the setup-uv action

The astral-sh/setup-uv action is not on the org's allowed-actions list,
so adding it made the CI workflow fail at startup (startup_failure)
before any job ran. Install a pinned uv from PyPI with the already
present setup-python instead; this needs no new third-party action and
keeps the resolver benefits that motivated the Poetry -> uv switch.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: add pip to the uv venv for spaCy model downloads

spaCy's `download` command shells out to `python -m pip install`, but
uv-created virtualenvs ship without pip, so runtime/first-use model
downloads (e.g. the presidio-cli conftest fetching en_core_web_lg)
failed with SystemExit: 1. Install pip alongside the test tooling.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: pre-install tomli for the wheel build on Python < 3.11

`python -m build` imports `tomli` on Python < 3.11 to read pyproject.toml,
but it is not in the hashed requirements-build.txt (pip-compiled on 3.11+
where tomllib is stdlib). Poetry previously pulled tomli onto the runner
as one of its own dependencies, so `pip install --require-hashes` found it
already satisfied. uv has no Python dependencies, so the 3.10 wheel-build
jobs began failing with "requirements must be pinned with ==". Pre-install
a marker-guarded tomli to restore that condition.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: build service Docker images with uv to fix the E2E resolve hang

The local-build-and-E2E job builds the analyzer/anonymizer/image-redactor
images via `docker compose build`. Each Dockerfile ran
`poetry install --no-root --only=main -E server`, which triggered the same
lockless Poetry backtracking that hangs the test jobs: the analyzer image
sat on "Resolving dependencies" for ~40 minutes until the job was
cancelled. Switch the dependency install to `uv pip install --system
-r pyproject.toml --extra server`, which resolves the same graph in
seconds (verified locally: the analyzer install layer completes in ~9s and
imports spacy/flask/gunicorn while correctly omitting the project itself,
matching --no-root). Drop the now-unused POETRY_VIRTUALENVS_CREATE env and
switch `poetry run python install_nlp_models.py` to a direct call.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: run gunicorn directly in container entrypoints (drop poetry run)

The Docker images no longer install Poetry (deps come from uv), so the
`exec poetry run gunicorn ...` entrypoints crashed at startup with
"exec: poetry: not found". The analyzer/anonymizer/image-redactor
containers never came up, so every E2E test failed with connection
refused on ports 5002/5003. uv installs gunicorn system-wide, so invoke
it directly. Verified locally: the anonymizer container now starts
healthy and /health returns 200.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: keep uv's wheel cache on the /mnt ephemeral disk

Restore the intent of the old POETRY_CACHE_DIR=/mnt/poetry_cache setup for
uv: point UV_CACHE_DIR at the runner's large ephemeral disk (/mnt, ~65 GB)
so the heavy analyzer --all-extras wheel cache does not fill the smaller
root volume. /mnt is root-owned, so a prep step creates the directory and
hands it to the runner user. UV_LINK_MODE=copy silences the cross-filesystem
hardlink warning, since the project venv lives on the root volume under the
checkout while the cache is on /mnt.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: broaden CHANGELOG/CI comment to cover the Docker image changes

Address review feedback that the PR scope grew beyond the test jobs: the
CHANGELOG now notes the analyzer/anonymizer/image-redactor image builds
and entrypoints also moved from Poetry to uv, and clarifies pyproject.toml
metadata is unchanged. Also clarify the ci.yml install-step comment that
the wheel-build step deliberately uses the system interpreter (not uv run).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* build: adopt PEP 735 dependency groups and commit uv.lock files

Migrate each CI-tested package's development tooling from Poetry's
[tool.poetry.group.dev.dependencies] to the standard PEP 735
[dependency-groups] table, and commit a uv.lock per package. This makes
pyproject.toml the single source of truth for dev tooling and lets CI and
Docker install a pinned, reproducible dependency graph instead of resolving
on every run. The [project] metadata and the poetry-core build backend are
unchanged, so wheels/sdists are byte-for-byte identical.

Covers presidio-analyzer, presidio-anonymizer, presidio-cli,
presidio-image-redactor, presidio-structured.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: install from the committed uv.lock in CI and Docker builds

CI now runs `uv sync --locked --group dev`, which installs exactly the
locked graph and fails if pyproject.toml and uv.lock disagree rather than
silently resolving new versions. The dev group provides the test tooling
(and pip, which spaCy's model download shells out to), so the manual
`uv pip install pytest ...` line is gone. The uv cache is persisted across
runs via actions/cache keyed on uv.lock and trimmed with `uv cache prune
--ci`.

The analyzer/anonymizer/image-redactor images consume the same lockfile
with `uv sync --locked --no-default-groups --extra server
--no-install-project` into UV_PROJECT_ENVIRONMENT=/usr/local, guaranteeing
images use the same dependency graph as CI. Splitting the dependency layer
from the source COPY keeps it cached until pyproject/uv.lock change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: allow pre-existing transformers advisories in dependency review

The newly committed uv.lock files pin exact versions, so dependency-review
now sees two transformers advisories that already exist on main (capped at
transformers <5 by spacy-huggingface-pipelines and tracked as Dependabot
alerts). They are unrelated to the Poetry->uv migration and will be
addressed in separate security PRs, so allow-list the two GHSAs here to
keep this PR's dependency review unblocked.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: require uv.lock review and commits alongside pyproject changes

Address review feedback from @SharonHart:
- CODEOWNERS: require presidio-administrators approval for **/uv.lock, the
  same as **/pyproject.toml, so lockfile changes get dependency review.
- copilot-instructions: switch the local dev commands to uv and add an
  explicit rule that editing pyproject.toml dependencies requires
  regenerating and committing that package's uv.lock in the same change,
  since CI installs with `uv sync --locked` and fails on drift.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: reference UV_CACHE_DIR in cache path; align dev-docs to uv

Address review feedback:
- ci.yml: use ${{ env.UV_CACHE_DIR }} for the cache action path instead of
  hardcoding /mnt/uv-cache, so the cache and uv stay in sync if the dir
  changes.
- copilot-instructions: update the "Technology Stack" bullet to name uv as
  the dependency/install tool (poetry-core retained only as build backend),
  matching the uv-based dev commands already documented.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* ci: shorten workflow comments; move transformers allow-ghsas out

Trim the verbose explanatory comments in the test job to 1-3 lines each,
and drop the dependency-review `allow-ghsas` entry for the transformers
advisories. That suppression is a security concern rather than part of the
Poetry->uv migration, so it moves to the stacked security PR alongside the
.trivyignore.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: drop stale pip cache; trim CHANGELOG entry

Remove `cache: 'pip'` (keyed on pyproject.toml) from the test job's
setup-python: it is leftover Poetry-era config. Project dependencies now use
the uv cache, and the only remaining pip installs (uv, tomli, build tools)
are tiny and unrelated to pyproject.toml. Also condense the unreleased
CHANGELOG entry to a single concise line; the implementation detail lives in
the PR description.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* small commit to trigger the pipeline again.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Ron Shakutai
2026-07-13 08:42:49 +03:00
committed by GitHub
parent 16ab0fd881
commit 8b7877ccd0
20 changed files with 12542 additions and 93 deletions

1
.github/CODEOWNERS vendored
View File

@@ -1,2 +1,3 @@
# Package dependencies and version changes should be approved by a member of 'presidio-administrators' team
**/pyproject.toml @data-privacy-stack/presidio-administrators
**/uv.lock @data-privacy-stack/presidio-administrators

View File

@@ -570,7 +570,7 @@ Use atomic grouping: (?>a+)b or possessive quantifier a++b"
### Technology Stack
- **Python** - Must support all versions
- **Poetry** - Package manager, not pip
- **uv** - Dependency management and installation (not pip or Poetry). Each package commits a `uv.lock`; `poetry-core` is retained only as the build backend for now.
- **Ruff** - Linting and formatting (replaces flake8, black, isort)
- **spaCy** - Default NLP engine (en_core_web_lg for production), although one can use other NLP engines via provider pattern
- **Docker** - Deployment via GitHub Container Registry (`ghcr.io/data-privacy-stack`)
@@ -587,20 +587,28 @@ Use atomic grouping: (?>a+)b or possessive quantifier a++b"
### Local Development
```bash
# Setup
# Setup (uv reads the committed uv.lock; --locked fails if it is stale)
cd presidio-analyzer # or presidio-anonymizer, presidio-cli, etc.
poetry install --all-extras
poetry run python -m spacy download en_core_web_lg # For analyzer/CLI only
uv sync --locked --all-extras --group dev
uv run python -m spacy download en_core_web_lg # For analyzer/CLI only
# Run tests
poetry run pytest -xvv # Stop on first failure with verbose output
poetry run pytest tests/test_us_ssn_recognizer.py -k "test_valid" # Specific test
uv run pytest -xvv # Stop on first failure with verbose output
uv run pytest tests/test_us_ssn_recognizer.py -k "test_valid" # Specific test
# Lint
ruff check . # From repo root
ruff format . # Auto-format
uv run ruff check .
uv run ruff format .
```
> **Dependency changes:** whenever you edit a package's `pyproject.toml`
> dependencies (add/remove/bump `[project]` deps, extras, or
> `[dependency-groups]`), you MUST regenerate and commit that package's
> `uv.lock` in the same change (`cd <package> && uv lock`). CI installs with
> `uv sync --locked` and fails if `pyproject.toml` and `uv.lock` are out of
> sync, so an updated `pyproject.toml` without its matching `uv.lock` will
> break the build.
### Docker Testing
```bash
# Quick test with pre-built images
@@ -624,7 +632,7 @@ pytest -v # Run all E2E tests
## Common Issues to Watch For
### Build/Test Issues
- **Poetry version conflicts** - Use `poetry lock --no-update` to preserve versions
- **Stale `uv.lock`** - If `uv sync --locked` fails with "lockfile needs to be updated", run `uv lock` in that package and commit the result.
- **Missing spaCy models** - Download en_core_web_lg before running tests
- **AHDS test skips** - Expected when AHDS_ENDPOINT not set
- **Transformers test failures** - Expected without HuggingFace access in restricted environments

View File

@@ -61,6 +61,7 @@ jobs:
test:
name: Test ${{ matrix.component.name }} (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
timeout-minutes: 60
permissions:
contents: write
pull-requests: write
@@ -96,9 +97,13 @@ jobs:
extras: '--all-extras'
spacy-models: 'en_core_web_lg en_core_web_sm'
env:
POETRY_CACHE_DIR: /mnt/poetry_cache
COVERAGE_THRESHOLD: 90
PRIMARY_PYTHON: '3.13'
# uv's wheel cache lives on the roomy /mnt disk (like the old
# POETRY_CACHE_DIR); it is persisted across runs by "Cache uv downloads".
# UV_LINK_MODE=copy avoids cross-filesystem hardlink warnings.
UV_CACHE_DIR: /mnt/uv-cache
UV_LINK_MODE: copy
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.0
@@ -110,22 +115,25 @@ jobs:
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: ${{ matrix.component.path }}/pyproject.toml
- name: Install Poetry
run: |
python -m pip install poetry==2.3.2
- name: Install uv
run: python -m pip install uv==0.11.6
- name: Setup Poetry Cache Directory
- name: Prepare uv cache directory on /mnt
run: |
sudo mkdir -p $POETRY_CACHE_DIR
sudo chown -R runner $POETRY_CACHE_DIR
# Remove stale virtualenvs to prevent cache corruption on re-run attempts.
# GitHub Actions may reuse the same runner VM when re-running failed jobs,
# which leaves the old /mnt/poetry_cache intact. Installing a new numpy
# version over an existing one causes mixed file state and IndentationErrors.
rm -rf $POETRY_CACHE_DIR/virtualenvs 2>/dev/null || true
# /mnt is root-owned, so create the cache dir and hand it to the
# runner user before uv (or the cache restore) writes to it.
sudo mkdir -p "$UV_CACHE_DIR"
sudo chown -R "$(id -u):$(id -g)" "$UV_CACHE_DIR"
- name: Cache uv downloads
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.0
with:
path: ${{ env.UV_CACHE_DIR }}
key: uv-${{ runner.os }}-${{ matrix.component.path }}-py${{ matrix.python-version }}-${{ hashFiles(format('{0}/uv.lock', matrix.component.path)) }}
restore-keys: |
uv-${{ runner.os }}-${{ matrix.component.path }}-py${{ matrix.python-version }}-
uv-${{ runner.os }}-${{ matrix.component.path }}-
- name: Install system dependencies for Image Redactor
if: matrix.component.name == 'Image Redactor'
@@ -134,33 +142,40 @@ jobs:
sudo apt-get install tesseract-ocr -y
- name: Install dependencies
timeout-minutes: 30
working-directory: ${{ matrix.component.path }}
run: |
poetry install ${{ matrix.component.extras }}
# Install the exact locked graph; --locked fails on pyproject/uv.lock
# drift instead of resolving new versions. The dev group provides the
# test tooling plus pip (spaCy's model download shells out to pip).
uv sync --locked ${{ matrix.component.extras }} --group dev --python ${{ matrix.python-version }}
- name: Install presidio-analyzer for Image Redactor
if: matrix.component.name == 'Image Redactor'
working-directory: ${{ matrix.component.path }}
run: |
poetry run pip install -e ../presidio-analyzer/.
# Override the locked PyPI presidio-analyzer with the in-repo copy so
# tests run against local analyzer changes; later steps use
# `uv run --no-sync` so uv won't revert this editable install.
uv pip install -e ../presidio-analyzer/.
- name: Download spaCy models
if: matrix.component.spacy-models != ''
working-directory: ${{ matrix.component.path }}
run: |
for model in ${{ matrix.component.spacy-models }}; do
poetry run python -m spacy download $model
uv run --no-sync python -m spacy download $model
done
- name: Run tests with coverage
working-directory: ${{ matrix.component.path }}
run: |
PACKAGE_NAME=$(echo "${{ matrix.component.path }}" | sed 's/-/_/g')
poetry run pytest --cov=$PACKAGE_NAME --cov-report=xml:coverage.xml --cov-report=term --cov-report=html -vv --tb=short
uv run --no-sync pytest --cov=$PACKAGE_NAME --cov-report=xml:coverage.xml --cov-report=term --cov-report=html -vv --tb=short
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "Checking PR difference coverage (>= ${{ env.COVERAGE_THRESHOLD }}%) with diff-cover..."
poetry run diff-cover coverage.xml \
uv run --no-sync diff-cover coverage.xml \
--compare-branch=origin/${{ github.base_ref }} \
--fail-under=${{ env.COVERAGE_THRESHOLD }} \
--show-uncovered
@@ -180,9 +195,19 @@ jobs:
- name: Build wheel package
working-directory: ${{ matrix.component.path }}
run: |
# `build` needs tomli on Python < 3.11 to read pyproject.toml, and it
# isn't in the hashed requirements file; pre-install it (marker-guarded)
# so --require-hashes finds it already satisfied.
python -m pip install "tomli==2.4.1; python_version < '3.11'"
pip install --require-hashes -r ${{ github.workspace }}/.github/pipelines/requirements-build.txt
python -m build --wheel
- name: Minimize uv cache
if: always()
run: |
# Trim the persisted cache (recommended for CI by the uv docs).
uv cache prune --ci
build-platform-images:
name: Build ${{ matrix.image }} (${{ matrix.platform }})
runs-on: ${{ matrix.runner }}
@@ -341,7 +366,7 @@ jobs:
run: |
docker compose -f docker-compose.yml down
# Build and test Docker images locally for non-main branches without publishing.
# Build and test Docker images locally for non-main branches without publishing
local-build-and-test:
name: Local Build and E2E Tests (${{ matrix.platform }})
runs-on: ${{ matrix.runner }}

View File

@@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file.
### Anonymizer
### General
#### Changed
- Migrated CI and service-image dependency installation from Poetry to [uv](https://github.com/astral-sh/uv) with committed lockfiles, fixing prolonged dependency-resolution hangs and making builds reproducible.
#### Fixed
- Retried the Zensical documentation build on transient crashes (e.g. SIGKILL/exit 247) so the docs release pipeline no longer fails intermittently (Thanks @Copilot)

View File

@@ -4,7 +4,8 @@ ARG NLP_CONF_FILE=presidio_analyzer/conf/default.yaml
ARG ANALYZER_CONF_FILE=presidio_analyzer/conf/default_analyzer.yaml
ARG RECOGNIZER_REGISTRY_CONF_FILE=presidio_analyzer/conf/default_recognizers.yaml
ENV PIP_NO_CACHE_DIR=1
ENV POETRY_VIRTUALENVS_CREATE=false
# Install the locked dependencies into the system environment (no venv).
ENV UV_PROJECT_ENVIRONMENT=/usr/local
ENV ANALYZER_CONF_FILE=${ANALYZER_CONF_FILE}
ENV RECOGNIZER_REGISTRY_CONF_FILE=${RECOGNIZER_REGISTRY_CONF_FILE}
@@ -24,16 +25,19 @@ RUN apt-get update \
&& apt-get install curl --no-install-recommends -y \
&& rm -rf /var/lib/apt/lists/*
COPY ./pyproject.toml /app/
COPY ./pyproject.toml ./uv.lock /app/
RUN pip install poetry==2.3.2 \
&& poetry install --no-root --only=main -E server \
&& rm -rf $(poetry config cache-dir)
# Install exactly the locked dependency graph (main + server extra, no dev
# group, project itself not installed — it is run from the copied source).
# Splitting this from the source COPY keeps the dependency layer cached until
# pyproject.toml/uv.lock change.
RUN pip install uv==0.11.6 \
&& uv sync --locked --no-cache --no-default-groups --extra server --no-install-project
# install nlp models specified in NLP_CONF_FILE or via nlp_configuration in ANALYZER_CONF_FILE
COPY ./install_nlp_models.py /app/
RUN poetry run python install_nlp_models.py \
RUN python install_nlp_models.py \
--conf_file ${NLP_CONF_FILE} \
--analyzer_conf_file ${ANALYZER_CONF_FILE}

View File

@@ -1,2 +1,2 @@
#!/bin/sh
exec poetry run gunicorn -w "$WORKERS" -b "0.0.0.0:$PORT" "app:create_app()"
exec gunicorn -w "$WORKERS" -b "0.0.0.0:$PORT" "app:create_app()"

View File

@@ -73,15 +73,17 @@ langextract = [
"jinja2 (>=3.0.0,<4.0.0)",
]
[tool.poetry.group.dev.dependencies]
pip = "*"
ruff = "*"
pytest = "*"
pytest-cov = "*"
pytest-mock = "*"
python-dotenv = "*"
pre_commit = "*"
diff-cover = "*"
[dependency-groups]
dev = [
"pip",
"ruff",
"pytest",
"pytest-cov",
"pytest-mock",
"python-dotenv",
"pre-commit",
"diff-cover",
]
[tool.coverage.run]
relative_files = true

4634
presidio-analyzer/uv.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
FROM python:3.14-slim@sha256:bc389f7dfcb21413e72a28f491985326994795e34d2b86c8ae2f417b4e7818aa
ENV PIP_NO_CACHE_DIR=1
ENV POETRY_VIRTUALENVS_CREATE=false
# Install the locked dependencies into the system environment (no venv).
ENV UV_PROJECT_ENVIRONMENT=/usr/local
ENV PORT=3000
ENV WORKERS=1
@@ -11,10 +12,11 @@ WORKDIR /app
# Install curl for health checks
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
COPY ./pyproject.toml /app/
RUN pip install poetry==2.3.2 \
&& poetry install --no-root --only=main -E server \
&& rm -rf $(poetry config cache-dir)
COPY ./pyproject.toml ./uv.lock /app/
# Install exactly the locked dependency graph (main + server extra, no dev
# group); the project itself is run from the copied source, not installed.
RUN pip install uv==0.11.6 \
&& uv sync --locked --no-cache --no-default-groups --extra server --no-install-project
COPY . /app/

View File

@@ -1,2 +1,2 @@
#!/bin/sh
exec poetry run gunicorn -w "$WORKERS" -b "0.0.0.0:$PORT" "app:create_app()"
exec gunicorn -w "$WORKERS" -b "0.0.0.0:$PORT" "app:create_app()"

View File

@@ -36,15 +36,17 @@ ahds = [
"azure-health-deidentification (>=1.1.0b1,<2.0.0)"
]
[tool.poetry.group.dev.dependencies]
pip = "*"
ruff = "*"
pytest = "*"
pytest-cov = "*"
pytest-mock = "*"
python-dotenv = "*"
pre_commit = "*"
diff-cover = "*"
[dependency-groups]
dev = [
"pip",
"ruff",
"pytest",
"pytest-cov",
"pytest-mock",
"python-dotenv",
"pre-commit",
"diff-cover",
]
[tool.coverage.run]
relative_files = true

1168
presidio-anonymizer/uv.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -33,15 +33,17 @@ dependencies = [
presidio = "presidio_cli.cli:run"
[tool.poetry.group.dev.dependencies]
pip = "*"
ruff = "*"
pytest = "*"
pytest-cov = "*"
pytest-mock = "*"
python-dotenv = "*"
pre_commit = "*"
diff-cover = "*"
[dependency-groups]
dev = [
"pip",
"ruff",
"pytest",
"pytest-cov",
"pytest-mock",
"python-dotenv",
"pre-commit",
"diff-cover",
]
[tool.coverage.run]
relative_files = true

1735
presidio-cli/uv.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,8 @@ ARG NLP_CONF_FILE
ARG ANALYZER_CONF_FILE
ARG RECOGNIZER_REGISTRY_CONF_FILE
ENV PIP_NO_CACHE_DIR=1
ENV POETRY_VIRTUALENVS_CREATE=false
# Install the locked dependencies into the system environment (no venv).
ENV UV_PROJECT_ENVIRONMENT=/usr/local
ENV ANALYZER_CONF_FILE=${ANALYZER_CONF_FILE}
ENV RECOGNIZER_REGISTRY_CONF_FILE=${RECOGNIZER_REGISTRY_CONF_FILE}
@@ -24,10 +25,11 @@ RUN apt-get update \
&& rm -rf /var/lib/apt/lists/* \
&& tesseract -v
COPY ./pyproject.toml /app/
RUN pip install poetry==2.3.2 \
&& poetry install --no-root --only=main -E server\
&& rm -rf $(poetry config cache-dir)
COPY ./pyproject.toml ./uv.lock /app/
# Install exactly the locked dependency graph (main + server extra, no dev
# group); the project itself is run from the copied source, not installed.
RUN pip install uv==0.11.6 \
&& uv sync --locked --no-cache --no-default-groups --extra server --no-install-project
# Install spaCy model during build (as root) so it's available to non-root user at runtime
RUN python -m spacy download en_core_web_lg

View File

@@ -1,2 +1,2 @@
#!/bin/sh
exec poetry run gunicorn -w "$WORKERS" -b "0.0.0.0:$PORT" "app:create_app()"
exec gunicorn -w "$WORKERS" -b "0.0.0.0:$PORT" "app:create_app()"

View File

@@ -39,15 +39,17 @@ server = [
"gunicorn (>=25.3.0,<26.0.0)"
]
[tool.poetry.group.dev.dependencies]
pip = "*"
ruff = "*"
pytest = "*"
pytest-cov = "*"
pytest-mock = "*"
python-dotenv = "*"
pre_commit = "*"
diff-cover = "*"
[dependency-groups]
dev = [
"pip",
"ruff",
"pytest",
"pytest-cov",
"pytest-mock",
"python-dotenv",
"pre-commit",
"diff-cover",
]
[tool.coverage.run]
relative_files = true

2445
presidio-image-redactor/uv.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -28,15 +28,17 @@ dependencies = [
"click (>=8.1.0,<9.0.0)",
]
[tool.poetry.group.dev.dependencies]
pip = "*"
ruff = "*"
pytest = "*"
pytest-cov = "*"
pytest-mock = "*"
python-dotenv = "*"
pre_commit = "*"
diff-cover = "*"
[dependency-groups]
dev = [
"pip",
"ruff",
"pytest",
"pytest-cov",
"pytest-mock",
"python-dotenv",
"pre-commit",
"diff-cover",
]
[tool.coverage.run]
relative_files = true

2413
presidio-structured/uv.lock generated Normal file

File diff suppressed because it is too large Load Diff