From b66f24285cb7060031e1a2d229b3a96d0157719e Mon Sep 17 00:00:00 2001 From: Nelson PROIA Date: Tue, 10 Feb 2026 16:27:29 +0100 Subject: [PATCH 1/5] feat: add workflows namespace sub-package extras Add optional dependencies for mistralai-workflows and its plugin extras, enabling `pip install mistralai[workflows]` and `pip install mistralai[workflows-mistralai]`. Document the PEP 420 namespace sub-package pattern in README. Co-Authored-By: Claude Opus 4.6 --- README.md | 23 ++++++++++++++++++++++- pyproject.toml | 6 ++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f31ccf2..52bb2e91 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ Once that is saved to a file, you can run it with `uv run script.py` where ### Agents extra dependencies -When using the agents related feature it is required to add the `agents` extra dependencies. This can be added when +When using the agents related feature it is required to add the `agents` extra dependencies. This can be added when installing the package: ```bash @@ -127,6 +127,27 @@ pip install "mistralai[agents]" > Note: These features require Python 3.10+ (the SDK minimum). +### Namespace Sub-packages + +`mistralai` uses [PEP 420](https://peps.python.org/pep-0420/) implicit namespace packages. Separate PyPI packages (e.g. `mistralai-workflows`) install under the shared `mistralai` namespace with no `__init__.py` at the top level. They are exposed here as optional extras: + +```bash +pip install "mistralai[workflows]" +``` + +If a sub-package has its own plugin extras, they are mirrored as flat extras: + +```toml +# pyproject.toml +[project.optional-dependencies] +workflows = ["mistralai-workflows>=2.0.0"] +workflows-mistralai = ["mistralai-workflows[mistralai]>=2.0.0"] +``` + +```bash +pip install "mistralai[workflows-mistralai]" +``` + ## SDK Example Usage diff --git a/pyproject.toml b/pyproject.toml index 7209c64c..6205a3c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,6 +32,12 @@ agents = [ realtime = [ "websockets >=13.0", ] +workflows = [ + "mistralai-workflows>=2.0.0", +] +workflows-mistralai = [ + "mistralai-workflows[mistralai]>=2.0.0", +] [project.urls] Repository = "https://github.com/mistralai/client-python.git" From 93c8fa2ac308d923fcbcf6b3a607c4283cae4b7d Mon Sep 17 00:00:00 2001 From: Nelson PROIA Date: Wed, 11 Feb 2026 09:51:49 +0100 Subject: [PATCH 2/5] pyproject.toml: mistralai-workflows>=2.0.0 -> mistralai-workflows>=2.0.0b1 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6205a3c5..5e163bc8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,10 +33,10 @@ realtime = [ "websockets >=13.0", ] workflows = [ - "mistralai-workflows>=2.0.0", + "mistralai-workflows>=2.0.0b1", ] workflows-mistralai = [ - "mistralai-workflows[mistralai]>=2.0.0", + "mistralai-workflows[mistralai]>=2.0.01", ] [project.urls] From 9a71b311d8a86de6e3ba9b699ccb20defd3f9bba Mon Sep 17 00:00:00 2001 From: Nelson PROIA Date: Wed, 11 Feb 2026 10:00:40 +0100 Subject: [PATCH 3/5] pyproject.toml: mistralai-workflows>=2.0.0 -> mistralai-workflows>=2.0.0b1 (erratum) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5e163bc8..07ffdf42 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ workflows = [ "mistralai-workflows>=2.0.0b1", ] workflows-mistralai = [ - "mistralai-workflows[mistralai]>=2.0.01", + "mistralai-workflows[mistralai]>=2.0.0b1", ] [project.urls] From 02bffb19298f51a2644aafbe6936d32bd4a2e799 Mon Sep 17 00:00:00 2001 From: Nelson PROIA Date: Wed, 11 Feb 2026 14:38:25 +0100 Subject: [PATCH 4/5] Updating README.md to clarify sub-packages + extras install --- README.md | 23 ++++++++++++++++------- pyproject.toml | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 52bb2e91..f96ce89e 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ When using the agents related feature it is required to add the `agents` extra d installing the package: ```bash -pip install "mistralai[agents]" +uv add "mistralai[agents]" ``` > Note: These features require Python 3.10+ (the SDK minimum). @@ -132,20 +132,29 @@ pip install "mistralai[agents]" `mistralai` uses [PEP 420](https://peps.python.org/pep-0420/) implicit namespace packages. Separate PyPI packages (e.g. `mistralai-workflows`) install under the shared `mistralai` namespace with no `__init__.py` at the top level. They are exposed here as optional extras: ```bash -pip install "mistralai[workflows]" +uv add "mistralai[workflows]" ``` -If a sub-package has its own plugin extras, they are mirrored as flat extras: +If a sub-package has its own plugin extras, they are mirrored as flat extras in this repo's `pyproject.toml`. When a new plugin is added to a sub-package, a corresponding entry must be added here: ```toml # pyproject.toml [project.optional-dependencies] -workflows = ["mistralai-workflows>=2.0.0"] -workflows-mistralai = ["mistralai-workflows[mistralai]>=2.0.0"] + = ["mistralai->=2.0.0"] +- = ["mistralai-[]>=2.0.0"] ``` +Example with workflows: + +```bash +uv add "mistralai[workflows]" # core +uv add "mistralai[workflows-mistralai]" # core + plugin +``` + +Sub-package plugins can also be installed directly, bypassing the `mistralai` extras: + ```bash -pip install "mistralai[workflows-mistralai]" +uv add "mistralai-workflows[mistralai]" ``` @@ -431,7 +440,7 @@ gcloud auth application-default login Install the extras dependencies specific to Google Cloud: ```bash -pip install mistralai[gcp] +uv add "mistralai[gcp]" ``` **Step 2: Example Usage** diff --git a/pyproject.toml b/pyproject.toml index 07ffdf42..7855e07f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ dependencies = [ "opentelemetry-sdk (>=1.33.1,<2.0.0)", "opentelemetry-api (>=1.33.1,<2.0.0)", "opentelemetry-exporter-otlp-proto-http (>=1.37.0,<2.0.0)", - "opentelemetry-semantic-conventions (>=0.59b0,<0.60)", + "opentelemetry-semantic-conventions (>=0.59b0,<0.61)", ] [project.optional-dependencies] From 5ba1a5111ebba4c03a5be3991e71833660da13e3 Mon Sep 17 00:00:00 2001 From: Nelson PROIA Date: Thu, 12 Feb 2026 10:08:38 +0100 Subject: [PATCH 5/5] Drop workflows syntactic sugar from optional dependencies --- README.md | 27 +++---------------- pyproject.toml | 6 ----- scripts/test_namespace.sh | 57 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 30 deletions(-) create mode 100755 scripts/test_namespace.sh diff --git a/README.md b/README.md index f96ce89e..1432ced6 100644 --- a/README.md +++ b/README.md @@ -129,32 +129,11 @@ uv add "mistralai[agents]" ### Namespace Sub-packages -`mistralai` uses [PEP 420](https://peps.python.org/pep-0420/) implicit namespace packages. Separate PyPI packages (e.g. `mistralai-workflows`) install under the shared `mistralai` namespace with no `__init__.py` at the top level. They are exposed here as optional extras: +`mistralai` uses [PEP 420](https://peps.python.org/pep-0420/) implicit namespace packages. Separate PyPI packages (e.g. `mistralai-workflows`) install under the shared `mistralai` namespace with no `__init__.py` at the top level. Install them directly: ```bash -uv add "mistralai[workflows]" -``` - -If a sub-package has its own plugin extras, they are mirrored as flat extras in this repo's `pyproject.toml`. When a new plugin is added to a sub-package, a corresponding entry must be added here: - -```toml -# pyproject.toml -[project.optional-dependencies] - = ["mistralai->=2.0.0"] -- = ["mistralai-[]>=2.0.0"] -``` - -Example with workflows: - -```bash -uv add "mistralai[workflows]" # core -uv add "mistralai[workflows-mistralai]" # core + plugin -``` - -Sub-package plugins can also be installed directly, bypassing the `mistralai` extras: - -```bash -uv add "mistralai-workflows[mistralai]" +uv add mistralai-workflows # core +uv add "mistralai-workflows[mistralai]" # core + plugin ``` diff --git a/pyproject.toml b/pyproject.toml index 7855e07f..5802feaa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,12 +32,6 @@ agents = [ realtime = [ "websockets >=13.0", ] -workflows = [ - "mistralai-workflows>=2.0.0b1", -] -workflows-mistralai = [ - "mistralai-workflows[mistralai]>=2.0.0b1", -] [project.urls] Repository = "https://github.com/mistralai/client-python.git" diff --git a/scripts/test_namespace.sh b/scripts/test_namespace.sh new file mode 100755 index 00000000..82d6bf29 --- /dev/null +++ b/scripts/test_namespace.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +set -euo pipefail + +CLIENT_WHL="${1:?Usage: $0 }" +WORKFLOWS_WHL="${2:?Usage: $0 }" +VENV="/tmp/test-pep420-ns" +PYTHON="${PYTHON:-python3.12}" + +cleanup() { rm -rf "$VENV"; } +trap cleanup EXIT + +echo "=== Creating clean venv ($PYTHON) ===" +"$PYTHON" -m venv "$VENV" +source "$VENV/bin/activate" + +echo "" +echo "=== Test 1: Client only ===" +pip install --quiet "$CLIENT_WHL" +python -c "from mistralai.client import Mistral; print(' client import: OK')" +python -c " +try: + from mistralai.workflows import workflow + print(' FAIL: workflows should not be importable') + exit(1) +except ImportError: + print(' workflows not importable (expected): OK') +" + +echo "" +echo "=== Test 2: No __init__.py at namespace level ===" +python -c " +import pathlib, sysconfig +ns = pathlib.Path(sysconfig.get_path('purelib')) / 'mistralai' / '__init__.py' +if ns.exists(): + print(' FAIL: mistralai/__init__.py exists (breaks PEP 420)') + exit(1) +else: + print(' no mistralai/__init__.py: OK') +" + +echo "" +echo "=== Test 3: Client + workflows ===" +pip install --quiet "$WORKFLOWS_WHL" +python -c "from mistralai.client import Mistral; print(' client import: OK')" +python -c "from mistralai.workflows import workflow; print(' workflows import: OK')" + +echo "" +echo "=== Test 4: Namespace directory listing ===" +python -c " +import pathlib, sysconfig +ns = pathlib.Path(sysconfig.get_path('purelib')) / 'mistralai' +for p in sorted(ns.iterdir()): + print(f' {p.name}/') +" + +echo "" +echo "=== All tests passed ==="