Skip to main content

Hermes Python client

Async Python client for the Hermes gRPC search server.

Installation

pip install hermes-client-python

Python 3.10 or newer is required.

Quick start

import asyncio

from hermes_client_python import HermesClient


async def main():
    async with HermesClient("localhost:50051") as client:
        await client.create_index(
            "articles",
            """
            index articles {
                field title: text<simple> [indexed, stored]
                field body: text<simple> [indexed, stored]
            }
            """,
        )

        indexed, error_count, errors = await client.index_documents(
            "articles",
            [
                {"title": "Hello World", "body": "First article"},
                {"title": "Hermes Search", "body": "Fast retrieval"},
            ],
        )
        if error_count:
            raise RuntimeError(errors)
        print(f"Indexed {indexed} documents")

        await client.commit("articles")

        results = await client.search(
            "articles",
            query={"match": {"field": "title", "text": "hello"}},
            fields_to_load=["title", "body"],
        )
        for hit in results.hits:
            print(hit.address, hit.score, hit.fields)

        if results.hits:
            document = await client.get_document("articles", results.hits[0].address)
            print(document.fields if document else "document not found")

        await client.delete_index("articles")


asyncio.run(main())

The context manager calls connect() and close() automatically. For manual lifecycle management:

client = HermesClient("localhost:50051")
await client.connect()
try:
    ...
finally:
    await client.close()

Index management

await client.create_index("articles", schema_sdl)
names = await client.list_indexes()
info = await client.get_index_info("articles")
print(info.num_docs, info.num_segments, info.vector_stats)

await client.force_merge("articles")
await client.reorder("articles")
await client.retrain_vector_index("articles")
await client.delete_index("articles")

commit() is required before newly indexed documents become searchable.

Batch and streaming indexing

indexed, error_count, errors = await client.index_documents(
    "articles",
    [
        {"title": "One", "tags": ["search", "rust"]},
        {"title": "Two", "tags": ["python"]},
    ],
)


async def documents():
    for number in range(10_000):
        yield {"title": f"Document {number}"}


streamed, stream_errors = await client.index_documents_stream("articles", documents())

Repeated list values become repeated field entries. Flat numeric lists are dense vectors; lists of (dimension, weight) pairs are sparse vectors.

Searching

Every search takes one query object whose single key matches a Hermes query variant:

# Exact term
await client.search(
    "articles",
    query={"term": {"field": "title", "term": "hermes"}},
)

# Tokenized full-text match
await client.search(
    "articles",
    query={"match": {"field": "body", "text": "fast retrieval"}},
)

# Recursive boolean query
await client.search(
    "articles",
    query={
        "boolean": {
            "must": [{"match": {"field": "body", "text": "retrieval"}}],
            "must_not": [{"term": {"field": "title", "term": "draft"}}],
        }
    },
)

# Dense vector query and optional reranking
await client.search(
    "articles",
    query={
        "dense_vector": {
            "field": "embedding",
            "vector": [0.1, 0.2, 0.3],
            "nprobe": 16,
        }
    },
    reranker={"field": "embedding", "vector": [0.1, 0.2, 0.3]},
    candidate_limit=20,
    limit=10,
    fields_to_load=["title"],
)

# Hybrid union fusion
await client.search(
    "articles",
    query={
        "fusion": {
            "method": "rrf",
            "rrf_k": 60,
            "queries": [
                {
                    "query": {
                        "sparse_vector": {
                            "field": "sparse_embedding",
                            "indices": [1, 5],
                            "values": [0.8, 0.2],
                        }
                    },
                    "weight": 1.0,
                },
                {
                    "query": {
                        "dense_vector": {
                            "field": "embedding",
                            "vector": [0.1, 0.2, 0.3],
                        }
                    },
                    "weight": 1.0,
                },
            ],
        }
    },
)

Other supported variants are binary_dense_vector, boost, range, prefix, and all. Search results expose the full DocAddress needed by get_document():

hit = results.hits[0]
document = await client.get_document("articles", hit.address)

Deadlines and errors

Every RPC accepts an optional timeout in seconds. A per-call value overrides the client default:

client = HermesClient("localhost:50051", default_timeout=5.0)
results = await client.search(
    "articles",
    query={"all": {}},
    timeout=0.5,
)
await client.force_merge("articles", timeout=3600)

gRPC failures raise grpc.RpcError (normally grpc.aio.AioRpcError). get_document() is the exception: it returns None for NOT_FOUND.

import grpc

try:
    await client.search("missing", query={"all": {}})
except grpc.RpcError as error:
    if error.code() == grpc.StatusCode.NOT_FOUND:
        print("index not found")
    else:
        raise

Development

From hermes-client-python:

uv sync --group dev --group test
uv run ruff check .
uv run ruff format --check .
uv run pytest tests/test_client_unit.py

The remaining tests are integration tests and expect a debug target/debug/hermes-server binary. Regenerate checked-in protobuf stubs after changing hermes-proto/hermes.proto:

uv run --group dev python generate_proto.py

License

MIT

Download files

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

Source Distribution

hermes_client_python-1.8.111.tar.gz (18.3 kB view details)

Uploaded Source

Built Distribution

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

hermes_client_python-1.8.111-py3-none-any.whl (19.8 kB view details)

Uploaded Python 3

File details

Details for the file hermes_client_python-1.8.111.tar.gz.

File metadata

  • Download URL: hermes_client_python-1.8.111.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.6 {"installer":{"name":"uv","version":"0.12.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for hermes_client_python-1.8.111.tar.gz
Algorithm Hash digest
SHA256 d900581bafedb669fb0f63074402354eb37f1fe2ce00989a58da8d8c2fb596e8
MD5 3dca19044d54eeca666a161f6ba69ffa
BLAKE2b-256 8654e8f4292a4b344788a82a4b1089f258bd416fb1f82346d4209232890d51f5

See more details on using hashes here.

File details

Details for the file hermes_client_python-1.8.111-py3-none-any.whl.

File metadata

  • Download URL: hermes_client_python-1.8.111-py3-none-any.whl
  • Upload date:
  • Size: 19.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.6 {"installer":{"name":"uv","version":"0.12.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for hermes_client_python-1.8.111-py3-none-any.whl
Algorithm Hash digest
SHA256 70d522bc2c4d336d550d66ea760e1d6b13f82747094618040b4e992bc413bedb
MD5 f89702036aca073c6dbef5997cb52b3b
BLAKE2b-256 dc9da07db400fce729b759e55af0e58b4df557a1fac0b8002018a51fce10275d

See more details on using hashes here.

Release history Release notifications | RSS feed

1.8.127

2 files

1.8.124

2 files

1.8.123

2 files

1.8.122

2 files

1.8.121

2 files

1.8.120

2 files

1.8.119

2 files

1.8.118

2 files

1.8.117

2 files

1.8.116

2 files

1.8.115

2 files

1.8.114

2 files

1.8.113

2 files

1.8.112

2 files

This release

1.8.111 This release

2 files

1.8.110

2 files

1.8.109

2 files

1.8.108

2 files

1.8.107

2 files

1.8.105

2 files

1.8.104

2 files

1.8.103

2 files

1.8.102

2 files

1.8.101

2 files

1.8.100

2 files

1.8.99

2 files

1.8.98

2 files

1.8.97

2 files

1.8.96

2 files

1.8.95

2 files

1.8.94

2 files

1.8.93

2 files

1.8.92

2 files

1.8.91

2 files

1.8.90

2 files

1.8.89

2 files

1.8.88

2 files

1.8.87

2 files

1.8.86

2 files

1.8.85

2 files

1.8.84

2 files

1.8.83

2 files

1.8.82

2 files

1.8.81

2 files

1.8.80

2 files

1.8.79

2 files

1.8.78

2 files

1.8.77

2 files

1.8.76

2 files

1.8.75

2 files

1.8.74

2 files

1.8.73

2 files

1.8.72

2 files

1.8.71

2 files

1.8.70

2 files

1.8.69

2 files

1.8.68

2 files

1.8.67

2 files

1.8.66

2 files

1.8.65

2 files

1.8.64

2 files

1.8.63

2 files

1.8.62

2 files

1.8.61

2 files

1.8.60

2 files

1.8.59

2 files

1.8.58

2 files

1.8.57

2 files

1.8.56

2 files

1.8.55

2 files

1.8.54

2 files

1.8.53

2 files

1.8.52

2 files

1.8.51

2 files

1.8.50

2 files

1.8.49

2 files

1.8.48

2 files

1.8.47

2 files

1.8.45

2 files

1.8.44

2 files

1.8.43

2 files

1.8.41

2 files

1.8.40

2 files

1.8.39

2 files

1.8.38

2 files

1.8.37

2 files

1.8.36

2 files

1.8.35

2 files

1.8.34

2 files

1.8.33

2 files

1.8.32

2 files

1.8.31

2 files

1.8.30

2 files

1.8.29

2 files

1.8.28

2 files

1.8.27

2 files

1.8.26

2 files

1.8.25

2 files

1.8.24

2 files

1.8.23

2 files

1.8.22

2 files

1.8.21

2 files

1.8.20

2 files

1.8.19

2 files

1.8.18

2 files

1.8.17

2 files

1.8.16

2 files

1.8.15

2 files

1.8.14

2 files

1.8.13

2 files

1.8.12

2 files

1.8.11

2 files

1.8.10

2 files

1.8.9

2 files

1.8.8

2 files

1.8.7

2 files

1.8.6

2 files

1.8.5

2 files

1.8.4

2 files

1.8.3

2 files

1.8.2

2 files

1.8.1

2 files

1.8.0

2 files

1.7.98

2 files

1.7.97

2 files

1.7.59

2 files

1.7.56

2 files

1.7.55

2 files

1.7.54

2 files

1.7.52

2 files

1.7.51

2 files

1.7.50

2 files

1.7.49

2 files

1.7.48

2 files

1.7.47

2 files

1.7.46

2 files

1.7.45

2 files

1.7.44

2 files

1.7.43

2 files

1.7.42

2 files

1.7.41

2 files

1.7.40

2 files

1.7.39

2 files

1.7.38

2 files

1.7.37

2 files

1.7.36

2 files

1.7.35

2 files

1.7.34

2 files

1.7.33

2 files

1.7.32

2 files

1.7.31

2 files

1.7.30

2 files

1.7.29

2 files

1.7.28

2 files

1.7.27

2 files

1.7.26

2 files

1.7.25

2 files

1.7.24

2 files

1.7.23

2 files

1.7.22

2 files

1.7.21

2 files

1.7.20

2 files

1.7.19

2 files

1.7.18

2 files

1.7.17

2 files

1.7.16

2 files

1.7.15

2 files

1.7.14

2 files

1.7.13

2 files

1.7.12

2 files

1.7.11

2 files

1.7.10

2 files

1.7.9

2 files

1.7.8

2 files

1.7.7

2 files

1.7.6

2 files

1.7.5

2 files

1.7.4

2 files

1.7.3

2 files

1.7.2

2 files

1.7.1

2 files

1.7.0

2 files

1.6.16

2 files

1.6.15

2 files

1.6.14

2 files

1.6.13

2 files

1.6.12

2 files

1.6.11

2 files

1.6.10

2 files

1.6.9

2 files

1.6.8

2 files

1.6.7

2 files

1.6.6

2 files

1.6.5

2 files

1.6.4

2 files

1.6.3

2 files

1.6.2

2 files

1.6.1

2 files

1.5.2

2 files

1.5.1

2 files

1.5.0

2 files

1.4.80

2 files

1.4.79

2 files

1.4.78

2 files

1.4.77

2 files

1.4.76

2 files

1.4.75

2 files

1.4.74

2 files

1.4.73

2 files

1.4.72

2 files

1.4.71

2 files

1.4.70

2 files

1.4.69

2 files

1.4.68

2 files

1.4.67

2 files

1.4.66

2 files

1.4.65

2 files

1.4.64

2 files

1.4.63

2 files

1.4.62

2 files

1.4.61

2 files

1.4.60

2 files

1.4.59

2 files

1.4.57

2 files

1.4.56

2 files

1.4.55

2 files

1.4.54

2 files

1.4.53

2 files

1.4.52

2 files

1.4.51

2 files

1.4.50

2 files

1.4.49

2 files

1.4.48

2 files

1.4.47

2 files

1.4.46

2 files

1.4.45

2 files

1.4.44

2 files

1.4.43

2 files

1.4.42

2 files

1.4.40

2 files

1.4.39

2 files

1.4.38

2 files

1.4.37

2 files

1.4.36

2 files

1.4.35

2 files

1.4.34

2 files

1.4.33

2 files

1.4.32

2 files

1.4.31

2 files

1.4.30

2 files

1.4.29

2 files

1.4.28

2 files

1.4.27

2 files

1.4.26

2 files

1.4.25

2 files

1.4.24

2 files

1.4.23

2 files

1.4.22

2 files

1.4.21

2 files

1.4.20

2 files

1.4.18

2 files

1.4.17

2 files

1.4.16

2 files

1.4.15

2 files

1.4.14

2 files

1.4.13

2 files

1.4.12

2 files

1.4.11

2 files

1.4.10

2 files

1.4.9

2 files

1.4.8

2 files

1.4.7

2 files

1.4.6

2 files

1.4.5

2 files

1.4.4

2 files

1.4.3

2 files

1.4.1

2 files

1.4.0

2 files

1.3.4

2 files

1.3.3

2 files

1.3.2

2 files

1.3.1

2 files

1.2.7

2 files

1.2.6

2 files

1.2.5

2 files

1.2.4

2 files

1.2.3

2 files

1.2.2

2 files

1.2.1

2 files

1.0.4

2 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