From 95038d964616957333343de02d4ce745a318882c Mon Sep 17 00:00:00 2001 From: thorinaboenke Date: Fri, 10 Jul 2026 13:57:51 +0200 Subject: [PATCH 1/5] optional dependencies --- Dockerfile | 11 ++- docker-compose.yml | 195 +++++++++++++++++++++-------------------- docs/development.md | 17 ++++ docs/installation.md | 31 +++++++ docs/library.md | 7 ++ pyproject.toml | 15 +++- scripts/change_toml.sh | 4 +- uv.lock | 70 +++++++++++++-- 8 files changed, 244 insertions(+), 106 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8104874f..a86cfe9b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,6 +2,11 @@ FROM python:3.14-slim WORKDIR /app +# Comma-separated detectmatelibrary extras to install, e.g. "llm,dataframes". +# Defaults to "full" (all optional components available). Pass an empty +# string to install only the base library. +ARG LIBRARY_EXTRAS=full + # Install system dependencies RUN apt-get update && \ apt-get install -y --no-install-recommends \ @@ -14,6 +19,10 @@ COPY pyproject.toml README.md ./ COPY ./src ./src COPY ./tests ./tests -RUN uv pip install --system . +RUN if [ -n "$LIBRARY_EXTRAS" ]; then \ + uv pip install --system ".[$LIBRARY_EXTRAS]" ; \ + else \ + uv pip install --system . ; \ + fi CMD ["detectmate", "--help"] diff --git a/docker-compose.yml b/docker-compose.yml index 88a28218..9ac07a5e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,104 +1,111 @@ # version: "3" services: - fluentin: - #image: dm-fluentd:latest - build: - context: . - dockerfile: container/Dockerfile_fluentd - volumes: - - '$PWD/container/fluentin:/fluentd/etc' - - '/var/log/nginx:/fluentd/log' - - '$PWD/container/run:/run' - depends_on: - - parser - parser: - # image: detectmate:dev-0.1.6 - build: . - volumes: - - '$PWD/container/config:/config' - - '$PWD/container/logs:/logs' - - '$PWD/container/run:/run' - command: uv run detectmate --settings /config/parser_settings.yaml --config /config/parser_config.yaml - ports: - - "8001:8000" - depends_on: - - detector + fluentin: + #image: dm-fluentd:latest + build: + context: . + dockerfile: container/Dockerfile_fluentd + volumes: + - '$PWD/container/fluentin:/fluentd/etc' + - '/var/log/nginx:/fluentd/log' + - '$PWD/container/run:/run' + depends_on: + - parser + parser: + # image: detectmate:dev-0.1.6 + build: + context: . + args: + LIBRARY_EXTRAS: ${LIBRARY_EXTRAS:-full} + volumes: + - '$PWD/container/config:/config' + - '$PWD/container/logs:/logs' + - '$PWD/container/run:/run' + command: uv run detectmate --settings /config/parser_settings.yaml --config /config/parser_config.yaml + ports: + - "8001:8000" + depends_on: + - detector - detector: - # image: detectmate:dev-0.1.6 - build: . - volumes: - - '$PWD/container/config:/config' - - '$PWD/container/logs:/logs' - - '$PWD/container/run:/run' - - '$PWD/container/state:/state' - command: uv run detectmate --settings /config/detector_settings.yaml --config /config/detector_config.yaml - ports: - - "8002:8000" - depends_on: - - fluentout + detector: + # image: detectmate:dev-0.1.6 + build: + context: . + args: + LIBRARY_EXTRAS: ${LIBRARY_EXTRAS:-full} + volumes: + - '$PWD/container/config:/config' + - '$PWD/container/logs:/logs' + - '$PWD/container/run:/run' + - '$PWD/container/state:/state' + command: uv run detectmate --settings /config/detector_settings.yaml --config /config/detector_config.yaml + ports: + - "8002:8000" + depends_on: + - fluentout - fluentout: - # image: dm-fluentd:latest - build: - context: . - dockerfile: container/Dockerfile_fluentd - volumes: - - '$PWD/container/fluentout:/fluentd/etc' - - '$PWD/container/fluentlogs:/fluentd/log' - - '$PWD/container/run:/run' + fluentout: + # image: dm-fluentd:latest + build: + context: . + dockerfile: container/Dockerfile_fluentd + volumes: + - '$PWD/container/fluentout:/fluentd/etc' + - '$PWD/container/fluentlogs:/fluentd/log' + - '$PWD/container/run:/run' - prometheus: - image: prom/prometheus:latest - container_name: prometheus - restart: unless-stopped - volumes: - - ./container/prometheus.yml:/etc/prometheus/prometheus.yml - - prometheus_data:/prometheus - command: - - '--config.file=/etc/prometheus/prometheus.yml' - - '--storage.tsdb.path=/prometheus' - - '--web.console.libraries=/etc/prometheus/console_libraries' - - '--web.console.templates=/etc/prometheus/consoles' - - '--web.enable-lifecycle' - expose: - - 9090 + prometheus: + image: prom/prometheus:latest + container_name: prometheus + restart: unless-stopped + volumes: + - ./container/prometheus.yml:/etc/prometheus/prometheus.yml + - prometheus_data:/prometheus + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + - '--web.console.libraries=/etc/prometheus/console_libraries' + - '--web.console.templates=/etc/prometheus/consoles' + - '--web.enable-lifecycle' + expose: + - 9090 - grafana: - image: grafana/grafana:latest - container_name: grafana - ports: - - "3000:3000" - environment: - - GF_SECURITY_ADMIN_PASSWORD=admin - depends_on: - - prometheus - volumes: - - ./container/grafana/prometheus.yml:/etc/grafana/provisioning/datasources/prometheus.yml - - ./container/grafana/provisioning/dashboards/dashboards.yml:/etc/grafana/provisioning/dashboards/dashboards.yml - - ./container/grafana/dashboards:/var/lib/grafana/dashboards - - grafana_data:/var/lib/grafana - # kafka: - # image: apache/kafka-native - # ports: - # - "9092:9092" - # environment: - # KAFKA_LISTENERS: CONTROLLER://localhost:9091,HOST://0.0.0.0:9092,DOCKER://0.0.0.0:9093 - # KAFKA_ADVERTISED_LISTENERS: DOCKER://kafka:9093,HOST://kafka:9092 - # KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,DOCKER:PLAINTEXT,HOST:PLAINTEXT - # - # # Settings required for KRaft mode - # KAFKA_NODE_ID: 1 - # KAFKA_PROCESS_ROLES: broker,controller - # KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER - # KAFKA_CONTROLLER_QUORUM_VOTERS: 1@localhost:9091 - # - # # Listener to use for broker-to-broker communication - # KAFKA_INTER_BROKER_LISTENER_NAME: DOCKER - # - # # Required for a single node cluster - # KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 + grafana: + image: grafana/grafana:latest + container_name: grafana + ports: + - "3000:3000" + environment: + - GF_SECURITY_ADMIN_PASSWORD=admin + depends_on: + - prometheus + volumes: + - ./container/grafana/prometheus.yml:/etc/grafana/provisioning/datasources/prometheus.yml + - ./container/grafana/provisioning/dashboards/dashboards.yml:/etc/grafana/provisioning/dashboards/dashboards.yml + - ./container/grafana/dashboards:/var/lib/grafana/dashboards + - grafana_data:/var/lib/grafana + + # kafka: + # image: apache/kafka-native + # ports: + # - "9092:9092" + # environment: + # KAFKA_LISTENERS: CONTROLLER://localhost:9091,HOST://0.0.0.0:9092,DOCKER://0.0.0.0:9093 + # KAFKA_ADVERTISED_LISTENERS: DOCKER://kafka:9093,HOST://kafka:9092 + # KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,DOCKER:PLAINTEXT,HOST:PLAINTEXT + # + # # Settings required for KRaft mode + # KAFKA_NODE_ID: 1 + # KAFKA_PROCESS_ROLES: broker,controller + # KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER + # KAFKA_CONTROLLER_QUORUM_VOTERS: 1@localhost:9091 + # + # # Listener to use for broker-to-broker communication + # KAFKA_INTER_BROKER_LISTENER_NAME: DOCKER + # + # # Required for a single node cluster + # KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 volumes: prometheus_data: diff --git a/docs/development.md b/docs/development.md index 94b8d7c4..8f4fa865 100644 --- a/docs/development.md +++ b/docs/development.md @@ -41,3 +41,20 @@ In oder to run the tests run the following command: ```bash uv run --dev pytest ``` + +## Updating the DetectMateLibrary version + +[DetectMateLibrary](https://github.com/ait-detectmate/DetectMateLibrary) ships optional +extras (`llm`, `dataframes`, `polars-rtcompat`) that the service passes through in +`pyproject.toml`. The version is pinned in exactly **one place** — the base +`detectmatelibrary==X.Y.Z` entry in `dependencies`. The `llm`/`dataframes`/ +`polars-rtcompat` extras deliberately reference `detectmatelibrary[extra]` with no +version of their own; since it's the same package name, uv/pip unify them onto +whatever version the base pin specifies. When bumping the library version: + +1. Update the single `detectmatelibrary==X.Y.Z` pin in `pyproject.toml`. +2. Run `uv lock` to regenerate `uv.lock`. +3. Run `uv sync --extra full && uv run --dev pytest` to confirm every extra still resolves and installs correctly. + +`Dockerfile`, `Dockerfile-dev`, and `scripts/change_toml.sh` don't hardcode the +library version either, so they don't need touching for a version bump. diff --git a/docs/installation.md b/docs/installation.md index 5fba05af..712ba411 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -31,5 +31,36 @@ source .venv/bin/activate pip install . ``` +## Optional library components (extras) +[DetectMateLibrary](https://github.com/ait-detectmate/DetectMateLibrary) ships some +components (e.g. LLM-backed detectors, dataframe-based persistency backends) as +optional extras rather than hard dependencies, to keep lean installs lean. The +service exposes matching pass-through extras so you only pull in what your +configured components actually need: + +| Extra | Adds | Needed for | +|---------------------|------------------------------------------|------------| +| `llm` | `openai`, `tiktoken`, `scikit-learn`, `scipy`, `tenacity` | LLM-backed detectors/parsers | +| `dataframes` | `pandas`, `polars` | Dataframe-based persistency backends and components | +| `polars-rtcompat` | `polars[rtcompat]` | Polars runtime compatibility on older CPUs | +| `full` | all of the above | Running any/all library components, e.g. local development | + +Install only what you need: + +```bash +uv sync --extra llm +# or with pip +pip install ".[llm]" +``` + +Or install everything: + +```bash +uv sync --extra full +``` + +`uv sync --dev` (used for local development, see [development.md](development.md)) +already installs the `full` extra via the `dev` dependency group, so +contributors get every optional component out of the box. diff --git a/docs/library.md b/docs/library.md index 6ea9fc1d..55de9a58 100644 --- a/docs/library.md +++ b/docs/library.md @@ -5,6 +5,13 @@ The Service can be run as any component imported from the [DetectMateLibrary](https://github.com/ait-detectmate/DetectMateLibrary). For this, ensure that the library is installed in the same activated virtual environment, where the service is installed. +> **Note:** Some library components depend on optional extras (e.g. LLM-backed +> detectors need `llm`, dataframe-based persistency backends need `dataframes`). +> If the component you want to use raises an `ImportError` mentioning a missing +> extra, install the service with the matching extra — see +> [Optional library components](installation.md#optional-library-components-extras) +> in the installation guide. + ### 1. Update settings Modify `settings.yaml` to use a library component: diff --git a/pyproject.toml b/pyproject.toml index 5063e75a..53710e66 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ requires-python = ">=3.12" dynamic = ["version"] dependencies = [ - "detectmatelibrary==0.3.1", + "detectmatelibrary==0.4.0", "pathlib>=1.0.1", "pydantic>=2.13.4", "pydantic-settings>=2.14.1", @@ -22,6 +22,18 @@ dependencies = [ "python-multipart>=0.0.20", ] +[project.optional-dependencies] +# pass-through extras for optional detectmatelibrary components, e.g. uv sync --extra llm +llm = ["detectmatelibrary[llm]==0.4.0"] +dataframes = ["detectmatelibrary[dataframes]==0.4.0"] +polars-rtcompat = ["detectmatelibrary[polars-rtcompat]==0.4.0"] +# install all optional extras at once: uv sync --extra full +full = [ + "DetectMateService[llm]", + "DetectMateService[dataframes]", + "DetectMateService[polars-rtcompat]", +] + [dependency-groups] dev = [ "mike>=2.2.0", @@ -29,6 +41,7 @@ dev = [ "prek>=0.4.5", "pytest-cov>=6.2.1", "types-requests", + "DetectMateService[full]", ] [project.scripts] diff --git a/scripts/change_toml.sh b/scripts/change_toml.sh index 3cb167a3..94466b1e 100755 --- a/scripts/change_toml.sh +++ b/scripts/change_toml.sh @@ -17,5 +17,5 @@ fi echo "Using branch: $BRANCH" -NEW_DEP="detectmatelibrary @ git+https://github.com/ait-detectmate/DetectMateLibrary.git@${BRANCH}\"" -sed -i "s|detectmatelibrary[^,]*|$NEW_DEP|g" pyproject.toml +GIT_SOURCE="git+https://github.com/ait-detectmate/DetectMateLibrary.git@${BRANCH}" +sed -i -E "s|detectmatelibrary==[^\"]+|detectmatelibrary @ ${GIT_SOURCE}|g" pyproject.toml diff --git a/uv.lock b/uv.lock index c0a4d87a..c0dad1bb 100644 --- a/uv.lock +++ b/uv.lock @@ -272,29 +272,39 @@ wheels = [ [[package]] name = "detectmatelibrary" -version = "0.3.1" +version = "0.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "detectmateperformance" }, { name = "fsspec" }, { name = "msgpack" }, { name = "numpy" }, - { name = "openai" }, - { name = "pandas" }, - { name = "polars" }, { name = "protobuf" }, { name = "pyarrow" }, { name = "pydantic" }, { name = "pyyaml" }, { name = "regex" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/f3/7397c5e667feddfcb042da2f3edf23f81ad777e798533e15f80b279378e2/detectmatelibrary-0.4.0.tar.gz", hash = "sha256:dc6bbaae82f2a0fb8c2a21fde66f9e58f1db0fa6b153e3fae9cd42ab6314bf34", size = 94244, upload-time = "2026-07-10T11:20:01.091Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/19/f7059c4b0e00fe1dc4d4d756b9266b4e1f2c8ad668599cbe815079031954/detectmatelibrary-0.4.0-py3-none-any.whl", hash = "sha256:70192525258c4878bd019a80a3c56d341891b66cdda9c1add0e007b1dd51f973", size = 134553, upload-time = "2026-07-10T11:19:59.858Z" }, +] + +[package.optional-dependencies] +dataframes = [ + { name = "pandas" }, + { name = "polars" }, +] +llm = [ + { name = "openai" }, + { name = "pandas" }, { name = "scikit-learn" }, { name = "scipy" }, { name = "tenacity" }, { name = "tiktoken" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7d/8e/ac9ebd2d1bae9d7ab28292e938e4caa961c3a529bd99bb85683a0d7a66d8/detectmatelibrary-0.3.1.tar.gz", hash = "sha256:11df9899ef47c800d9b3212519e38d8b97b89ca70896bd85826a212daf838b95", size = 135113, upload-time = "2026-06-12T10:47:55.316Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/4d/bb0f2e4c2f6d45990f04510bb2d82fbf56072c8970dcafb8bae0741bf373/detectmatelibrary-0.3.1-py3-none-any.whl", hash = "sha256:6cf54a586d9184ab93c0c5bca8dc31f4444ed7b104ecf0c220be7769bf055d32", size = 201929, upload-time = "2026-06-12T10:47:53.821Z" }, +polars-rtcompat = [ + { name = "polars", extra = ["rtcompat"] }, ] [[package]] @@ -333,8 +343,23 @@ dependencies = [ { name = "uvicorn", extra = ["standard"] }, ] +[package.optional-dependencies] +dataframes = [ + { name = "detectmatelibrary", extra = ["dataframes"] }, +] +full = [ + { name = "detectmatelibrary", extra = ["dataframes", "llm", "polars-rtcompat"] }, +] +llm = [ + { name = "detectmatelibrary", extra = ["llm"] }, +] +polars-rtcompat = [ + { name = "detectmatelibrary", extra = ["polars-rtcompat"] }, +] + [package.dev-dependencies] dev = [ + { name = "detectmateservice", extra = ["full"] }, { name = "mike" }, { name = "prek" }, { name = "pytest" }, @@ -344,7 +369,13 @@ dev = [ [package.metadata] requires-dist = [ - { name = "detectmatelibrary", specifier = "==0.3.1" }, + { name = "detectmatelibrary", specifier = "==0.4.0" }, + { name = "detectmatelibrary", extras = ["dataframes"], marker = "extra == 'dataframes'" }, + { name = "detectmatelibrary", extras = ["llm"], marker = "extra == 'llm'" }, + { name = "detectmatelibrary", extras = ["polars-rtcompat"], marker = "extra == 'polars-rtcompat'" }, + { name = "detectmateservice", extras = ["dataframes"], marker = "extra == 'full'" }, + { name = "detectmateservice", extras = ["llm"], marker = "extra == 'full'" }, + { name = "detectmateservice", extras = ["polars-rtcompat"], marker = "extra == 'full'" }, { name = "fastapi", specifier = ">=0.137.1" }, { name = "httpx", specifier = ">=0.28.1" }, { name = "pathlib", specifier = ">=1.0.1" }, @@ -358,9 +389,11 @@ requires-dist = [ { name = "types-pyyaml", specifier = ">=6.0.12.20260518" }, { name = "uvicorn", extras = ["standard"], specifier = ">=0.49.0" }, ] +provides-extras = ["llm", "dataframes", "polars-rtcompat", "full"] [package.metadata.requires-dev] dev = [ + { name = "detectmateservice", extras = ["full"] }, { name = "mike", specifier = ">=2.2.0" }, { name = "prek", specifier = ">=0.4.5" }, { name = "pytest", specifier = ">=9.1.0" }, @@ -1040,6 +1073,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1f/22/28f62d24f7db56ac4343588f9362d49b7b4177e55ac47a466fe696b0099b/polars-1.41.2-py3-none-any.whl", hash = "sha256:23ce9a2910b6e3e8d4258770bf44aa17170958df7af6e85feedf4458a04d8d29", size = 833445, upload-time = "2026-05-29T17:37:05.576Z" }, ] +[package.optional-dependencies] +rtcompat = [ + { name = "polars-runtime-compat" }, +] + [[package]] name = "polars-runtime-32" version = "1.41.2" @@ -1056,6 +1094,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cd/c6/79e9f3f270270d7ed5575d92b7bfef49f01abd9275447161275b23b553a8/polars_runtime_32-1.41.2-cp310-abi3-win_arm64.whl", hash = "sha256:843d96f69d18eca53429c1198e58891db7f18111f83b9c419bb45ad9d73eaed5", size = 46006901, upload-time = "2026-05-29T17:37:42.522Z" }, ] +[[package]] +name = "polars-runtime-compat" +version = "1.41.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/50/3c/a274ecfeb1f39231e166d3b7df87674865211abc00dc42c2c57e9709dd80/polars_runtime_compat-1.41.2.tar.gz", hash = "sha256:cdd12ca3d79cc9748b6217dc969f8b3a3b282effa1b088aab00595ed86947f09", size = 2990973, upload-time = "2026-05-29T17:39:21.364Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/53/b9/f6d13337327c6a6aecb9eb615bafc09cee1c7fb02bdeecb838e14f7bae68/polars_runtime_compat-1.41.2-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:c9646fc527ac8167adc681b17b78370e3064ef7ff3fe6a4253626fbef76bf3ea", size = 52212192, upload-time = "2026-05-29T17:38:32.948Z" }, + { url = "https://files.pythonhosted.org/packages/cc/ce/b94ebe08e916a9478a1b99eb31616d70a4e28999cfb85e611d1c658e1302/polars_runtime_compat-1.41.2-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:84c4b9629fa43fe0627149d539424573a51f7b3e6450e4f33e6de474739d4d4d", size = 46431731, upload-time = "2026-05-29T17:38:38.358Z" }, + { url = "https://files.pythonhosted.org/packages/15/86/217be7207d7da90f744be26ad17658ff6251d6d8212c15df590b3fd6aed5/polars_runtime_compat-1.41.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad7042bf2d33a98b913e545705552f916fc95c508962a0b4f29dc25aeab247e4", size = 50273757, upload-time = "2026-05-29T17:38:43.339Z" }, + { url = "https://files.pythonhosted.org/packages/d2/da/50bc1943028fd56c59d82a6e1185dd1076f312326aa24040027ba9f623fc/polars_runtime_compat-1.41.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16f80d5f171c8ba1b2d351d0462f4d99a911aa5cb7c17833e01a1589de272837", size = 56049955, upload-time = "2026-05-29T17:38:52.841Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f5/51a9ed2baa9d65cbc4c97210c690a0bd5ac29432684a78c19c3bd00e49fc/polars_runtime_compat-1.41.2-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:50576d8d190effd7167a81361060993d00f7a90ef58b5b1c2a71b241f5771580", size = 50443852, upload-time = "2026-05-29T17:38:57.709Z" }, + { url = "https://files.pythonhosted.org/packages/8b/5d/928656351ce28c13559b1126ba64dcb266f93022b98838c6fc396f3167c3/polars_runtime_compat-1.41.2-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:33e46cf96175794827a85ec010826b04f54d074ea4f9bb37af572982be0f0e76", size = 53939413, upload-time = "2026-05-29T17:39:02.908Z" }, + { url = "https://files.pythonhosted.org/packages/04/e6/7c64efd7ec8c39e9a7a6bee4798caac0bf46a5398278f1957c180f480c8e/polars_runtime_compat-1.41.2-cp310-abi3-win_amd64.whl", hash = "sha256:42c207b8319e85f861eb673c2ca18260a0159161a2aaa997ef2754af56a81586", size = 51852978, upload-time = "2026-05-29T17:39:07.83Z" }, + { url = "https://files.pythonhosted.org/packages/b5/d2/d13ff429824e9ec0c5d4cad9540b90b3c529f33e9f7004abd7eec9b987b8/polars_runtime_compat-1.41.2-cp310-abi3-win_arm64.whl", hash = "sha256:fb28837bec86a064ebe49907bbcbdc365919c80c99b920f2ad9ebc1ceed9ea3a", size = 45900408, upload-time = "2026-05-29T17:39:12.945Z" }, +] + [[package]] name = "prek" version = "0.4.5" From e7a0e3e69b8a051203b5e3c7edd3f6fee4ee635d Mon Sep 17 00:00:00 2001 From: thorinaboenke Date: Fri, 10 Jul 2026 14:00:17 +0200 Subject: [PATCH 2/5] dockerfile dev with install extras --- Dockerfile-dev | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Dockerfile-dev b/Dockerfile-dev index 4943ffb5..b22a9f04 100644 --- a/Dockerfile-dev +++ b/Dockerfile-dev @@ -3,6 +3,11 @@ FROM python:3.14-slim WORKDIR /app ARG DETECTMATELIBRARY_BRANCH=development +# Comma-separated detectmatelibrary extras to install, e.g. "llm,dataframes". +# Defaults to "full" (all optional components available). Pass an empty +# string to install only the base library. +ARG LIBRARY_EXTRAS=full + # Install system dependencies RUN apt-get update && \ apt-get install -y --no-install-recommends \ @@ -15,11 +20,19 @@ COPY pyproject.toml README.md ./ COPY ./src ./src COPY ./tests ./tests -RUN uv pip install --system . +RUN if [ -n "$LIBRARY_EXTRAS" ]; then \ + uv pip install --system ".[$LIBRARY_EXTRAS]" ; \ + else \ + uv pip install --system . ; \ + fi RUN if [ "$DETECTMATELIBRARY_BRANCH" != "main" ]; then \ uv pip uninstall --system detectmatelibrary && \ + if [ -n "$LIBRARY_EXTRAS" ]; then \ + uv pip install --system "detectmatelibrary[$LIBRARY_EXTRAS] @ git+https://github.com/ait-detectmate/DetectMateLibrary.git@$DETECTMATELIBRARY_BRANCH" ; \ + else \ uv pip install --system "detectmatelibrary @ git+https://github.com/ait-detectmate/DetectMateLibrary.git@$DETECTMATELIBRARY_BRANCH" ; \ + fi ; \ fi CMD ["detectmate", "--help"] From 3a3b95d808b6b7e5450c00ad3bd2325ffa33a0db Mon Sep 17 00:00:00 2001 From: thorinaboenke Date: Fri, 10 Jul 2026 14:04:43 +0200 Subject: [PATCH 3/5] update docs on release process! --- docs/release.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/release.md b/docs/release.md index 8da45758..020da3b4 100644 --- a/docs/release.md +++ b/docs/release.md @@ -29,7 +29,8 @@ Open a pull request to merge the `development` branch into `main`. Once CI passe !!! note - Merging `development` into `main` will delete the `development` branch. See the last step for how to recreate it. + Merging `development` into `main` will delete the `development` branch. A GitHub Actions + workflow (`recreate-development-branch.yml`) automatically recreates it from `main`, see the last step for details and the manual fallback. ### 3. Determine the new version number @@ -79,7 +80,13 @@ Monitor the [Actions tab](https://github.com/ait-detectmate/DetectMateService/ac ### 7. Recreate the development branch -Because merging `development` into `main` deletes the `development` branch, create a new one branching from the now-updated `main`: +Because merging `development` into `main` deletes the `development` branch, it needs to be +recreated from the now-updated `main`. This happens automatically: `.github/workflows/recreate-development-branch.yml` +listens for the branch deletion and pushes a new `development` branch from `main` for you. +Check the [Actions tab](https://github.com/ait-detectmate/DetectMateService/actions) to confirm +it ran successfully. + +If the workflow fails or you need to do it manually: ```bash git checkout main From a21abf2ffb87714c54b0b8f4faeffad6fbdb2e8f Mon Sep 17 00:00:00 2001 From: thorinaboenke Date: Fri, 10 Jul 2026 14:27:59 +0200 Subject: [PATCH 4/5] optional dependencies in docker images --- docs/installation.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/installation.md b/docs/installation.md index 712ba411..4cce7851 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -64,3 +64,19 @@ uv sync --extra full already installs the `full` extra via the `dev` dependency group, so contributors get every optional component out of the box. +### Extras in Docker + +`Dockerfile` and `Dockerfile-dev` take a `LIBRARY_EXTRAS` build arg (comma-separated +extras, default `full`) that controls which extras get installed in the image: + +```bash +docker build --build-arg LIBRARY_EXTRAS=llm,dataframes -t detectmate . +``` + +With `docker compose`, set the `LIBRARY_EXTRAS` env var before building (it defaults +to `full` if unset): + +```bash +LIBRARY_EXTRAS=llm docker compose build parser detector +``` + From 647a7896c5873104eaa01bb95eaa04b00243e9fc Mon Sep 17 00:00:00 2001 From: thorinaboenke Date: Fri, 10 Jul 2026 15:09:09 +0200 Subject: [PATCH 5/5] simplify pyproject.toml --- pyproject.toml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 53710e66..17d4a32d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,10 @@ requires-python = ">=3.12" dynamic = ["version"] +# NOTE: this is the only place detectmatelibrary's version is pinned. The +# llm/dataframes/polars-rtcompat extras below deliberately reference +# detectmatelibrary[extra] with no version — since it's the same package name, +# uv/pip unify it to this pin. Bump here, then run `uv lock`. dependencies = [ "detectmatelibrary==0.4.0", "pathlib>=1.0.1", @@ -24,9 +28,9 @@ dependencies = [ [project.optional-dependencies] # pass-through extras for optional detectmatelibrary components, e.g. uv sync --extra llm -llm = ["detectmatelibrary[llm]==0.4.0"] -dataframes = ["detectmatelibrary[dataframes]==0.4.0"] -polars-rtcompat = ["detectmatelibrary[polars-rtcompat]==0.4.0"] +llm = ["detectmatelibrary[llm]"] +dataframes = ["detectmatelibrary[dataframes]"] +polars-rtcompat = ["detectmatelibrary[polars-rtcompat]"] # install all optional extras at once: uv sync --extra full full = [ "DetectMateService[llm]",