Weaviate

Call Weaviate from Flux tasks for vector search and multi-tenant collections.

Weaviate is an open-source vector database, available self-hosted via Docker or as a managed service through Weaviate Cloud. Flux has no native client — use the weaviate-client v4 SDK from inside @task.

Setup options

Self-hosted (Docker). A single container is enough for development:

# docker-compose.yml
services:
  weaviate:
    image: cr.weaviate.io/semitechnologies/weaviate:1.27.0
    ports:
      - "8080:8080"
      - "50051:50051"
    environment:
      AUTHENTICATION_APIKEY_ENABLED: "true"
      AUTHENTICATION_APIKEY_ALLOWED_KEYS: "dev-key-please-rotate"
      AUTHENTICATION_APIKEY_USERS: "admin"
      AUTHORIZATION_ADMINLIST_ENABLED: "true"
      AUTHORIZATION_ADMINLIST_USERS: "admin"

Weaviate Cloud. Sign up, create a cluster, copy the REST endpoint and a tenant API key from the dashboard.

Install

pip install weaviate-client

The v4 client (weaviate-client>=4.0) reworked the API; v3 examples on the wider internet do not apply.

API key

Store the key in Flux’s secret store:

flux secrets set weaviate_api_key wv_...
flux secrets set weaviate_url https://your-cluster.weaviate.network

Connect, write, query

from flux import workflow, task, ExecutionContext


@task.with_options(secret_requests=["weaviate_api_key", "weaviate_url"])
async def add_articles(secrets, articles: list[dict]) -> int:
    import weaviate
    from weaviate.classes.init import Auth

    with weaviate.connect_to_weaviate_cloud(
        cluster_url=secrets["weaviate_url"],
        auth_credentials=Auth.api_key(secrets["weaviate_api_key"]),
    ) as client:
        coll = client.collections.get("Article")
        with coll.batch.dynamic() as batch:
            for a in articles:
                batch.add_object(properties=a)
        return len(articles)


@task.with_options(secret_requests=["weaviate_api_key", "weaviate_url"])
async def search(secrets, query: str, k: int = 5) -> list[dict]:
    import weaviate
    from weaviate.classes.init import Auth
    from weaviate.classes.query import MetadataQuery

    with weaviate.connect_to_weaviate_cloud(
        cluster_url=secrets["weaviate_url"],
        auth_credentials=Auth.api_key(secrets["weaviate_api_key"]),
    ) as client:
        coll = client.collections.get("Article")
        result = coll.query.near_text(
            query=query,
            limit=k,
            return_metadata=MetadataQuery(distance=True),
        )
        return [
            {"props": o.properties, "distance": o.metadata.distance}
            for o in result.objects
        ]

connect_to_weaviate_cloud is the helper for managed clusters. For local Docker use connect_to_local(host="localhost", port=8080). The v4 client manages a long-lived gRPC connection and needs the with block — leaking a client across @task boundaries leaks the connection.

Multi-tenant collections

Weaviate’s multi-tenancy is first-class and fits Flux’s namespace model directly. Enable it on the collection:

from weaviate.classes.config import Configure
client.collections.create(
    name="Article",
    multi_tenancy_config=Configure.multi_tenancy(enabled=True),
)

Then attach a tenant before reading or writing:

coll = client.collections.get("Article").with_tenant("acme")

A natural mapping is tenant = workflow_namespace. Build it into a helper task so every read and write is scoped automatically — forgetting .with_tenant(...) on a multi-tenant collection raises immediately, which is the right failure mode.

What goes wrong

See also


Derived against weaviate-client 4.9.x and Weaviate Server 1.27, 2026-05.