Repository navigation
packaging: move the Ollama client behind a [semantic] extra - #83
Conversation
`ollama` was a hard dependency, so a keyword-only install pulled the client
without being told. It is now the `semantic` extra, and the import failure
names the install step instead of surfacing as a bare ModuleNotFoundError:
pip install "opensdmx[semantic]"
Importing stays safe (`from opensdmx import semantic_search` keeps working);
only calling semantic_search/build_embeddings without the extra raises.
`numpy` stays a hard dependency on purpose, against the issue's first proposal:
the default keyword path ranks with BM25 in `ranking.py`, which is numpy-based
(`ranking.py:75-128`, called from `discovery.py:408-432`). Making it optional
means a numpy-free scorer, which is a separate change.
Refs ondata#75
|
[Medium risk] Moves Ollama client to an optional dependency. The PR appears safe to merge; no blocking issue remains. SummaryMoves the Ollama Python client into the
Reviews (4) · Last reviewed commit: "docs: name the [semantic] extra in the s..." |
…test search `run_guide` falls back to `semantic_search` when no dataset is supplied (guide.py:72), so moving the client out of the required dependencies broke `opensdmx[guide]` installs with an ImportError. `[guide]` now carries it too, and the dev environment — which installs `opensdmx[guide]` — is the proof: `ollama 0.6.1` is back in it. The keyword test called `ranking.tokenize`, so it passed without ever running a search. It now runs the real `search_dataset` over the stub catalog, with the client hidden, and asserts it finds the dataset.
|
Both findings addressed in 1. 2. The keyword test never searched. Right — it called
|
aborruso
left a comment
There was a problem hiding this comment.
@paoValle thanks. I checked the branch at c97c0ba: 410 passed, ruff and mypy clean. I also built the wheel and installed it in two empty venvs: without the extra ollama is not installed, import opensdmx and keyword search work; with [semantic] the client is there. On numpy you are right: ranking.py builds BM25 on it, so it has to stay.
One bug and a couple of smaller points inline. Two more that have no line in the diff:
docs/search.md:12still says only that semantic search needs a reachable Ollama server. I think it should mention the extra too.LOG.mdand the release note: I'll write them at release time, no need to add them here.
| # Semantic search (`search --semantic`, `embed`, `semantic_search`, | ||
| # `build_embeddings`). numpy stays a hard dependency: the default keyword path | ||
| # ranks with BM25 in ranking.py, which is numpy-based (discovery.py:408-432). | ||
| semantic = [ |
There was a problem hiding this comment.
A question about the name rather than a change request. The semantic backend is an open question (#77: a static retriever might replace Ollama). If that happens, [semantic] would mean something different from today. Would it be better to name the extra after the backend ([ollama]), or do we keep [semantic] as the stable name and change what it contains later?
There was a problem hiding this comment.
@paoValle agreed, let's keep [semantic]. One thing left: docs/search.md:12 still says only that semantic search needs a reachable Ollama server. Could you mention the extra there too?
Rich parses `[semantic]` as markup when the message is printed, so the hint came out as `pip install "opensdmx"`. The two semantic handlers (search --semantic, embed) now escape the message, the hint also names the uv tool install command, and the two packaging tests share one pyproject fixture. Two CliRunner tests pin the CLI output and fail without the escape.
|
All three covered in 1. Rich was eating Two CliRunner tests ( 2. Extra naming. I would keep 3. Test duplication. The two packaging tests now share a session-scoped Verification on the PR head: |
Without it, a fresh install reading the doc learns only about the Ollama server and finds out about the extra from the CLI error instead.
|
Done — |
Implements #75 for the
ollamapart.numpystays a hard dependency, and the reason is below: moving both as the issue first proposed would break the default search path.What changes
ollamaleavesdependenciesand becomes thesemanticextra inpyproject.toml(uv.lockregenerated).embed.pyimports the client lazily and, when it is missing, raises anImportErrorthat names what to install:Deprecation path:
from opensdmx import semantic_searchkeeps working, because the client is only imported when the function is called. Only a caller that actually callssemantic_search/build_embeddingswithout the extra breaks, and it gets an error that says how to fix it (in the CLI this already goes throughexcept Exception as e→Error: ..., so no traceback).README: the extra is named in the install section and in "Semantic search / Setup".
Why
numpycannot moveThe issue states that only
search --semantic,embedandguideuse numpy. That is not the case: the keyword ranking (the default path) is BM25 implemented on numpy —ranking.py:75-128usesnp.array,np.fromiter,np.nonzero, anddiscovery.py:408-432calls it on everyopensdmx search. Moving it behind the extra would break default keyword search.Making numpy optional as well needs a numpy-free scorer (or a pure-Python fallback with benchmarks), which is a change of its own; I left it out of this PR. Happy to open a separate issue describing it if you want.
Verification
tests/test_semantic_extra.py:_require_ollama/semantic_search/build_embeddingsall name the extra when the client is missing (client hidden throughsys.modules), the keyword path does not need it, and a packaging regression test keepsollamain the extra and out of the mandatory dependencies.uv run pytest tests/ -v→ 409 passed (the dev environment now genuinely runs withoutollama, so the ImportError path is exercised for real rather than through an importorskip).uv run ruff check src/anduv run mypyclean.I did not touch
LOG.md: the release note is yours to write with the format and measurements you normally use — tell me how to title it if you would rather I add it.