mrkeyoor.com_
Wed 05 Aug 10:02 UTC
PyPIAI / MLupdated 05 Aug 2026

weaviate-client

The official Python client for the Weaviate vector database. Version 4 is a ground-up rewrite that talks REST for control-plane work and gRPC for data operations, organized around a collections-first API: you get a collection object once, then call typed methods on it for inserts, batching, vector search, BM25, hybrid search, filters, and generative (RAG) queries. Typed configuration and query helper classes under weaviate.classes replace the raw dicts of the v3 era.

Verdict

If Weaviate is your database, this client is well maintained, fast thanks to gRPC, and the typed v4 API is genuinely pleasant once learned. The honest cost is everything around it: a server to operate, two ports to open, and a v3 to v4 break that rotted most of the tutorials you will find.

API stability3/5The v3 to v4 rewrite invalidated essentially all prior code, and inside v4 the config surface still shifts (Configure.Vectorizer deprecated in favor of Configure.Vectors); the core query API has held steady, but expect deprecation warnings across minor versions.
Docs4/5weaviate.io has thorough guides with v4 code samples and readthedocs covers the API reference, but content is split across the two sites and search results still surface v3-era material that no longer applies.
Maintenance5/5Pushed the day before this review with frequent releases (4.22.0 current), developed in the open by Weaviate B.V. with a paid cloud product funding it; v3 still receives critical fixes.
Ecosystem4/5First-class integrations exist in LangChain, LlamaIndex, and Haystack, plus pluggable vectorizer and generative modules for the major model providers, though the community is smaller than the Postgres-plus-pgvector crowd.

Use it if

  • You have already chosen Weaviate (self-hosted or Weaviate Cloud) as your vector database and want the first-party, fully supported way to talk to it from Python
  • You want hybrid search (BM25 plus vector, blended by an alpha weight) as a one-line query method instead of assembling it yourself
  • You want batching with automatic retries and per-object error reporting for bulk imports, which the client's batch context manager handles
  • You want RAG in the query layer: generate.near_text runs retrieval and hands the results to a configured LLM module in one call
Skip it if

Setup reality

pip install weaviate-client is the easy part; the client is useless without a running Weaviate instance, so real setup starts with docker run (or a Weaviate Cloud cluster). The v4 client needs two open ports, 8080 for HTTP and 50051 for gRPC, and the gRPC one is what fails behind corporate proxies and default Kubernetes ingress, usually as an opaque connection deadline error. The v3 to v4 break was large: every tutorial written before 2024 shows an API that no longer exists. Clients hold connection pools, so you must call client.close() or use a context manager or you get ResourceWarning spam. Config helpers keep moving too: vectorizer_config with Configure.Vectorizer is deprecated in favor of vector_config with Configure.Vectors, so even early v4 examples now emit warnings.

Patterns

Connect to a local Weaviateconnect-local

import weaviate

client = weaviate.connect_to_local()
print(client.is_ready())
client.close()

connect_to_local assumes HTTP on 8080 and gRPC on 50051; if you remapped Docker ports, pass port= and grpc_port= or you get a connection deadline error that never mentions ports.

Connect to Weaviate Cloudconnect-cloud

import os
import weaviate
from weaviate.classes.init import Auth

client = weaviate.connect_to_weaviate_cloud(
    cluster_url=os.environ["WEAVIATE_URL"],
    auth_credentials=Auth.api_key(os.environ["WEAVIATE_API_KEY"]),
    headers={"X-OpenAI-Api-Key": os.environ["OPENAI_API_KEY"]},
)

Model-provider keys ride along as headers; without the right X-*-Api-Key header, vectorizer and generative calls fail at query time, not at connect time.

Auto-close the clientcontext-manager

import weaviate

with weaviate.connect_to_local() as client:
    collection = client.collections.get("Article")
    print(collection.aggregate.over_all(total_count=True).total_count)

Clients hold HTTP and gRPC connection pools; skipping close() leaks sockets and prints ResourceWarning at interpreter exit, so the with block is the sane default.

Create a collection with a vectorizercreate-collection

from weaviate.classes.config import Configure, Property, DataType

client.collections.create(
    "Article",
    vector_config=Configure.Vectors.text2vec_openai(),
    properties=[
        Property(name="title", data_type=DataType.TEXT),
        Property(name="body", data_type=DataType.TEXT),
    ],
)

vector_config with Configure.Vectors is the current form; the older vectorizer_config=Configure.Vectorizer.* from early v4 tutorials is deprecated and warns. Collection names are capitalized by the server, so "article" and "Article" are the same collection.

Insert a single objectinsert-object

articles = client.collections.get("Article")

uuid = articles.data.insert({
    "title": "Vector databases in production",
    "body": "...",
})
print(uuid)

collections.get does not hit the network or verify the collection exists; typos surface later as errors on the first data call, not here.

Bulk import with error trackingbatch-import

articles = client.collections.get("Article")

with articles.batch.fixed_size(batch_size=200) as batch:
    for row in rows:
        batch.add_object(properties=row)

if articles.batch.failed_objects:
    print(len(articles.batch.failed_objects), "failed")
    print(articles.batch.failed_objects[0].message)

Batch inserts do not raise on per-object failures; if you never check failed_objects you can silently lose a chunk of your import.

Semantic search with near_textnear-text-search

articles = client.collections.get("Article")

result = articles.query.near_text(
    query="impact of climate change on farming",
    limit=5,
)
for obj in result.objects:
    print(obj.properties["title"])

near_text only works when the collection has a vectorizer module configured; with self-provided vectors you must embed the query yourself and use near_vector instead.

Hybrid BM25 plus vector searchhybrid-search

result = articles.query.hybrid(
    query="grpc connection timeout",
    alpha=0.5,
    limit=5,
)
for obj in result.objects:
    print(obj.properties["title"])

alpha=0 is pure BM25, alpha=1 is pure vector; hybrid usually beats either alone for short keyword-ish queries, and 0.5 is the starting point, not the answer.

Filter results by propertyfiltered-query

from weaviate.classes.query import Filter

result = articles.query.fetch_objects(
    filters=Filter.by_property("title").like("*climate*"),
    limit=10,
)

Filters compose with & and | operators on Filter objects; they also plug into near_text and hybrid via the same filters= argument, which is how you scope semantic search to a tenant or date range.

Get distances and scores backreturn-metadata

from weaviate.classes.query import MetadataQuery

result = articles.query.near_text(
    query="solar panels",
    limit=5,
    return_metadata=MetadataQuery(distance=True, score=True),
)
for obj in result.objects:
    print(obj.metadata.distance, obj.properties["title"])

Metadata is opt-in; without return_metadata every obj.metadata field is None, which reads like a bug the first time you hit it.

RAG: retrieve then generate in one callrag-generative-search

result = articles.generate.near_text(
    query="climate change",
    grouped_task="Summarize these articles in two sentences",
    limit=5,
)
print(result.generative.text)

Requires a generative module configured on the collection plus the provider API key header on the client; grouped_task runs once over all hits, single_prompt runs per object.

Delete objects matching a filterdelete-by-filter

from weaviate.classes.query import Filter

result = articles.data.delete_many(
    where=Filter.by_property("title").like("*draft*"),
)
print(result.matches, "deleted")

delete_many is capped by the server's QUERY_MAXIMUM_RESULTS per call, so wiping a large collection may need a loop; dry_run=True tells you what would match first.

Alternatives

PackageRegistryPick it when
qdrant-clientPyPIYou want a similar dedicated vector database with a single-binary server that is lighter to self-host
chromadbPyPIYou want an embedded, in-process vector store for prototypes and small apps with no server to run
pgvectorPyPIYou already run Postgres and would rather add a vector column than operate a second database
pineconePyPIYou want a fully managed vector database and are fine with a proprietary hosted service