Async Python client for Hermes search server
Project description
Hermes Client
Async Python client for Hermes search server.
Installation
pip install hermes-client-python
Quick Start
import asyncio
from hermes_client_python import HermesClient
async def main():
async with HermesClient("localhost:50051") as client:
# Create index with SDL schema
await client.create_index("articles", '''
index articles {
title: text indexed stored
body: text indexed stored
score: f64 stored
}
''')
# Index documents
await client.index_documents("articles", [
{"title": "Hello World", "body": "First article", "score": 1.5},
{"title": "Goodbye World", "body": "Last article", "score": 2.0},
])
# Commit changes
await client.commit("articles")
# Search
results = await client.search("articles", term=("title", "hello"), limit=10)
for hit in results.hits:
print(f"Doc {hit.doc_id}: score={hit.score}, fields={hit.fields}")
# Get document by ID
doc = await client.get_document("articles", 0)
print(doc.fields)
# Delete index
await client.delete_index("articles")
asyncio.run(main())
API Reference
HermesClient
client = HermesClient(address="localhost:50051")
Connection
# Using context manager (recommended)
async with HermesClient("localhost:50051") as client:
...
# Manual connection
client = HermesClient("localhost:50051")
await client.connect()
# ... use client ...
await client.close()
Index Management
# Create index with SDL schema
await client.create_index("myindex", '''
index myindex {
title: text indexed stored
body: text indexed stored
}
''')
# Create index with JSON schema
await client.create_index("myindex", '''
{
"fields": [
{"name": "title", "type": "text", "indexed": true, "stored": true},
{"name": "body", "type": "text", "indexed": true, "stored": true}
]
}
''')
# Get index info
info = await client.get_index_info("myindex")
print(f"Documents: {info.num_docs}, Segments: {info.num_segments}")
# Delete index
await client.delete_index("myindex")
Document Indexing
# Index multiple documents (batch)
indexed, errors = await client.index_documents("myindex", [
{"title": "Doc 1", "body": "Content 1"},
{"title": "Doc 2", "body": "Content 2"},
])
# Index single document
await client.index_document("myindex", {"title": "Doc", "body": "Content"})
# Stream documents (for large datasets)
async def doc_generator():
for i in range(10000):
yield {"title": f"Doc {i}", "body": f"Content {i}"}
count = await client.index_documents_stream("myindex", doc_generator())
# Commit changes (required to make documents searchable)
num_docs = await client.commit("myindex")
# Force merge segments (for optimization)
num_segments = await client.force_merge("myindex")
Searching
# Term query
results = await client.search("myindex", term=("title", "hello"), limit=10)
# Boolean query
results = await client.search("myindex", boolean={
"must": [("title", "hello")],
"should": [("body", "world")],
"must_not": [("title", "spam")],
})
# With pagination
results = await client.search("myindex", term=("title", "hello"), limit=10, offset=20)
# With field loading
results = await client.search(
"myindex",
term=("title", "hello"),
fields_to_load=["title", "body"]
)
# Access results
for hit in results.hits:
print(f"Doc {hit.doc_id}: {hit.score}")
print(f" Title: {hit.fields.get('title')}")
print(f"Total hits: {results.total_hits}")
print(f"Took: {results.took_ms}ms")
Document Retrieval
# Get document by ID
doc = await client.get_document("myindex", doc_id=42)
if doc:
print(doc.fields["title"])
Field Types
| Type | Python Type | Description |
|---|---|---|
text |
str |
Full-text searchable string |
u64 |
int (>= 0) |
Unsigned 64-bit integer |
i64 |
int |
Signed 64-bit integer |
f64 |
float |
64-bit floating point |
bytes |
bytes |
Binary data |
json |
dict / list |
JSON object (auto-serialized) |
dense_vector |
list[float] |
Dense vector for semantic search |
sparse_vector |
dict |
Sparse vector with indices and values |
Error Handling
import grpc
try:
await client.search("nonexistent", term=("field", "value"))
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
print("Index not found")
else:
raise
Development
Generate protobuf stubs:
pip install grpcio-tools
python generate_proto.py
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hermes_client_python-1.4.43.tar.gz.
File metadata
- Download URL: hermes_client_python-1.4.43.tar.gz
- Upload date:
- Size: 12.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
296867f223507e8518c9721dd1503a32477209fe562173a659dc115db10cd8fb
|
|
| MD5 |
6b64904094ea82a5267bcc1a7f4a303f
|
|
| BLAKE2b-256 |
a77d7310d8c573f46a632c820798bfd51c9bb7a98fede1b4e908ac4342f1ae7d
|
File details
Details for the file hermes_client_python-1.4.43-py3-none-any.whl.
File metadata
- Download URL: hermes_client_python-1.4.43-py3-none-any.whl
- Upload date:
- Size: 14.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50d375c6f04173b48ebb119ad995981e9d92e876f9261605b8e102880fe0016d
|
|
| MD5 |
2ab1eff64d881b941c045814776174e5
|
|
| BLAKE2b-256 |
868dfc7f56f2c65ad98057f7aeff0540a2ab0fd3efdbb5d12779322ab34c3c36
|