Skip to main content

aspected-client

Python client for Aspected, a new kind of vector database that uses metadata as in-search signals, not filters.

Try Aspected locally

You can spin up a local instance of Aspected using Docker:

docker run -p 8080:8080 xillio/aspected:latest

This starts the Aspected server on http://localhost:8080, which you can point this client at. See the documentation for more information on getting started with the database setup.

Installation

pip install aspected-client

Quick Start

from aspected_client import AspectedClient, AspectedError

with AspectedClient(
    "http://localhost:8080", headers={"Authorization": "Bearer your-api-key"}
) as client:
    ...

Usage

aspected-client is a thin, httpx-based wrapper around the Aspected HTTP API (API reference). Every method on AspectedClient corresponds with an HTTP endpoint of the API. The client builds the request URL and query string, serializes the request body to JSON, sends the request (merging in any default httpx client options you provided, such as headers), and parses the JSON response into typed Pydantic models. If the server responds with a non-2xx status, the client raises an AspectedError instead of returning the response.

Indexes

from aspected_client import Aspect, AspectedClient, CreateIndexPayload, QuerySearch

client = AspectedClient("http://localhost:8080")

# List all indexes
list_resp = client.list_indexes()

# Create an index
client.create_index(
    "my-index",
    CreateIndexPayload(
        id_size=36,
        schema_=[
            Aspect(
                name="color",
                type="enum",
                path="$.color",
                settings={"values": ["red", "green", "blue"]},
                multiplier=1.0,
            ),
            Aspect(
                name="size",
                type="enum",
                path="$.size",
                settings={"values": ["small", "medium", "large"]},
                multiplier=1.0,
            ),
        ],
        hnsw={"M": 16, "efConstruction": 200},
    ),
)

# Get index details
index = client.get_index("my-index")

# Search an index
results = client.search_index(
    "my-index",
    QuerySearch(k=10, query={"color": "red"}),
)

# Delete an index
client.delete_index("my-index")

Documents

from aspected_client import UploadDocsPayload, UpsertOperation

# Upload documents
client.upload_docs(
    "my-index",
    UploadDocsPayload(
        data=[
            UpsertOperation(id="doc-1", doc={"color": "red", "size": "small"}),
            UpsertOperation(id="doc-2", doc={"color": "blue", "size": "large"}),
        ],
    ),
)

# Get a single document
doc = client.get_doc("my-index", "doc-1")

# List documents
docs = client.get_docs("my-index")

Raw vector queries

If you have pre-computed vectors you can pass them directly using the $raw syntax. The vector must match the number of dimensions produced by that aspect's resolver (e.g. an enum resolver with 3 values encodes to a 2-dimensional radial vector, as reported by client.get_index(...)):

from aspected_client import QuerySearch

results = client.search_index(
    "my-index",
    QuerySearch(k=5, query={"color": {"$raw": [0.1, 0.9]}}),
)

Error Handling

HTTP errors are automatically parsed and raised as AspectedError with the server's error message:

from aspected_client import AspectedError

try:
    client.get_index("nonexistent")
except AspectedError as err:
    print(err)  # Formatted message, e.g. "404 Not Found: ..."
    print(err.status)  # HTTP status code (e.g. 404)
    print(err.status_text)  # HTTP status text (e.g. "Not Found")
    print(err.error)  # Server error string, if provided

Configuration

The client constructor accepts a base URL and any additional keyword arguments accepted by httpx.Client. These are merged into every underlying request the client makes, so it's the place to set headers (e.g. authentication), timeouts, proxies, or any other native httpx option:

client = AspectedClient(
    "http://localhost:8080",  # API base URL
    headers={
        "Authorization": "Bearer your-api-key",  # Authentication header
        "X-Custom": "value",  # Any additional headers
    },
)

The client can also be used as a context manager (with AspectedClient(...) as client:) to automatically close the underlying connection pool, or closed manually via client.close().

Development

Prerequisites

  • Python 3.12+
  • uv package manager
uv sync

Regenerate the SDK from the OpenAPI spec

To (re-)generate the client and build a distributable package:

uv build

This single command both generates the client code in the src/aspected_client/ directory and produces distributable packages (wheel and source distribution) in the dist/ directory.

The build uses Hatchling as the build backend with a custom build hook (hatch_build.py). When uv build is invoked, the hook automatically runs the following steps before packaging:

  1. Preprocesses the OpenAPI spec — Reads openapi.json, normalises schema titles (renaming *Request/*Response suffixes to *Payload/*Result), and resolves naming collisions.
  2. Generates src/aspected_client/model.py — Uses datamodel-code-generator to produce Pydantic models from the preprocessed spec.
  3. Generates src/aspected_client/client.py — Renders the AspectedClient class from a Jinja2 template (templates/client.py.j2) with operation metadata extracted from the spec.
  4. Generates src/aspected_client/__init__.py — Renders a Jinja2 template (templates/__init__.py.j2) that re-exports all public symbols (client class and model classes).
  5. Formats & lints — Runs ruff format and ruff check --fix on all generated files.

After code generation completes, Hatchling packages the result into a wheel (containing only aspected_client/) and a source distribution (containing the spec, templates, and build hook so the client can be regenerated from source).

Checks

The same checks run in CI (see .github/workflows/ci.yml):

uv build                                # generated code is up to date
uv run ruff format --check              # formatting
uv run ruff check                       # lint
uv run ty check                         # type check

Configuration for ty lives under [tool.ty] in pyproject.toml.

Running the Quickstart Example

The quickstart example requires a running Aspected database on port 8080 with the nomic embed text model available. See the Getting Started guide for setting up the database.

uv run python examples/quickstart.py

The example demonstrates the full lifecycle of an Aspected index: creating an index, uploading documents, performing searches, and deleting the index.

License

MIT

Metadata

Release files for aspected-client 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aspected-client 0.3.0
File Size Uploaded
aspected_client-0.3.0.tar.gz 50.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aspected-client 0.3.0
File Interpreter ABI Platform
aspected_client-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 60.0 kB

Release files / aspected_client-0.3.0.tar.gz

Download URL aspected_client-0.3.0.tar.gz
Size 50.8 kB
Tags Source
SHA-256 checksum
How to use checksums
5bb02d519c1ff2cef1143763ff928fd720bd650d4d39935775276f825b525bcd
BLAKE2b-256 checksum
How to use checksums
365c8c87a76247f78c0c4929d90bfddf229612e3ce2857172923b985b33b9821
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / aspected_client-0.3.0-py3-none-any.whl

Download URL aspected_client-0.3.0-py3-none-any.whl
Size 9.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e81aa1df93f5c2648bb16c895226d47d40757a5a6c263bbe6c4bb59f39a1ca9d
BLAKE2b-256 checksum
How to use checksums
3f1a177ec673be0034645683054129189bf7a5a4572c11bca9597641efa95f90
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page