From 41227379a9b3b9a5d78bc7ed6c6c1a4730220913 Mon Sep 17 00:00:00 2001 From: Sebastien Larinier Date: Tue, 4 Aug 2026 17:06:49 +0200 Subject: [PATCH 1/3] refactor: move typer and rich from runtime deps to new [cli] extra --- pyproject.toml | 14 ++++++++++++-- uv.lock | 16 +++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7bfa1ed..0810876 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,12 +31,19 @@ dependencies = [ "httpx>=0.28", "pydantic>=2.11", "python-dotenv>=1.1", - "rich>=14.0", - "typer>=0.16", "tomli>=2.0; python_version < '3.11'", ] [project.optional-dependencies] +# Only `cli.py` imports typer and rich, so they do not belong to the library. +# Declaring them at runtime imposed rich>=14 on every consumer, which collides +# with pins such as censys==2.0.9 (rich<11) and made pyonyphe unresolvable in +# projects that merely import the client. typer is here too because it pulls +# rich in on its own. +cli = [ + "rich>=14.0", + "typer>=0.16", +] # SDK v2: `FastMCP` became `MCPServer` and the import paths moved, so the # major is pinned rather than left open. mcp = ["mcp>=2,<3"] @@ -64,6 +71,9 @@ dev = [ "twine>=6.1", # The MCP extra, so the server is importable in the test suite. "mcp>=2,<3", + # The CLI extra, so the cli tests still run from a bare dev install. + "rich>=14.0", + "typer>=0.16", # Not needed at runtime on 3.11+, but ty analyses against 3.10 and has to # be able to resolve the fallback import in config.py. "tomli>=2.0", diff --git a/uv.lock b/uv.lock index a3572e5..cd5d347 100644 --- a/uv.lock +++ b/uv.lock @@ -1048,12 +1048,14 @@ dependencies = [ { name = "httpx" }, { name = "pydantic" }, { name = "python-dotenv" }, - { name = "rich" }, { name = "tomli", marker = "python_full_version < '3.11'" }, - { name = "typer" }, ] [package.optional-dependencies] +cli = [ + { name = "rich" }, + { name = "typer" }, +] mcp = [ { name = "mcp" }, ] @@ -1066,10 +1068,12 @@ dev = [ { name = "pytest-asyncio" }, { name = "pytest-cov" }, { name = "respx" }, + { name = "rich" }, { name = "ruff" }, { name = "tomli" }, { name = "twine" }, { name = "ty" }, + { name = "typer" }, { name = "zizmor" }, ] @@ -1079,11 +1083,11 @@ requires-dist = [ { name = "mcp", marker = "extra == 'mcp'", specifier = ">=2,<3" }, { name = "pydantic", specifier = ">=2.11" }, { name = "python-dotenv", specifier = ">=1.1" }, - { name = "rich", specifier = ">=14.0" }, + { name = "rich", marker = "extra == 'cli'", specifier = ">=14.0" }, { name = "tomli", marker = "python_full_version < '3.11'", specifier = ">=2.0" }, - { name = "typer", specifier = ">=0.16" }, + { name = "typer", marker = "extra == 'cli'", specifier = ">=0.16" }, ] -provides-extras = ["mcp"] +provides-extras = ["cli", "mcp"] [package.metadata.requires-dev] dev = [ @@ -1093,10 +1097,12 @@ dev = [ { name = "pytest-asyncio", specifier = ">=0.25" }, { name = "pytest-cov", specifier = ">=6.0" }, { name = "respx", specifier = ">=0.22" }, + { name = "rich", specifier = ">=14.0" }, { name = "ruff", specifier = ">=0.12" }, { name = "tomli", specifier = ">=2.0" }, { name = "twine", specifier = ">=6.1" }, { name = "ty", specifier = ">=0.0.50" }, + { name = "typer", specifier = ">=0.16" }, { name = "zizmor", specifier = ">=1.28" }, ] From ce88df067dc069beb08492d9791cc263e434f7c1 Mon Sep 17 00:00:00 2001 From: Sebastien Larinier Date: Tue, 4 Aug 2026 17:06:49 +0200 Subject: [PATCH 2/3] docker: install the [cli] extra so the container image still ships the CLI --- Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 28e876e..a6aeb52 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,12 +23,14 @@ ENV UV_COMPILE_BYTECODE=1 \ WORKDIR /app # Dependencies first: this layer is cached until pyproject.toml or uv.lock move. +# --extra cli is required since 3.1.0: typer and rich moved out of the runtime +# dependencies, and the image exists to ship the CLI. COPY pyproject.toml uv.lock ./ -RUN uv sync --frozen --no-dev --no-install-project +RUN uv sync --frozen --no-dev --no-install-project --extra cli COPY README.md LICENSE ./ COPY src ./src -RUN uv sync --frozen --no-dev --no-editable +RUN uv sync --frozen --no-dev --no-editable --extra cli FROM python:3.13-slim-bookworm From 9a977a3601bd0db641007eb3178bfa33c4318133 Mon Sep 17 00:00:00 2001 From: Sebastien Larinier Date: Tue, 4 Aug 2026 17:06:49 +0200 Subject: [PATCH 3/3] docs: update README and CHANGELOG to document the [cli] extra requirement --- CHANGELOG.md | 21 +++++++++++++++++++++ README.md | 13 +++++++++++++ 2 files changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 855256b..33996e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,27 @@ All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.1.0] - 2026-08-04 + +### Changed + +- **Breaking for CLI users.** `typer` and `rich` moved out of the runtime + dependencies into a new `cli` extra. Only the CLI module imports them, but + declaring them at runtime forced `rich>=14` onto every project that merely + imported the client, which made pyonyphe unresolvable alongside pins such as + `censys==2.0.9` (`rich<11`). + + Installing the library is unchanged. To get the `pyonyphe` command, install + the extra: + + ``` + uv add 'pyonyphe[cli]' + ``` + + Without it, importing `pyonyphe` still works; running `pyonyphe` fails with + `ModuleNotFoundError: typer`. The published container image is unaffected — + it installs the extra. + ## [3.0.2] - 2026-08-04 ### Fixed diff --git a/README.md b/README.md index 14e957f..293f74d 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,22 @@ the Cyber Defense Search Engine. ## Install +The library on its own: + ```bash uv add pyonyphe +``` + +The `pyonyphe` command needs the `cli` extra, which pulls in Typer and Rich: + +```bash +uv add 'pyonyphe[cli]' uv run pyonyphe --help ``` +Since 3.1.0 those two are no longer runtime dependencies, so importing the +client no longer constrains `rich` in your own resolution. + ## Library ```python @@ -56,6 +67,8 @@ asyncio.run(main()) ## CLI +Needs `uv add 'pyonyphe[cli]'`, or use the container image below. + ```bash export ONYPHE_API_KEY=...