* feat(serverless): expose CollectionsService response time
Sync the serverless collections proto with the public-api `time` field and
surface it on create/delete/get/list results (sync and async clients).
* feat(serverless): drop objects_deleted from delete result
Match public-api DeleteCollectionResponse after removing the storage
object count from the tenant-facing delete reply.
* chore(serverless): sync DeleteCollectionResponse.time to field 2
* new: add QdrantServerless client prototype
Serverless exposes the same point-level API as a regular cluster (minus
read consistency, shard selection, write ordering and filtered updates),
but a simplified tenant-facing collection management API.
- qdrant_client/serverless: dedicated module, nothing added to the
top-level package
- gRPC stubs generated from qdrant-cloud-public-api's
serverless/collections.proto (renamed to serverless_collections.proto
to avoid a descriptor-pool filename clash with the regular client's
collections.proto), kept internal
- hand-written pydantic models for the serverless collection config,
reusing the existing Distance/TokenizerType enums
- point operations delegate to an internal QdrantRemote(prefer_grpc=True)
with trimmed signatures; collection operations talk to the serverless
CollectionsService on the same channel
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw
* fix: exclude generated serverless grpc code from mypy
Same treatment as qdrant_client/grpc: generated stubs have untyped defs,
and the ListCollectionsResponse.collections field shadows the collections
module in the .pyi. Also import PointStruct from qdrant_client.http.models
in the example, matching the rest of the codebase.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw
* fix: remove lookup_from from serverless query_points, not supported
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw
* docs: full docstrings for QdrantServerless public methods
Match the Args/Returns docstring style of the regular client; each
method notes where the serverless API diverges from it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw
* new: generate AsyncQdrantServerless from the sync serverless client
Same approach as the regular client: the sync client is the source of
truth and tools/async_client_generator produces the async version.
The serverless generator delegates to AsyncQdrantRemote, awaits the
CollectionsService stub RPCs (awaitable on the aio channel the async
remote already builds), and drops the sync context manager. The file is
covered by the async-client-consistency-check like the other generated
clients.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw
* fix: resolve raw-vector queries in serverless query_points
query_points delegated straight to QdrantRemote, which expects a
resolved Query model, so a plain list like [0.1, 0.2] failed with
"invalid Query model". Apply the same QdrantFastembedMixin._resolve_query
type normalization the regular client applies - type resolution only, no
client-side embedding inference: Document/Image inputs go to the server
as-is, serverless inference is server-side only.
Verified live against a serverless dev space: create/list/get/upsert/
query/delete all pass, sync and async. Along the way: create_collection
docstring now documents that an existing collection raises gRPC
ALREADY_EXISTS (the service errors instead of returning the "already
exists" result string the proto comment mentions), and the example
deletes a leftover collection first so it can be rerun.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw
* new: expose serverless models under qdrant_client.models.serverless
Thin alias module re-exporting qdrant_client.serverless.models, matching
the qdrant_client.models convention of the regular client; the old
import path keeps working. Examples and tests use the new path. Also
replace an API key that slipped into the committed example with the
placeholder, and exclude examples/ from mypy so examples can use the
dynamic qdrant_client.models namespace.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw
* refactor: import serverless models from qdrant_client.serverless.models
Drop the qdrant_client.models.serverless alias module and the model
re-exports in qdrant_client.serverless: both were manually maintained
re-export lists. qdrant_client.serverless.models is the single public
import path; the serverless package itself exports only the clients.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw
* new: batch/group queries and remaining update ops in serverless client
query_batch_points and query_points_groups (both implemented by the
service, verified live) with the usual serverless trims: no consistency,
no shard selection, no cross-collection lookups. Add the update
operations the service implements that were still missing:
update_vectors, delete_vectors, overwrite_payload, clear_payload,
batch_update_points (ids-only selectors; the service rejects filters).
Update methods default to wait=False: serverless reads are eventually
consistent with writes, so waiting does not provide read-your-write.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw
* refactor: future-proof selector arguments in serverless update methods
All id-selecting update methods take a uniform `points` parameter,
typed narrowly as Sequence[PointId] to match what the service accepts
today. When serverless adds filtered updates, the type widens to
PointsSelector without breaking callers: same name, same position,
strictly wider input.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R25zh9xS78xMHgPcoFaUdw
* docs: mark QdrantServerless as in development
Warn that the serverless client is experimental and should not be used yet.
* refactor: explicitly deconstruct serverless conversion fields
Bind every model field via structural pattern matching so new fields force
an update instead of being silently ignored.
* feat(serverless): sync collections API pagination and text options
Align with the latest public-api collections.proto: paginated
ListCollections (limit/offset_token/next_offset_token) plus keyword
prefix and text analysis fields (stopwords, stemmer, ascii_folding).
* fix: remove enter/exit, add conversion tests
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: qdrant-cloud-bot <111755117+qdrant-cloud-bot@users.noreply.github.com>
Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
* fix(conversion): keep an absent UpdateResult.operation_id as None over gRPC
`UpdateResult.operation_id` is declared `optional uint64` in points.proto, so
it carries explicit presence. The server leaves it unset for updates that were
never assigned a sequence number - a delete-by-filter that matched no points, a
clock-rejected update, or a write to a custom-sharded collection that has no
shard keys yet.
`GrpcToRest.convert_update_result` read the field unconditionally, so the proto
default surfaced as `operation_id=0` while the same update over REST (where the
key is omitted from the body) yields `operation_id=None`. Since 0 is also a
valid operation id, callers could not tell the two apart.
Guard the read with `HasField`, matching the presence handling already used for
the neighbouring optional fields in this module.
* fix(conversion): keep an absent CollectionInfo.points_count as None over gRPC
`points_count` is `optional uint64` in collections.proto, so it carries explicit presence and the server may leave it unset when the count is not available. `GrpcToRest.convert_collection_info` read it unconditionally, so `get_collection` over gRPC reported `points_count=0` where the REST client reports `None`, turning "count unavailable" into "collection is empty". The sibling `indexed_vectors_count` on the next line is already guarded with `HasField`. Guard `points_count` the same way.
* tests: extend tests
---------
Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
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.
* 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
* new: update models, add conversions, add conversion tests
* new: add list shard keys, add get_optimizations
* new: add weights to rrf
* new: add cluster telemetry
* new: add update_mode usage
* fix: fix mypy
* fix: populate inspection cache
* use RRF ranking as in the core
* timeouts propagation
* gen async clients
* implement score threshold for formular
* new: add tests for update mode
* fix: fix test skip comment
* Relevance feedback local mode (#1152)
* AI: implement local computation
prompt: Considering the implementation in the server, make the local
python implementation of the same scores calculation in this file:
[@distances.py](...), consider that the local mode calculates for all
points at once, while the server does it point by point.
Server impl:
```
...
```
* use constant for MARGIN
* relevance feedback integration and test
* do not exclude relevance context from result
* Revert "do not exclude relevance context from result"
This reverts commit 9c2a5cedc0.
---------
Co-authored-by: generall <andrey@vasnetsov.com>
* fix: fix conversion test
---------
Co-authored-by: generall <andrey@vasnetsov.com>
Co-authored-by: Luis Cossío <luis.cossio@qdrant.com>
* new: remove vectors_count, update http and grpc models
* fix: update inspection cache
* new: add conversions and update interface
* fix: fix some conversions
* fix: fix typo
* fix: fix isinstance
* fix: regen async
* fix: fix update_filter usage, fix isinstance
* tests: collection metadata test
* fix: address backward compatibility in test
* new: update models, add max payload index count and copy vectors
* fix; update _inspection_cache
* new: add read consistency to count points
* Allow uuids in interface (#1085)
* new: direct uuid support
* tests: add uuid tests
* fix: update inspection cache
* new: add collection metadata and tests to local mode (#1089)
* new: add collection metadata and tests to local mode
* fix: regen async client
* new: implement parametrized rrf in local mode (#1087)
* new: implement parametrized rrf in local mode
* refactoring: use a variable for a magic value
* fix: adjust conversion according to AI
* Update filter (#1090)
* new: add missing update_filter, implement it in local mode
* fix: fix type hint, fix update operation, fix rest uploader, add tests
* fix: fix update filter is None case
* fix: mypy was not a good boy
* Text any filter (#1091)
* new: add match text any local mode
* tests: add match text any tests
* new: update models, remove init_from and locks (#1100)
* new: update models, remove init_from and locks
* deprecate: remove init from tests
* deprecate: remove lock tests
* new: convert ascii_folding
* fix: fix type stub
* new: convert acorn
* new: convert shard key with fallback
* new: update grpcio and grpcio tools in generator (#1106)
* new: update grpcio and grpcio tools in generator
* fix: bind grpcio and tools versions to 1.62.0 in generator
* Remove deprecated methods (#1103)
* deprecate: remove old api methods
* deprecate: remove type stub for removed methods
* deprecate: remove old api methods from test_qdrant_client
* deprecate: replace search with query points in test_in_memory
* deprecate: replace search methods in fastembed mixin with query points
* deprecate: replace old api methods in test async qdrant client
* deprecate: replace search with query points in test delete points
* deprecate: replace discover and context with query points in test_discovery
* deprecate: replace recommend_groups with query_points_groups in test_group_recommend
* deprecate: replace search_groups in test_group_search
* deprecate: replace recommend with query points in test_recommendation
* deprecate: replace search with query points in test search
* deprecate: replace context and discover with query points in test sparse discovery
* deprecate: replace search with query points in test sparse idf search
* deprecate: replace recommend with query points in test sparse recommend
* deprecate: replace search with query points in test sparse search
* deprecate: replace missing search request with query request in qdrant_fastembed
* deprecate: replace search with query points in test multivector search queries
* deprecate: replace upload records with upload points in test_updates
* deprecate: remove redundant structs (#1104)
* deprecate: remove redundant structs
* fix: do not use removed conversions in local mode
* fix: remove redundant conversions, simplify types.QueryRequest
* deprecate: replace old style grpc vector conversion to a new one (#1105)
* deprecate: replace old style grpc vector conversion to a new one
* fix: ignore union attr in conversion
* review fixes
---------
Co-authored-by: generall <andrey@vasnetsov.com>
---------
Co-authored-by: generall <andrey@vasnetsov.com>
---------
Co-authored-by: generall <andrey@vasnetsov.com>
* new: deprecate add, query, query_batch in fastembed mixin (#1102)
* new: deprecate add, query, query_batch in fastembed mixin
* 1.16 -> 1.17
---------
Co-authored-by: generall <andrey@vasnetsov.com>
---------
Co-authored-by: generall <andrey@vasnetsov.com>
* new: yet another update
* new: add initial_state to create shard key (#1109)
* new: drop python3.9, replace union and optional with | where possible
* fix: fix missing type hints, regen async
* fix: remove redundant optional
* fix: fix ai comments
* fix: update type hints from merge
* new: update pyproject and lock
* new: replace optional and union with |
* new: remove optional and union from qdrant local
* new: replace union with | in client classes
* fix: replace remaining union, optional, etc, address review comments
* new: adjust numpy versioning
---------
Co-authored-by: generall <andrey@vasnetsov.com>
* new: remove vectors_count, update http and grpc models
* fix: update inspection cache
* new: add conversions and update interface
* fix: fix some conversions
* fix: fix typo
* fix: fix isinstance
* fix: regen async
* fix: fix update_filter usage, fix isinstance
* tests: collection metadata test
* fix: address backward compatibility in test
* new: update models, add max payload index count and copy vectors
* fix; update _inspection_cache
* new: add read consistency to count points
* Allow uuids in interface (#1085)
* new: direct uuid support
* tests: add uuid tests
* fix: update inspection cache
* new: add collection metadata and tests to local mode (#1089)
* new: add collection metadata and tests to local mode
* fix: regen async client
* new: implement parametrized rrf in local mode (#1087)
* new: implement parametrized rrf in local mode
* refactoring: use a variable for a magic value
* fix: adjust conversion according to AI
* Update filter (#1090)
* new: add missing update_filter, implement it in local mode
* fix: fix type hint, fix update operation, fix rest uploader, add tests
* fix: fix update filter is None case
* fix: mypy was not a good boy
* Text any filter (#1091)
* new: add match text any local mode
* tests: add match text any tests
* new: update models, remove init_from and locks (#1100)
* new: update models, remove init_from and locks
* deprecate: remove init from tests
* deprecate: remove lock tests
* new: convert ascii_folding
* fix: fix type stub
* new: convert acorn
* new: convert shard key with fallback
* new: update grpcio and grpcio tools in generator (#1106)
* new: update grpcio and grpcio tools in generator
* fix: bind grpcio and tools versions to 1.62.0 in generator
* Remove deprecated methods (#1103)
* deprecate: remove old api methods
* deprecate: remove type stub for removed methods
* deprecate: remove old api methods from test_qdrant_client
* deprecate: replace search with query points in test_in_memory
* deprecate: replace search methods in fastembed mixin with query points
* deprecate: replace old api methods in test async qdrant client
* deprecate: replace search with query points in test delete points
* deprecate: replace discover and context with query points in test_discovery
* deprecate: replace recommend_groups with query_points_groups in test_group_recommend
* deprecate: replace search_groups in test_group_search
* deprecate: replace recommend with query points in test_recommendation
* deprecate: replace search with query points in test search
* deprecate: replace context and discover with query points in test sparse discovery
* deprecate: replace search with query points in test sparse idf search
* deprecate: replace recommend with query points in test sparse recommend
* deprecate: replace search with query points in test sparse search
* deprecate: replace missing search request with query request in qdrant_fastembed
* deprecate: replace search with query points in test multivector search queries
* deprecate: replace upload records with upload points in test_updates
* deprecate: remove redundant structs (#1104)
* deprecate: remove redundant structs
* fix: do not use removed conversions in local mode
* fix: remove redundant conversions, simplify types.QueryRequest
* deprecate: replace old style grpc vector conversion to a new one (#1105)
* deprecate: replace old style grpc vector conversion to a new one
* fix: ignore union attr in conversion
* review fixes
---------
Co-authored-by: generall <andrey@vasnetsov.com>
---------
Co-authored-by: generall <andrey@vasnetsov.com>
---------
Co-authored-by: generall <andrey@vasnetsov.com>
* new: deprecate add, query, query_batch in fastembed mixin (#1102)
* new: deprecate add, query, query_batch in fastembed mixin
* 1.16 -> 1.17
---------
Co-authored-by: generall <andrey@vasnetsov.com>
---------
Co-authored-by: generall <andrey@vasnetsov.com>
* new: yet another update
* new: add initial_state to create shard key (#1109)
* chore: remove obsolete imports
* fix: add metadata parameter to recreate collection in local
* fix: fix metadata handling in local more
---------
Co-authored-by: generall <andrey@vasnetsov.com>
* new: add sum_scores strategy, fix lookup from in query_batch_points, fix euclid between multivectors local mode
* new: recommend average multivectors, fix tests, add new tests for multivectors
* fix: address review comments
* fix: regen async
* tests: uncomment tests
* new: update poetry lock, require pydantic >=2.11 for populate inspection cache
* fix: tmp disable euclidean multivec search tests, fix multivec with nan test
* fix: align euclid and manhattan with core, add tests
* fix: fix type hints
* tests: use atol in comparison
* tests: remove manhattan tests
* tests: reduce number of multivectors
* remove float comparison relaxation
* explain why it is different for euclid and manhattan
---------
Co-authored-by: Luis Cossío <luis.cossio@outlook.com>
* add local mode of formula scoring
* grpc<->rest conversions
* fixes for formula evaluation
* add mixed payload type to fixture payload
* update tests
* ignore math warnings (invalid operations raise an error anyway)
* fix conversions
* use same haversine distance as in core
* upd tests
* add fixtures for expressions
* fix import
* temporary hack for tests
* evaluation fixes
* satisfy mypy
* gen async client
* reduce flakiness
..by nesting less equations, so that floating point differences affect
less
* get_args_subscribed
* retriever match multivalue behavior
* review remarks
* more review remarks
* review nit
* no type ignore
* fix imports
* new: drop python 3.8 support, update type hints
* fix: remove 3.8 from ci
* fix: update type hints
* fix: make netlify use python3.10
* fix: try python3.9 for sphinx
* debug: try updating sphinx
* new: bump ffastembed to 0.4.2
* fix: install numpy<2 for mypy
* fix: install numpy via poetry
* universal-search: Query Group API and local mode
* requires different logic for gRPC error assertion
* you come to me at runtime for a compile time issue
* suddenly throwing a different error
* test more group key types
* extend limit of prefetches during group_by
* rescoring is the issue
* one problem at a time please
* code review
* regen clients
* code review
* add lookup_from to query_points_groups
* test with_lookup
* test and fix gRPC
* drop dedicated conversion
* Update qdrant_client/qdrant_client.py
Co-authored-by: Luis Cossío <luis.cossio@outlook.com>
* regen async
* Distribution-based score fusion in local mode (#703)
* pre-implement dbsf
* add dbsf congruence tests
* mypy lints
* add conversions
* tests: add test for dbsf conversion
---------
Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
* Random sample in local mode (#705)
* pre-implement random sampling
* generate models
* add conversions and tests
* fix mypy lints
* tests: add test for sample random conversion
* use camelcase Sample.Random
* review fixes
* fix mypy
---------
Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
* fix: add type ignore for mypy
* fix: fix type hints for 3.8
* fix: do not run mypy on async client generator in CI, simplify condition
* Grpc comparison in tests (#726)
* add parametrized fixture for using grpc too
* compare grpc and http without running each setup twice
* fix: fix exception types in invalid types test
* fix: remove random seed which led to a erroneous sequence
---------
Co-authored-by: Luis Cossío <luis.cossio@outlook.com>
---------
Co-authored-by: Luis Cossío <luis.cossio@outlook.com>
Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>