hermes-client-python 1.4.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,232 @@
1
+ Metadata-Version: 2.4
2
+ Name: hermes-client-python
3
+ Version: 1.4.11
4
+ Summary: Async Python client for Hermes search server
5
+ Project-URL: Homepage, https://github.com/SpaceFrontiers/hermes
6
+ Project-URL: Repository, https://github.com/SpaceFrontiers/hermes
7
+ Author: izihawa
8
+ License-Expression: MIT
9
+ Keywords: async,full-text-search,grpc,search
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Database :: Database Engines/Servers
19
+ Classifier: Topic :: Text Processing :: Indexing
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: grpcio>=1.76.0
22
+ Requires-Dist: protobuf>=6.33.4
23
+ Description-Content-Type: text/markdown
24
+
25
+ # Hermes Client
26
+
27
+ Async Python client for [Hermes](https://github.com/SpaceFrontiers/hermes) search server.
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ pip install hermes-client-python
33
+ ```
34
+
35
+ ## Quick Start
36
+
37
+ ```python
38
+ import asyncio
39
+ from hermes_client_python import HermesClient
40
+
41
+ async def main():
42
+ async with HermesClient("localhost:50051") as client:
43
+ # Create index with SDL schema
44
+ await client.create_index("articles", '''
45
+ index articles {
46
+ title: text indexed stored
47
+ body: text indexed stored
48
+ score: f64 stored
49
+ }
50
+ ''')
51
+
52
+ # Index documents
53
+ await client.index_documents("articles", [
54
+ {"title": "Hello World", "body": "First article", "score": 1.5},
55
+ {"title": "Goodbye World", "body": "Last article", "score": 2.0},
56
+ ])
57
+
58
+ # Commit changes
59
+ await client.commit("articles")
60
+
61
+ # Search
62
+ results = await client.search("articles", term=("title", "hello"), limit=10)
63
+ for hit in results.hits:
64
+ print(f"Doc {hit.doc_id}: score={hit.score}, fields={hit.fields}")
65
+
66
+ # Get document by ID
67
+ doc = await client.get_document("articles", 0)
68
+ print(doc.fields)
69
+
70
+ # Delete index
71
+ await client.delete_index("articles")
72
+
73
+ asyncio.run(main())
74
+ ```
75
+
76
+ ## API Reference
77
+
78
+ ### HermesClient
79
+
80
+ ```python
81
+ client = HermesClient(address="localhost:50051")
82
+ ```
83
+
84
+ #### Connection
85
+
86
+ ```python
87
+ # Using context manager (recommended)
88
+ async with HermesClient("localhost:50051") as client:
89
+ ...
90
+
91
+ # Manual connection
92
+ client = HermesClient("localhost:50051")
93
+ await client.connect()
94
+ # ... use client ...
95
+ await client.close()
96
+ ```
97
+
98
+ #### Index Management
99
+
100
+ ```python
101
+ # Create index with SDL schema
102
+ await client.create_index("myindex", '''
103
+ index myindex {
104
+ title: text indexed stored
105
+ body: text indexed stored
106
+ }
107
+ ''')
108
+
109
+ # Create index with JSON schema
110
+ await client.create_index("myindex", '''
111
+ {
112
+ "fields": [
113
+ {"name": "title", "type": "text", "indexed": true, "stored": true},
114
+ {"name": "body", "type": "text", "indexed": true, "stored": true}
115
+ ]
116
+ }
117
+ ''')
118
+
119
+ # Get index info
120
+ info = await client.get_index_info("myindex")
121
+ print(f"Documents: {info.num_docs}, Segments: {info.num_segments}")
122
+
123
+ # Delete index
124
+ await client.delete_index("myindex")
125
+ ```
126
+
127
+ #### Document Indexing
128
+
129
+ ```python
130
+ # Index multiple documents (batch)
131
+ indexed, errors = await client.index_documents("myindex", [
132
+ {"title": "Doc 1", "body": "Content 1"},
133
+ {"title": "Doc 2", "body": "Content 2"},
134
+ ])
135
+
136
+ # Index single document
137
+ await client.index_document("myindex", {"title": "Doc", "body": "Content"})
138
+
139
+ # Stream documents (for large datasets)
140
+ async def doc_generator():
141
+ for i in range(10000):
142
+ yield {"title": f"Doc {i}", "body": f"Content {i}"}
143
+
144
+ count = await client.index_documents_stream("myindex", doc_generator())
145
+
146
+ # Commit changes (required to make documents searchable)
147
+ num_docs = await client.commit("myindex")
148
+
149
+ # Force merge segments (for optimization)
150
+ num_segments = await client.force_merge("myindex")
151
+ ```
152
+
153
+ #### Searching
154
+
155
+ ```python
156
+ # Term query
157
+ results = await client.search("myindex", term=("title", "hello"), limit=10)
158
+
159
+ # Boolean query
160
+ results = await client.search("myindex", boolean={
161
+ "must": [("title", "hello")],
162
+ "should": [("body", "world")],
163
+ "must_not": [("title", "spam")],
164
+ })
165
+
166
+ # With pagination
167
+ results = await client.search("myindex", term=("title", "hello"), limit=10, offset=20)
168
+
169
+ # With field loading
170
+ results = await client.search(
171
+ "myindex",
172
+ term=("title", "hello"),
173
+ fields_to_load=["title", "body"]
174
+ )
175
+
176
+ # Access results
177
+ for hit in results.hits:
178
+ print(f"Doc {hit.doc_id}: {hit.score}")
179
+ print(f" Title: {hit.fields.get('title')}")
180
+
181
+ print(f"Total hits: {results.total_hits}")
182
+ print(f"Took: {results.took_ms}ms")
183
+ ```
184
+
185
+ #### Document Retrieval
186
+
187
+ ```python
188
+ # Get document by ID
189
+ doc = await client.get_document("myindex", doc_id=42)
190
+ if doc:
191
+ print(doc.fields["title"])
192
+ ```
193
+
194
+ ## Field Types
195
+
196
+ | Type | Python Type | Description |
197
+ | --------------- | --------------- | ------------------------------------- |
198
+ | `text` | `str` | Full-text searchable string |
199
+ | `u64` | `int` (>= 0) | Unsigned 64-bit integer |
200
+ | `i64` | `int` | Signed 64-bit integer |
201
+ | `f64` | `float` | 64-bit floating point |
202
+ | `bytes` | `bytes` | Binary data |
203
+ | `json` | `dict` / `list` | JSON object (auto-serialized) |
204
+ | `dense_vector` | `list[float]` | Dense vector for semantic search |
205
+ | `sparse_vector` | `dict` | Sparse vector with indices and values |
206
+
207
+ ## Error Handling
208
+
209
+ ```python
210
+ import grpc
211
+
212
+ try:
213
+ await client.search("nonexistent", term=("field", "value"))
214
+ except grpc.RpcError as e:
215
+ if e.code() == grpc.StatusCode.NOT_FOUND:
216
+ print("Index not found")
217
+ else:
218
+ raise
219
+ ```
220
+
221
+ ## Development
222
+
223
+ Generate protobuf stubs:
224
+
225
+ ```bash
226
+ pip install grpcio-tools
227
+ python generate_proto.py
228
+ ```
229
+
230
+ ## License
231
+
232
+ MIT
@@ -0,0 +1,8 @@
1
+ hermes_client_python/__init__.py,sha256=qUaFnTSVr4fSOXfRHJIu8ur5IJEChfIJPOqTC0MiIMw,282
2
+ hermes_client_python/client.py,sha256=wPkMQk43YgvGaFX8ZAWu6h5mxXKvyfGzXXFVGNcyurs,19009
3
+ hermes_client_python/hermes_pb2.py,sha256=GryWk909ocMfKLqlueNQNtDoFmuwj7hvY5ibq4HJduc,10532
4
+ hermes_client_python/hermes_pb2_grpc.py,sha256=aFn4mHdGUWnFBtfzHue9i-kATCNVlE1pjIeW9QXhXIA,17463
5
+ hermes_client_python/types.py,sha256=e6_amiC4F9AkOSzAB9woAfLf9gooN9Y-rzJShrR9YEo,954
6
+ hermes_client_python-1.4.11.dist-info/METADATA,sha256=5492c_z4BlBO9xBTjn6OJvmM9hNPdcSf52CayszuVhY,6121
7
+ hermes_client_python-1.4.11.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
8
+ hermes_client_python-1.4.11.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any