Skip to main content

The official Python SDK for the Hydra DB (hydradb.com)

Project description

HydraDB Python SDK

The official Python SDK for HydraDB — a managed retrieval engine that combines vector search, full‑text search, and a knowledge graph behind a single API.

  • Package: hydradb-sdk
  • Import module: hydra_db
  • Version: 2.1.1 (API version 2)
  • Docs: https://docs.hydradb.com
  • Python: 3.10+

Table of contents


Installation

pip install hydradb-sdk

Quick start

from hydra_db import HydraDB

client = HydraDB(
    token="YOUR_API_KEY",      # your HydraDB API key (bearer token)
    api_version="2",           # optional, defaults to "2"
)

# Run a hybrid search over a database ("tenant")
result = client.query(
    query="What is our refund policy?",
    database="acme-corp",
    type="knowledge",
    max_results=5,
)

for chunk in result.data.chunks:
    print(chunk)

Every method returns a typed response object (Pydantic models). Responses are wrapped in a HandlerEnvelope… type — the payload lives on .data, with request metadata on .meta.


Client configuration

from hydra_db import HydraDB
from hydra_db.environment import HydraDBEnvironment

client = HydraDB(
    token="YOUR_API_KEY",
    api_version="2",
    environment=HydraDBEnvironment.DEFAULT,   # https://api.hydradb.com
    # base_url="https://api.hydradb.com",     # override for self-hosted / staging
    timeout=60.0,                             # seconds; default 60
    headers={"X-Custom-Header": "value"},     # sent on every request
)
Parameter Type Default Notes
token str | Callable[[], str] Bearer token. Pass a callable for dynamic/refreshing tokens.
api_version str "2" Sets the API version header.
environment HydraDBEnvironment DEFAULT DEFAULThttps://api.hydradb.com.
base_url str Explicit URL; overrides environment.
timeout float 60 Per‑request timeout in seconds.
headers dict[str, str] Extra headers on every request.
follow_redirects bool True
httpx_client httpx.Client Bring your own configured client.

Core concepts

Database vs. Collection (tenant vs. sub‑tenant). HydraDB v2 renamed the isolation scopes:

v2 name (canonical) v1 alias (deprecated, still accepted) Meaning
database tenant_id Top‑level isolation boundary.
collection sub_tenant_id A namespace within a database.

The server’s TenantAliases middleware reconciles the two, so you can pass either — but new code should use database / collection. The legacy aliases will be removed in a future release.

Corpora (type). Data is split into two corpora you can target independently: "knowledge" (documents), "memory" (agent memories), or "all".


Endpoints

query — unified retrieval

POST /queryHandlerEnvelopeSearchV2RetrievalResult

The single retrieval endpoint. Dispatches across corpus (type) and retrieval method (query_by), optionally enriching results with knowledge‑graph context.

from hydra_db import HydraDB

client = HydraDB(token="YOUR_API_KEY")

result = client.query(
    query="How do I rotate API keys?",
    database="acme-corp",           # v2 name for the tenant scope
    type="knowledge",               # "knowledge" | "memory" | "all"
    query_by="hybrid",              # "hybrid" | "text"
    mode="auto",                    # "fast" | "thinking" | "auto"
    operator="or",                  # "or" | "and" | "phrase"
    max_results=10,
    num_related_chunks=3,
    graph_context=True,             # include KG context (default True)
    recency_bias=0.2,
    metadata_filters={              # exact-match on tenant/document metadata
        "department": "security",
        "additional_metadata": {"author": "ada"},
    },
)

print(result.data)

Scoping to specific collections (preferred over the deprecated sub_tenant_ids):

# Equal weighting across collections
client.query(query="pricing", database="acme-corp", collections=["eu", "us"])

# Weighted ranking (one decimal place max)
client.query(query="pricing", database="acme-corp", collections={"eu": 1.0, "us": 0.5})

Scoping to specific source IDsids applies a hard source_id in [...] pre‑filter; if nothing matches it returns empty rather than widening to the whole corpus:

client.query(query="onboarding", database="acme-corp", ids=["doc_123", "doc_456"])

Key parameters:

Parameter Type Notes
query str The search text.
database str Tenant scope (v2). Alias: tenant_id.
collection / collections str / list | dict Sub‑tenant scope. Prefer over sub_tenant_id(s).
type "knowledge" | "memory" | "all" Corpus to query.
query_by "hybrid" | "text" Retrieval method.
mode "fast" | "thinking" | "auto" Recall mode.
operator "or" | "and" | "phrase" Text‑match operator.
max_results int Result cap.
num_related_chunks int Neighboring chunks to attach.
graph_context bool Include KG context. Default True.
query_apps bool App‑aware knowledge retrieval.
query_forceful_relations bool Force relation expansion. Default True.
metadata_filters dict[str, Any] Exact‑match on metadata (nest under additional_metadata for doc metadata).
recency_bias float Boost newer sources.
ids list[str] Restrict to specific source IDs.

Context (client.context)

Everything about the data inside a database: ingesting, listing, inspecting, updating metadata, checking processing status, reading graph relations, and deleting.

context.ingest

POST (multipart) → HandlerEnvelopeIngestionV2SourceUploadResponse

Ingest knowledge documents or memories. documents is a file upload; the other fields are form fields (JSON strings where structured).

from hydra_db import HydraDB

client = HydraDB(token="YOUR_API_KEY")

# Ingest a document file
with open("handbook.pdf", "rb") as f:
    resp = client.context.ingest(
        database="acme-corp",           # required
        documents=f,                    # file-like / (filename, bytes) / bytes
        collection="hr",
        type="knowledge",
        # document_metadata is a JSON *array* — one object per uploaded file.
        document_metadata='[{"title": "Employee Handbook", "author": "HR"}]',
        upsert="true",                  # form field is a string
    )

print(resp.data)

# Ingest memories (no file). Each item needs "text" (or "user_assistant_pairs").
client.context.ingest(
    database="acme-corp",
    memories='[{"text": "User prefers dark mode"}]',
    type="memory",
)
Parameter Type Notes
database str (required) Database (tenant scope). Alias: tenant_id.
documents core.File File upload (path handle, bytes, or (name, bytes) tuple).
memories str JSON array string; each item needs text (or user_assistant_pairs).
document_metadata str JSON array string of per‑document metadata — one object per uploaded file (count must match).
app_knowledge str App‑knowledge items as a JSON array string (not raw text).
graph_payload str Pre‑computed graph payload.
collection str Collection (sub‑tenant scope). Alias: sub_tenant_id.
type str "knowledge" or "memory".
upsert str "true" to upsert on existing IDs.

context.list

GET /context/listHandlerEnvelopeListV2SourceListResponse

List sources or memories (IDs + metadata) for a database, with filtering and pagination.

from hydra_db import HydraDB
from hydra_db import ListContentFilter

client = HydraDB(token="YOUR_API_KEY")

resp = client.context.list(
    database="acme-corp",
    collection="hr",
    type="knowledge",
    page=1,
    page_size=50,
    include_fields=["title", "type", "timestamp"],
    filters=ListContentFilter(
        metadata={"department": "finance"},          # tenant/source metadata
        additional_metadata={"author": "ada"},       # document metadata
        source_fields={"type": "pdf"},               # well-known source fields
    ),
)

for source in resp.data.sources:
    print(source)

context.inspect

GETHandlerEnvelopeFetchV2SourceFetchResponse

Fetch a single ingested source: its content, inferred content, and a presigned download URL.

resp = client.context.inspect(
    id="doc_1234",                 # required — source ID
    database="acme-corp",          # required
    collection="hr",
    expiry_seconds=3600,           # presigned URL lifetime
    mode="both",                   # fetch mode: "content", "url", or "both"
)
print(resp.data.presigned_url)

context.status

GETHandlerEnvelopeIngestionV2BatchProcessingStatus

Check processing status for one or more source IDs.

# Single source
client.context.status(database="acme-corp", id="doc_1234", collection="hr")

# Batch
resp = client.context.status(
    database="acme-corp",
    ids=["doc_1", "doc_2", "doc_3"],
)
print(resp.data)

context.relations

GETHandlerEnvelopeGraphGraphRelationsResponse

Return knowledge‑graph relations for a whole database or a single source.

resp = client.context.relations(
    database="acme-corp",          # required
    collection="hr",
    id="doc_1234",                 # omit for database-wide relations
    type="knowledge",              # "knowledge" | "memory"
    limit=100,
    cursor=0,                      # pagination cursor (float)
)
for triplet in resp.data.relations:
    print(triplet)

context.update_source_metadata

PATCHHandlerEnvelope…MetadataEditResult

Merge/upsert tenant_metadata and additional_metadata for one source. collection (alias sub_tenant_id) is required by the server.

resp = client.context.update_source_metadata(
    id="doc_1234",                 # required — source ID
    database="acme-corp",
    collection="hr",               # required by the server
    # tenant_metadata keys must be declared in the database's tenant_metadata_schema
    # (and match the declared type). Use additional_metadata for free-form fields.
    tenant_metadata={"department": "finance"},
    additional_metadata={"author": "ada", "tags": ["policy", "2026"], "reviewed": True},
)
print(resp.data)

Note: although the SDK exposes a document_metadata parameter here, this endpoint rejects it (HTTP 400 "document_metadata is not accepted; use additional_metadata"). Put per-document fields in additional_metadata instead.

context.delete

DELETEHandlerEnvelopeSourcesMemoryDeleteResponse

Delete one or more sources or memories by ID.

resp = client.context.delete(
    database="acme-corp",
    collection="hr",
    ids=["doc_1234", "doc_5678"],
    type="knowledge",
)
print(resp.data)

Databases (client.databases)

Manage databases (tenants) and inspect their collections, stats, and provisioning status.

databases.create

POSTHandlerEnvelopeTenantsTenantCreateAcceptedResponse

Create a new database, optionally with a custom metadata schema for its collections.

from hydra_db import HydraDB
from hydra_db import TenantsCustomPropertyDefinition

client = HydraDB(token="YOUR_API_KEY")

resp = client.databases.create(
    database="acme-corp",
    embeddings_dimension=1536,
    database_metadata_schema=[
        TenantsCustomPropertyDefinition(
            name="department",
            data_type="VARCHAR",   # BOOL | INT8..INT64 | FLOAT | DOUBLE | VARCHAR | JSON | ARRAY
            max_length=128,
            enable_match=True,
        ),
        TenantsCustomPropertyDefinition(name="priority", data_type="INT32"),
    ],
)
print(resp.data)

Creation is asynchronous — poll databases.status until infrastructure is provisioned before ingesting.

databases.list

GETHandlerEnvelopeTenantsTenantIdsResponse

List all databases for the authenticated user.

resp = client.databases.list()
print(resp.data)

databases.collections

GETHandlerEnvelopeTenantsSubTenantIdsResponse

List all collections within a database.

resp = client.databases.collections(database="acme-corp")
print(resp.data)

databases.stats

GETHandlerEnvelopeTenantsTenantStatsResponse

Get collection statistics for a database.

resp = client.databases.stats(database="acme-corp")
print(resp.data)

databases.status

GETHandlerEnvelopeTenantsInfraStatusResponseV2

Check infrastructure provisioning status for a database.

resp = client.databases.status(database="acme-corp")
print(resp.data)

databases.delete

DELETEHandlerEnvelopeTenantsTenantDeleteResponse

Delete a database and all associated data.

resp = client.databases.delete(database="acme-corp")
print(resp.data)

Webhooks (client.webhooks)

Register a single indexing webhook per org and inspect/replay its deliveries.

webhooks.register

POSTHandlerEnvelopeWebhooksWebhookRegisterResponse

Register (or update) the indexing webhook for this API key’s org.

resp = client.webhooks.register(
    url="https://example.com/hooks/hydradb",
    event_types=["indexing.status_changed"],   # the only supported event type
    signing_secret="whsec_at_least_16_chars",  # must be >= 16 characters
)
print(resp.data)

webhooks.get

GETHandlerEnvelopeWebhooksWebhookGetResponse

Fetch the currently registered webhook.

resp = client.webhooks.get()
print(resp.data)

webhooks.test

POSTHandlerEnvelopeWebhooksWebhookTestResponse

Send a test delivery to the registered endpoint.

resp = client.webhooks.test()
print(resp.data)

webhooks.delete

DELETEHandlerEnvelopeWebhooksWebhookDeleteResponse

Remove the registered webhook.

resp = client.webhooks.delete()
print(resp.data)

webhooks.list_deliveries

GETHandlerEnvelopeWebhooksDeliveryListResponse

List recent webhook deliveries, with filtering and cursor pagination.

resp = client.webhooks.list_deliveries(
    limit=50,
    cursor=None,                    # pass the previous page's cursor to continue
    status="failed",               # filter by delivery status
)
for delivery in resp.data.deliveries:
    print(delivery)

webhooks.get_delivery

GETHandlerEnvelopeWebhooksDeliveryItem

Fetch a single delivery by ID.

resp = client.webhooks.get_delivery(delivery_id="dlv_1234")
print(resp.data)

webhooks.retry_delivery

POSTHandlerEnvelopeWebhooksRetryResponse

Re‑attempt a failed delivery.

resp = client.webhooks.retry_delivery(delivery_id="dlv_1234")
print(resp.data)

Async usage

Every method has an async twin on AsyncHydraDB. The API surface is identical — just await each call.

import asyncio
from hydra_db import AsyncHydraDB

client = AsyncHydraDB(token="YOUR_API_KEY")


async def main() -> None:
    result = await client.query(query="refund policy", database="acme-corp")
    print(result.data)

    dbs = await client.databases.list()
    print(dbs.data)


asyncio.run(main())

AsyncHydraDB also accepts an async_token callable for token acquisition that involves async I/O (e.g. refreshing a token over HTTP).


Error handling

Non‑2xx responses raise typed exceptions, all subclasses of ApiError. Each carries status_code and the parsed body.

from hydra_db import HydraDB
from hydra_db.core.api_error import ApiError
from hydra_db.errors import (
    BadRequestError,          # 400
    ForbiddenError,           # 403
    NotFoundError,            # 404
    ConflictError,            # 409
    UnprocessableEntityError, # 422
    InternalServerError,      # 500
)

client = HydraDB(token="YOUR_API_KEY")

try:
    client.databases.status(database="does-not-exist")
except NotFoundError as e:
    print("not found:", e.body)
except ApiError as e:
    print(f"API error {e.status_code}: {e.body}")

Advanced

Request options (timeouts & retries)

Pass request_options to any method to override per call.

client.query(
    query="hello",
    database="acme-corp",
    request_options={
        "timeout_in_seconds": 30,
        "max_retries": 3,
        "additional_headers": {"X-Trace-Id": "abc123"},
    },
)

Raw responses

Use with_raw_response to access status code and headers alongside the parsed body.

raw = client.with_raw_response.query(query="hello", database="acme-corp")
print(raw.headers)
print(raw.data)

Custom HTTP client

import httpx
from hydra_db import HydraDB

client = HydraDB(
    token="YOUR_API_KEY",
    httpx_client=httpx.Client(
        proxy="http://localhost:8080",   # httpx >= 0.26 renamed `proxies` -> `proxy`
        transport=httpx.HTTPTransport(retries=3),
    ),
)

Endpoint reference

Group Method Description
query Unified hybrid/text retrieval across corpora with optional graph context.
context ingest Ingest documents or memories (multipart upload).
context list List sources/memories with metadata filters + pagination.
context inspect Fetch a source’s content + presigned download URL.
context status Processing status for one or many source IDs.
context relations Knowledge‑graph relations for a database or source.
context update_source_metadata Merge/upsert metadata for a source.
context delete Delete sources/memories by ID.
databases create Create a database with optional metadata schema.
databases list List all databases for the user.
databases collections List collections in a database.
databases stats Collection statistics for a database.
databases status Infrastructure provisioning status.
databases delete Delete a database and all its data.
webhooks register Register/update the org indexing webhook.
webhooks get Get the registered webhook.
webhooks test Send a test delivery.
webhooks delete Remove the webhook.
webhooks list_deliveries List recent deliveries.
webhooks get_delivery Fetch one delivery by ID.
webhooks retry_delivery Retry a failed delivery.

This SDK is generated from the HydraDB API definition. For the full parameter reference see src/hydra_db/reference.md or https://docs.hydradb.com.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hydradb_sdk-2.1.1.tar.gz (100.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hydradb_sdk-2.1.1-py3-none-any.whl (153.3 kB view details)

Uploaded Python 3

File details

Details for the file hydradb_sdk-2.1.1.tar.gz.

File metadata

  • Download URL: hydradb_sdk-2.1.1.tar.gz
  • Upload date:
  • Size: 100.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for hydradb_sdk-2.1.1.tar.gz
Algorithm Hash digest
SHA256 9d3bddde37e19d9523a4bf5cd70c7bbca08d3b14b5f41077ee632e7b07b65dfc
MD5 eb212dfa807c0820023b91bc3523724c
BLAKE2b-256 88328e23dab9adf2d6fd5cdf13f94c012581d0bcac614c6b872bf07ba723589e

See more details on using hashes here.

File details

Details for the file hydradb_sdk-2.1.1-py3-none-any.whl.

File metadata

  • Download URL: hydradb_sdk-2.1.1-py3-none-any.whl
  • Upload date:
  • Size: 153.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for hydradb_sdk-2.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 bf68d877320ac825a3be8ff2888a21e03655a54e63fd5595b453b621c4e6352d
MD5 1cf7f1a8e3528be433144a86ad967fd3
BLAKE2b-256 fa0e5d1713574f96cdacd45fd1ef52f3d700f3aa084830fbd463847caee91613

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page