Commit Graph
652 Commits
Author SHA1 Message Date
de3c4328ef fix: local mode text/phrase and is-null semantics diverge from server — CI congruence failures investigated (#1394)
* fix: mirror server token-aware text/phrase matching on unindexed fields

qdrant/qdrant#10341 (dev) changed MatchText and MatchPhrase on fields
without a text index from a substring scan to token-aware matching via
the default word tokenizer: every query token must appear as a whole
document token (text, order-independent; consecutive for phrase), empty
queries match nothing. Local mode still substring-scanned, so congruence
tests randomly failed whenever the filter generator drew a MatchText
whose word is a substring of another fixture word ("fly" in "butterfly",
"ant" in "elephant"). MatchTextAny keeps substring semantics, matching
the server.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw

* fix: match null elements inside arrays in local IsNull condition

qdrant/qdrant#10101 (dev) made the unindexed IsNull check inspect array
elements: a value like [null, 1] now satisfies IsNull (one level deep).
Local mode only matched values that were null themselves. This was the
second divergence behind the congruence CI failures, previously masked
by the MatchText one because pytest runs with -x.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw

* fix: close local client before reopening storage in persistence tests

The persistence tests released the storage lock with `del local_client`,
relying on garbage collection timing; when the lock outlived the del,
reopening the same directory raised "Storage folder is already accessed
by another instance". test_query.py was already fixed to call close()
(90913f8); apply the same fix to the remaining five persistence tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw

* fix: bound remote group hits by exact local hits instead of equality

Server-side grouping is best-effort within a request budget (qdrant
lib/shard/src/grouping/driver.rs): once the budget is spent, a group may
be filled with worse points than its true best, or stay below
group_size. Local mode groups exhaustively, so asserting exact per-rank
score equality of deep group hits randomly failed when the fill budget
missed a group member (test_query_group, local 0.6926 vs remote 0.6798
at rank 4). Compare one-sided instead: at any rank the remote hit may be
worse than the exact local one, never better; the top hit stays strict.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw

* test: move local text-match and is-null tests to their conventional homes

The two new test files sat at the tests/ root. Local-mode behavior belongs in
qdrant_client/local/tests, and filter corner cases in
tests/congruence_tests/test_complex_filters.py.

- the check_match assertions mirroring the server's unindexed_text_match_test.rs
  move into qdrant_client/local/tests/test_payload_filters.py, next to the other
  filter unit tests
- the client-level cases become congruence tests in test_complex_filters.py, so
  they compare local against a real server instead of asserting local behavior
  alone: text/phrase/text-any matching on an unindexed field, and IsNull over
  arrays holding a null

Both congruence tests fail against the pre-fix payload_filters and pass with it,
against qdrant 1.19.1-dev.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* tests: add non-consecutive case for match filter

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
2026-09-16 00:25:42 +07:00
Arav 8acb48dcee Fix in-place mutation of inputs in cosine_similarity (#1357)
* Fix in-place mutation of inputs in cosine_similarity

cosine_similarity normalized its `query` and `vectors` arguments in place
via `/=`, which (1) mutated caller-owned arrays as a side effect and
(2) raised UFuncTypeError on integer-dtype inputs, unlike the dot,
euclidean, and manhattan distance functions. Switch to out-of-place
division so the inputs are left untouched. Computed results are unchanged.

Add regression tests asserting the query/vectors arguments are not mutated
(1D and 2D query paths) and that integer-dtype inputs are accepted.

* test: exercise 2D cosine query path with multiple rows

Use a two-row 2D query so the batched per-row normalization path is
verified, and assert the full distance matrix in addition to input
immutability.

* Keep vectors normalization in place per review, fix query only

@joein noted that vectors is always already normalized when reaching
cosine_similarity through the client API (cosine collections are
normalized on upsert), so copying it is unnecessary overhead on what
can be a large candidate set. Revert vectors to in-place normalization
and keep only the query-side fix, which he agreed is worth the
(minimal) copy cost since queries are fresh, user-supplied input each
call and aren't guaranteed to be pre-normalized.

Update tests to match: drop the vectors-not-mutated assertions and the
vectors integer-dtype case (vectors is always float32 in real usage),
keep the query-side mutation and integer-dtype coverage.
2026-09-16 00:25:36 +07:00
2sumtech 9a01291535 fix: pin keyword index prefix=False round-trip behavior over gRPC (#1356)
grpc.KeywordPrefixParams is an empty message: presence is the only
signal, so an explicit prefix=False cannot be represented in gRPC.
It is sent as absent (same server-side semantics, disabled) and is
recovered as None. Document this at both conversion sites and pin
the behavior with a reverse-direction (rest->grpc->rest) test.
2026-09-16 00:25:31 +07:00
Georgeand2sumtech 334e9cbf8c fix: fix shard key selector usage in update payload methods (#1364)
Co-authored-by: 2sumtech <2sumtech@gmail.com>
2026-09-16 00:25:26 +07:00
Tai An 704f037e8a fix(warnings): give the User-Agent override warning a stacklevel (#1363)
`show_warning_once` defaults to `stacklevel=1`, which makes `warnings.warn`
attribute the warning to `qdrant_client/common/client_warnings.py:7` -- inside
the client -- instead of the caller's construction site.

Every other `show_warning_once` call in the package passes an explicit
stacklevel (4, 5, 6 or 10, depending on nesting); this is the only site that
omits it. Its two immediate siblings in the same `__init__` -- the
`api-key`-in-headers warning and the `grpc.primary_user_agent` warning -- both
pass `stacklevel=4`, so this brings it in line with them.

Before:
  .../qdrant_client/common/client_warnings.py:7: UserWarning: `User-Agent` ...
After:
  .../qdrant_client/qdrant_client.py:134: UserWarning: `User-Agent` ...

which is where the sibling warnings already point.

`async_qdrant_remote.py` is generated from the sync source; the hunk there
matches what `tools/generate_async_client.sh` emits (verified by running the
generator with ruff pinned to 0.4.3).
2026-09-16 00:25:21 +07:00
dependabot[bot] 9343494232 chore(deps): bump pypa/gh-action-pypi-publish (#1315)
Bumps the version-updates group with 1 update in the / directory: [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish).


Updates `pypa/gh-action-pypi-publish` from 1.14.0 to 1.14.2
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/cef221092ed1bacb1cc03d23a2d87d1d172e277b...dc37677b2e1c63e2034f94d8a5b11f265b73ba33)

---
updated-dependencies:
- dependency-name: pypa/gh-action-pypi-publish
  dependency-version: 1.14.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: version-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-16 00:25:14 +07:00
dependabot[bot] 96a1605e34 chore(deps): bump actions/checkout from 6.0.2 to 7.0.1 (#1316)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 7.0.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...3d3c42e5aac5ba805825da76410c181273ba90b1)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-16 00:25:09 +07:00
dependabot[bot] a391f86c3c chore(deps): bump dcarbone/install-jq-action from 3.2.0 to 4.0.1 (#1317)
Bumps [dcarbone/install-jq-action](https://github.com/dcarbone/install-jq-action) from 3.2.0 to 4.0.1.
- [Release notes](https://github.com/dcarbone/install-jq-action/releases)
- [Commits](https://github.com/dcarbone/install-jq-action/compare/b7ef57d46ece78760b4019dbc4080a1ba2a40b45...4fcb5062d7ce9bc4382d1a352d19ba3ba2c317c1)

---
updated-dependencies:
- dependency-name: dcarbone/install-jq-action
  dependency-version: 4.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-16 00:25:02 +07:00
dependabot[bot] 7b3ba9e5e2 chore(deps): bump actions/setup-python from 6.2.0 to 7.0.0 (#1318)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6.2.0 to 7.0.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/a309ff8b426b58ec0e2a45f0f869d46889d02405...5fda3b95a4ea91299a34e894583c3862153e4b97)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-16 00:24:56 +07:00
dependabot[bot] 9a9f37fafe chore(deps-dev): bump coverage from 6.5.0 to 7.15.2 (#1320)
Bumps [coverage](https://github.com/coveragepy/coveragepy) from 6.5.0 to 7.15.2.
- [Release notes](https://github.com/coveragepy/coveragepy/releases)
- [Changelog](https://github.com/coveragepy/coveragepy/blob/main/CHANGES.rst)
- [Commits](https://github.com/coveragepy/coveragepy/compare/6.5.0...7.15.2)

---
updated-dependencies:
- dependency-name: coverage
  dependency-version: 7.15.2
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-16 00:24:51 +07:00
nightcitybladeandGeorge Panchuk 0cb8f0bd31 fix: reject empty collection names in existence checks (#1332)
* fix: reject empty collection names in existence checks

* tests: move tests to congruence

* fix: regen async client

---------

Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
2026-09-16 00:24:43 +07:00
Nazrul AnsariandGeorge Panchuk 201232d080 fix: local mode matches the wrong points on null and empty-should filters (#1333)
* fix: local mode matches wrong points on null and empty-should filters

* tests: move tests to complex filters

---------

Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
2026-09-16 00:24:38 +07:00
dependabot[bot] fa6f7ea1ec chore(deps-dev): bump pytest-asyncio from 0.21.2 to 0.23.8 (#1323)
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.21.2 to 0.23.8.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.21.2...v0.23.8)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-version: 0.23.8
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-16 00:24:31 +07:00
As 17c761f08e docs: restore local mode image missing from master (#1406) 2026-09-10 15:22:31 +07:00
George 550484d767 new: add dependabot config (#1314) 2026-08-04 23:37:23 +07:00
George Panchuk 425840be98 bump version to v1.19.0 v1.19.0 2026-08-04 21:20:14 +07:00
George 34dbb37a55 fix: fix nested payload local mode (#1312)
* fix: fix nested payload local mode

* test: update test data in complex filter
2026-08-04 21:17:34 +07:00
George da58e7d492 deprecate: remove max_disk_usage_percent, deprecate max_resident_memory_percent (#1311) 2026-08-04 21:17:11 +07:00
Nazrul Ansari efc46195e1 fix: values_count bounds must be satisfied by a single value in local mode (#1293) 2026-08-04 21:17:06 +07:00
George 589aece6f5 new: 1.19.0 updates (#1298)
* new: 1.19.0 updates

* fix: fix search params as a dict in local mode

* fix: update qdrant backward compatibility version

* fix: add version check to the test

* fix: add version check to the test
2026-08-04 21:16:58 +07:00
George 24bd6bf314 fix: add limit > 0 rules in local mode (#1281) 2026-08-04 21:16:09 +07:00
Madan kumarandGeorge Panchuk 715b48b720 Preserve proto3 field presence for falsy values in REST/gRPC conversion (#1260)
Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
2026-08-04 21:16:04 +07:00
ErenAta16 5a0e0d00fb fix: do not drop falsy shard keys in convert_points_update_operation (#1279) 2026-08-04 21:15:39 +07:00
George 2257c55b99 fix: fix embed paths (#1278)
* fix: fix embed paths

* tests: add local inference test for complex prefetch
2026-08-04 21:15:23 +07:00
Madhan Kumar ReddyandGeorge Panchuk f28634c053 Warn that search_params is ignored in local mode instead of silently dropping it (#1083) (#1247)
Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
2026-08-04 21:15:15 +07:00
Madan kumarandGeorge Panchuk 53c81ee2c8 Fix local mode filters cross-matching booleans and integers (#1259)
* Fix local mode filters cross-matching booleans and integers

Python treats bool as a subclass of int (True == 1, False == 0), but Qdrant
keeps booleans and integers as distinct payload value types. Local mode
compared them with a plain `==` / `in` / `isinstance(value, (int, float))`, so:

- MatchValue(value=1) matched a payload of True, and MatchValue(value=True)
  matched a payload of 1 (same for 0 / False)
- MatchAny / MatchExcept cross-matched the same way
- Range matched booleans as if they were 0 / 1

The server never cross-matches these (its ValueVariants keeps Integer and Bool
distinct, and booleans are not numeric for range conditions). Add a type-aware
equality helper used by the value-match conditions, and exclude booleans from
range checks. Adds an in-memory regression test.

* Cover MatchExcept in the bool/int cross-match test

MatchExcept also routes through values_match, so assert that except=[1]
keeps the True payload (bool is not the integer 1).

* Add isolated MatchAny and range asserts to the bool/int cross-match test

Lock the single-value MatchAny path and the check_range bool guard against
regressions, in addition to the existing combined-condition coverage.

* fix: handle floats in cross-match local mode filters, add congruence tests

---------

Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
2026-08-04 21:15:10 +07:00
GeorgeandHassan Zafar 800017d527 fix: do not include local test files into the distribution (#1277)
Co-authored-by: Hassan Zafar <hassanzafar619@gmail.com>
2026-08-04 21:15:05 +07:00
GeorgeandEren Ata 6f0d9bec8c fix: fix local mode set payload shared nested object #1271 (#1276)
Co-authored-by: Eren Ata <erena6466@gmail.com>
2026-08-04 21:14:59 +07:00
George 152b6cec84 Fix env installation (#1255)
* fix: update poetry lock

* fix: add type annotations, update poetry.lock

* fix: fix local persistence tests

* fix: replace del client with client.close in local mode persistence tests

* new: update local mode values count filter behaviour
2026-08-04 21:14:51 +07:00
Charles DuffyandGeorge Panchuk 64c766a963 fix: spurious async client tests failures (#1181)
* fix: spurious async client tests failures

* skip cluster-only test when server is standalone

* increase timeout for unit test performing multiple snapshot operations

* clean up stale snapshots left by previous runs

* fix: remove deleted methods, add/update cluster checks

* fix: remove unused import

* fix: remove redundant indent

---------

Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
2026-08-04 21:14:44 +07:00
George 62bd70f23a fix: fix persistence test in test query (#1245) 2026-08-04 21:14:38 +07:00
George b4ef6a4ff4 fix: fix update vectors in local mode (#1244) 2026-08-04 21:14:32 +07:00
George 397df8b596 fix: fix persistence in local mode multivector tests (#1243) 2026-08-04 21:14:25 +07:00
Alok TripathiandGeorge Panchuk 7bd755bf32 fix: check_match() raises TypeError when MatchText applied to non-string field (#1224)
* fix: check_match() raises TypeError when MatchText applied to non-string field

* tests: move non-string match test to test_nested_filter, cover MatchText and MatchTextAny

---------

Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
2026-08-04 21:14:07 +07:00
George 8409ae34b5 fix: update poetry lock (#1242)
* fix: update poetry lock

* fix: add type annotations, update poetry.lock

* fix: fix local persistence tests

* fix: replace del client with client.close in local mode persistence tests
2026-08-04 21:13:59 +07:00
Esteban Yusunguaira 2e03ad3f58 ci: update all actions to node 24 (#1216) 2026-08-04 21:10:34 +07:00
George b09b2131ae new: remove add and query methods (#1210)
* new: deprecate add and query methods

* fix: update async client generator
2026-08-04 21:10:18 +07:00
Esteban Yusunguaira f569ead5a7 ci: update github actions to node 24 (#1212) 2026-08-04 21:10:04 +07:00
George 37d59107ef new: check the package is importable before publish (#1207) 2026-08-04 21:09:49 +07:00
Mohamed Arbi 0559a7c274 docs: Add docstring for ParallelWorkerPool class (#1199) 2026-08-04 21:09:42 +07:00
Mohamed Arbi fd8de6a46a fix: use HasVectorCondition in local search_distance_matrix (#1197) 2026-08-04 21:09:37 +07:00
Solaris-star 200d865d0d docs: correct default gRPC timeout description (#1282)
The client docstrings claimed gRPC timeout was unlimited, but
QdrantRemote.DEFAULT_GRPC_TIMEOUT is 5 seconds and is applied when
timeout=None. Align docs with implementation.

Fixes #1023
2026-07-24 12:59:47 +07:00
George Panchuk 326adefcc2 bump version to v1.18.0 v1.18.0 2026-05-11 20:59:32 +07:00
George e9ec2c0d2b new: update models to 1.18, add create_named_vector and delete_named_vector (#1201)
* new: update models to 1.18, add create_named_vector and delete_named_vector

* fix: add missing strict mode config updates

* fix: fix local mode create and delete vector name

* new: update turbo quant fields

* fix: persist vector deletion
2026-05-11 20:53:44 +07:00
Andrey VasnetsovandGeorge Panchuk 07f19f7dee Per-request custom headers for tracing (#1173)
* implement thread-local header overwrite for setting headers for individual requests

* mypy

* fix: remove redundant import in init, remove redundant import in qdrant remote

---------

Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
2026-05-11 20:53:38 +07:00
George beb9ae5b90 new: remove python docs in favour of qdrant.tech (#1174)
* new: remove python docs in favour of qdrant.tech

* fix: docs redirect

* fix: fix netlify

* fix: fix netlify
2026-05-11 20:53:29 +07:00
George e191b02f90 fix: fix geo bounding box filters on edges (#1190)
* fix: fix geo bounding box filters on edges

* tests: add test
2026-05-11 20:51:43 +07:00
George d1d25a2fd3 fix: fix local mode values count (#1191) 2026-05-11 20:51:37 +07:00
estebany-qdandGeorge Panchuk 504ba7b74e ci: Pin all gh actions to commit SHAs (#1179)
* ci: Pin all gh actions to commit SHAs

* new: update checkout to v2 in type check ci

---------

Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
2026-05-11 20:51:30 +07:00
George f994dcf6e7 new: bump fastembed to 0.8.0 (#1176) 2026-05-11 20:49:29 +07:00