Add test suite and CI, fix six backend bugs, automate releases - #42
Merged
Conversation
Brings the repo in line with the JMLR MLOSS track's expectations, which require extensive testing, continuous integration, developer docs, and per-file licensing. Tests (new, 338 tests, 98% coverage): - Cover every module: loader, metadata stores, all four vector stores, embedding backends, captioner, agent tools, SearchEngine, and the v2 Search_Setup shim. - No model downloads and no servers. open_clip, timm, openai and psycopg2 are faked; Chroma and Qdrant run in-process. Full suite runs in ~6s. Bugs the tests found, all user-facing: - index_type="ivf" segfaulted the interpreter on every use. The FAISS quantizer was garbage-collected while IndexIVFFlat still held a raw pointer to it, and FAISS's OpenMP k-means clashed with torch's runtime. - On macOS, any FAISS search aborted with "OMP: Error #15" because torch and faiss-cpu vendor separate copies of libomp.dylib. Suppressing the abort alone turns it into a segfault in FAISS's parallel routines, so DeepImageSearch/_openmp.py both sets KMP_DUPLICATE_LIB_OK and pins FAISS to one thread when it detects the duplicate. - create_langchain_tool() raised NameError on every call: a pydantic field shadowed the `k` parameter inside the class body. - The MCP server failed against mcp >= 2.0, which renamed FastMCP to MCPServer; both import paths are now supported. - Qdrant search failed against qdrant-client >= 1.12, which removed QdrantClient.search() in favour of query_points(). - ChromaStore.add() rejected vectors added without metadata, and returned None instead of {} for their metadata on search. - FAISSStore.delete() raised ValueError when every vector was deleted. - PostgresMetadataStore.__del__ raised AttributeError when the connection was never established. - __version__ said 3.0.0 while the package shipped 3.0.2. CI (new): - Lint, tests on Python 3.10-3.13 across Linux/macOS/Windows with all extras installed and a 90% coverage floor, plus a packaging check. Packaging and docs: - Add .gitignore, CONTRIBUTING.md, CITATION.cff, and an SPDX header on every source file. - Remove setup.cfg, which referenced a non-existent README.rst. - Replace the logo with the new banner, trimmed to its content bounds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Releases were manual. Now pushing a v* tag builds, verifies, and publishes to PyPI using Trusted Publishing (OIDC), so no API token is stored in GitHub secrets. - .github/workflows/release.yml: builds and twine-checks the artifacts, then publishes from a separate job holding the id-token permission and a "pypi" environment, which can carry a manual approval gate. It refuses to build when the tag does not match the version in pyproject.toml — PyPI does not allow reuploading a version, so a mismatch is unrecoverable. - scripts/bump_version.py: updates the version in pyproject.toml, DeepImageSearch/__init__.py and CITATION.cff together, and exits non-zero rather than silently skipping a file whose format has drifted. - Cover the script with 15 tests, including one that runs it against the real repo layout so the patterns cannot rot unnoticed. - Document the release process in CONTRIBUTING.md, including the one-time PyPI trusted-publisher setup. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
TechyNilesh
added a commit
that referenced
this pull request
Aug 15, 2026
Ships the backend fixes from #42: the IVF segfault, the macOS OpenMP abort, the broken LangChain tool, and the MCP and Qdrant integrations that no longer worked against current versions of their SDKs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
TechyNilesh
added a commit
that referenced
this pull request
Aug 15, 2026
Ships the backend fixes from #42: the IVF segfault, the macOS OpenMP abort, the broken LangChain tool, and the MCP and Qdrant integrations that no longer worked against current versions of their SDKs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings the repo in line with the JMLR MLOSS track requirements — extensive testing, continuous integration, developer documentation, and per-file licensing — and fixes the bugs that writing the tests uncovered.
Bugs fixed
All of these are in the currently published 3.0.2 release:
index_type="ivf"segfaulted the interpreter on every usetorchandfaiss-cpuvendor separatelibomp.dylibcopiesOMP: Error #15; suppressing that turns it into a segfault in FAISS's parallel routines, so both are handledkparameter in a class bodycreate_langchain_tool()raisedNameErroron every callFastMCPtoMCPServerQdrantClient.search()query_points()with a fallbackChromaStore.add()sent empty metadata dictsNoneinstead of{}on searchnp.vstack([])on a full deleteFAISSStore.delete()raisedValueError__del__ran on a partially built objectPostgresMetadataStore.__del__raisedAttributeError__version__said 3.0.0 while the package shipped 3.0.2Tests
353 tests, 98% coverage, ~6s. No model downloads and no servers:
open_clip,timm,openaiandpsycopg2are faked, while Chroma and Qdrant run in-process. Coverage went from 57% to 98%.CI and releases
ci.yml— lint, tests on Python 3.10–3.13 across Linux/macOS/Windows with all extras installed and a 90% coverage floor, plus a packaging check.release.yml— pushing av*tag builds, verifies and publishes to PyPI via Trusted Publishing (OIDC, no stored token). Refuses to build if the tag does not match the packaged version, since PyPI versions cannot be reused.scripts/bump_version.py— updates all three places the version is recorded.Also
.gitignore,CONTRIBUTING.md,CITATION.cff, SPDX headers on every source file.setup.cfg, which referenced a non-existentREADME.rst.🤖 Generated with Claude Code