ekodb-client 0.1.0__tar.gz

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.
Files changed (32) hide show
  1. ekodb_client-0.1.0/Cargo.toml +23 -0
  2. ekodb_client-0.1.0/PKG-INFO +461 -0
  3. ekodb_client-0.1.0/README.md +436 -0
  4. ekodb_client-0.1.0/ekodb-client-py/Cargo.lock +2556 -0
  5. ekodb_client-0.1.0/ekodb-client-py/Cargo.toml +23 -0
  6. ekodb_client-0.1.0/ekodb-client-py/DEVELOPMENT.md +84 -0
  7. ekodb_client-0.1.0/ekodb-client-py/README.md +436 -0
  8. ekodb_client-0.1.0/ekodb-client-py/python/ekodb_client/__init__.py +52 -0
  9. ekodb_client-0.1.0/ekodb-client-py/src/lib.rs +1216 -0
  10. ekodb_client-0.1.0/ekodb_client/.gitignore +14 -0
  11. ekodb_client-0.1.0/ekodb_client/CHANGELOG.md +40 -0
  12. ekodb_client-0.1.0/ekodb_client/Cargo.toml +41 -0
  13. ekodb_client-0.1.0/ekodb_client/DEVELOPMENT.md +241 -0
  14. ekodb_client-0.1.0/ekodb_client/README.md +644 -0
  15. ekodb_client-0.1.0/ekodb_client/src/auth.rs +148 -0
  16. ekodb_client-0.1.0/ekodb_client/src/batch.rs +105 -0
  17. ekodb_client-0.1.0/ekodb_client/src/chat.rs +464 -0
  18. ekodb_client-0.1.0/ekodb_client/src/client.rs +1120 -0
  19. ekodb_client-0.1.0/ekodb_client/src/error.rs +106 -0
  20. ekodb_client-0.1.0/ekodb_client/src/http.rs +1090 -0
  21. ekodb_client-0.1.0/ekodb_client/src/join.rs +134 -0
  22. ekodb_client-0.1.0/ekodb_client/src/lib.rs +77 -0
  23. ekodb_client-0.1.0/ekodb_client/src/query.rs +7 -0
  24. ekodb_client-0.1.0/ekodb_client/src/query_builder.rs +565 -0
  25. ekodb_client-0.1.0/ekodb_client/src/retry.rs +151 -0
  26. ekodb_client-0.1.0/ekodb_client/src/schema.rs +402 -0
  27. ekodb_client-0.1.0/ekodb_client/src/search.rs +462 -0
  28. ekodb_client-0.1.0/ekodb_client/src/types.rs +576 -0
  29. ekodb_client-0.1.0/ekodb_client/src/websocket.rs +215 -0
  30. ekodb_client-0.1.0/ekodb_client/tests/integration_test.rs +97 -0
  31. ekodb_client-0.1.0/pyproject.toml +38 -0
  32. ekodb_client-0.1.0/python/ekodb_client/__init__.py +52 -0
@@ -0,0 +1,23 @@
1
+ [workspace]
2
+ members = [
3
+ "ekodb_server",
4
+ "ekodb_client",
5
+ ]
6
+ exclude = [
7
+ "examples/rust",
8
+ "ekodb-client-py", # Python package, built with maturin
9
+ ]
10
+ resolver = "2"
11
+
12
+ [workspace.dependencies]
13
+ # Shared dependencies across workspace members
14
+ serde = { version = "1.0", features = ["derive"] }
15
+ serde_json = "1.0"
16
+ tokio = { version = "1", features = ["full"] }
17
+ reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false }
18
+ chrono = { version = "0.4.38", features = ["serde"] }
19
+ rust_decimal = "1.33"
20
+ uuid = { version = "1.10.0", features = ["serde", "v4"] }
21
+ thiserror = "1.0"
22
+ base64 = "0.22.1"
23
+ log = "0.4"
@@ -0,0 +1,461 @@
1
+ Metadata-Version: 2.4
2
+ Name: ekodb_client
3
+ Version: 0.1.0
4
+ Classifier: Development Status :: 4 - Beta
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: MIT License
7
+ Classifier: License :: OSI Approved :: Apache Software License
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.8
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Rust
15
+ Summary: Python client for ekoDB - a high-performance document database
16
+ Keywords: database,ekodb,document-database,nosql
17
+ Author: ekoDB Team
18
+ License: MIT OR Apache-2.0
19
+ Requires-Python: >=3.8
20
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
21
+ Project-URL: Homepage, https://github.com/ekoDB/ekodb
22
+ Project-URL: Repository, https://github.com/ekoDB/ekodb
23
+ Project-URL: Documentation, https://github.com/ekoDB/ekodb/tree/main/documentation
24
+
25
+ # ekoDB Python Client
26
+
27
+ High-performance Python client for ekoDB, built with Rust for speed and safety.
28
+
29
+ This package wraps the `ekodb_client` Rust library using PyO3 to provide a
30
+ native Python interface.
31
+
32
+ ## Features
33
+
34
+ - ✅ **Fast**: Built with Rust, leveraging the same client library as the Rust
35
+ SDK
36
+ - ✅ **Type-safe**: Strong typing with Python type hints
37
+ - ✅ **Async/await**: Full async support using Python's asyncio
38
+ - ✅ **Easy to use**: Pythonic API that feels natural
39
+ - ✅ **Complete**: All ekoDB features supported
40
+ - ✅ **Query Builder** - Fluent API for complex queries with operators, sorting,
41
+ and pagination
42
+ - ✅ **Search** - Full-text search, fuzzy search, and field-specific search with
43
+ scoring
44
+ - ✅ **Schema Management** - Define and enforce data schemas with validation
45
+ - ✅ **Join Operations** - Single and multi-collection joins with queries
46
+ - ✅ **Rate limiting with automatic retry** (429, 503, network errors)
47
+ - ✅ **Rate limit tracking** (`X-RateLimit-*` headers)
48
+ - ✅ **Configurable retry behavior**
49
+ - ✅ **Retry-After header support**
50
+
51
+ ## Installation
52
+
53
+ ```bash
54
+ pip install ekodb
55
+ ```
56
+
57
+ Or install from source:
58
+
59
+ ```bash
60
+ cd ekodb-py
61
+ pip install maturin
62
+ maturin develop
63
+ ```
64
+
65
+ ## Quick Start
66
+
67
+ ```python
68
+ import asyncio
69
+ from ekodb_client import Client, RateLimitError
70
+
71
+ async def main():
72
+ # Create client with configuration
73
+ client = Client.new(
74
+ "http://localhost:8080",
75
+ "your-api-key",
76
+ should_retry=True, # Enable automatic retries (default: True)
77
+ max_retries=3, # Maximum retry attempts (default: 3)
78
+ timeout_secs=30 # Request timeout in seconds (default: 30)
79
+ )
80
+
81
+ try:
82
+ # Insert a document
83
+ record = await client.insert("users", {
84
+ "name": "John Doe",
85
+ "age": 30,
86
+ "email": "john@example.com",
87
+ "active": True
88
+ })
89
+ print(f"Inserted: {record['id']}")
90
+
91
+ # Find by ID
92
+ user = await client.find_by_id("users", record["id"])
93
+ print(f"Found: {user}")
94
+
95
+ # Find with query
96
+ results = await client.find("users", limit=10)
97
+ print(f"Found {len(results)} users")
98
+
99
+ # Update
100
+ updated = await client.update("users", record["id"], {
101
+ "age": 31
102
+ })
103
+ print(f"Updated: {updated}")
104
+
105
+ # Delete
106
+ await client.delete("users", record["id"])
107
+ print("Deleted")
108
+
109
+ except RateLimitError as e:
110
+ print(f"Rate limited! Retry after {e.retry_after_secs} seconds")
111
+
112
+ asyncio.run(main())
113
+ ```
114
+
115
+ ## Usage Examples
116
+
117
+ ### Query Builder
118
+
119
+ ```python
120
+ from ekodb_client import Client, QueryBuilder
121
+
122
+ async def main():
123
+ client = Client.new("http://localhost:8080", "your-api-key")
124
+
125
+ # Simple query with operators
126
+ query = QueryBuilder() \
127
+ .eq("status", "active") \
128
+ .gte("age", 18) \
129
+ .lt("age", 65) \
130
+ .limit(10) \
131
+ .build()
132
+
133
+ results = await client.find("users", query)
134
+
135
+ # Complex query with sorting and pagination
136
+ query = QueryBuilder() \
137
+ .in_array("status", ["active", "pending"]) \
138
+ .contains("email", "@example.com") \
139
+ .sort_desc("created_at") \
140
+ .skip(20) \
141
+ .limit(10) \
142
+ .build()
143
+
144
+ results = await client.find("users", query)
145
+ ```
146
+
147
+ ### Search Operations
148
+
149
+ ```python
150
+ # Basic text search
151
+ search_query = {
152
+ "query": "programming",
153
+ "min_score": 0.1,
154
+ "limit": 10
155
+ }
156
+
157
+ results = await client.search("articles", search_query)
158
+ for result in results["results"]:
159
+ print(f"Score: {result['score']:.4f} - {result['record']['title']}")
160
+
161
+ # Search with field weights
162
+ search_query = {
163
+ "query": "rust database",
164
+ "fields": ["title", "description"],
165
+ "weights": {"title": 2.0},
166
+ "limit": 5
167
+ }
168
+
169
+ results = await client.search("articles", search_query)
170
+ ```
171
+
172
+ ### Schema Management
173
+
174
+ ```python
175
+ # Create a collection with schema
176
+ schema = {
177
+ "fields": {
178
+ "name": {
179
+ "field_type": "String",
180
+ "required": True,
181
+ "regex": "^[a-zA-Z ]+$"
182
+ },
183
+ "email": {
184
+ "field_type": "String",
185
+ "required": True,
186
+ "unique": True
187
+ },
188
+ "age": {
189
+ "field_type": "Integer",
190
+ "min": 0,
191
+ "max": 150
192
+ }
193
+ }
194
+ }
195
+
196
+ await client.create_collection("users", schema)
197
+
198
+ # Get collection schema
199
+ schema = await client.get_schema("users")
200
+ ```
201
+
202
+ ### Join Operations
203
+
204
+ ```python
205
+ # Single collection join
206
+ query = {
207
+ "$join": {
208
+ "collection": "departments",
209
+ "local_field": "department_id",
210
+ "foreign_field": "id",
211
+ "as": "department"
212
+ },
213
+ "$limit": 10
214
+ }
215
+
216
+ results = await client.find("users", query)
217
+
218
+ # Multi-collection join
219
+ query = {
220
+ "$join": [
221
+ {
222
+ "collection": "departments",
223
+ "local_field": "department_id",
224
+ "foreign_field": "id",
225
+ "as": "department"
226
+ },
227
+ {
228
+ "collection": "profiles",
229
+ "local_field": "id",
230
+ "foreign_field": "id",
231
+ "as": "profile"
232
+ }
233
+ ],
234
+ "$limit": 10
235
+ }
236
+
237
+ results = await client.find("users", query)
238
+ ```
239
+
240
+ ## API Reference
241
+
242
+ ### Client
243
+
244
+ #### `Client.new(base_url: str, api_key: str, should_retry: bool = True, max_retries: int = 3, timeout_secs: int = 30) -> Client`
245
+
246
+ Create a new ekoDB client.
247
+
248
+ **Parameters:**
249
+
250
+ - `base_url`: The base URL of the ekoDB server
251
+ - `api_key`: Your API key
252
+ - `should_retry`: Enable automatic retries (default: True)
253
+ - `max_retries`: Maximum number of retry attempts (default: 3)
254
+ - `timeout_secs`: Request timeout in seconds (default: 30)
255
+
256
+ **Returns:**
257
+
258
+ - A new `Client` instance
259
+
260
+ ### RateLimitInfo
261
+
262
+ Rate limit information is automatically tracked and logged by the client. The
263
+ client will automatically retry on rate limit errors using the server's
264
+ `Retry-After` header.
265
+
266
+ #### Properties
267
+
268
+ - `limit: int` - Maximum requests allowed per window
269
+ - `remaining: int` - Requests remaining in current window
270
+ - `reset: int` - Unix timestamp when the rate limit resets
271
+
272
+ #### Methods
273
+
274
+ - `is_near_limit() -> bool` - Check if approaching rate limit (<10% remaining)
275
+ - `is_exceeded() -> bool` - Check if the rate limit has been exceeded
276
+ - `remaining_percentage() -> float` - Get the percentage of requests remaining
277
+
278
+ ### RateLimitError
279
+
280
+ Exception raised when rate limit is exceeded (if retries are disabled or
281
+ exhausted).
282
+
283
+ #### Properties
284
+
285
+ - `retry_after_secs: int` - Number of seconds to wait before retrying
286
+
287
+ #### `await client.insert(collection: str, record: dict) -> dict`
288
+
289
+ Insert a document into a collection.
290
+
291
+ **Parameters:**
292
+
293
+ - `collection`: The collection name
294
+ - `record`: A dictionary representing the document
295
+
296
+ **Returns:**
297
+
298
+ - The inserted document with ID
299
+
300
+ #### `await client.find_by_id(collection: str, id: str) -> dict`
301
+
302
+ Find a document by ID.
303
+
304
+ **Parameters:**
305
+
306
+ - `collection`: The collection name
307
+ - `id`: The document ID
308
+
309
+ **Returns:**
310
+
311
+ - The found document
312
+
313
+ #### `await client.find(collection: str, limit: Optional[int] = None) -> List[dict]`
314
+
315
+ Find documents in a collection.
316
+
317
+ **Parameters:**
318
+
319
+ - `collection`: The collection name
320
+ - `limit`: Optional limit on number of results
321
+
322
+ **Returns:**
323
+
324
+ - List of matching documents
325
+
326
+ #### `await client.update(collection: str, id: str, updates: dict) -> dict`
327
+
328
+ Update a document.
329
+
330
+ **Parameters:**
331
+
332
+ - `collection`: The collection name
333
+ - `id`: The document ID
334
+ - `updates`: Dictionary of fields to update
335
+
336
+ **Returns:**
337
+
338
+ - The updated document
339
+
340
+ #### `await client.delete(collection: str, id: str) -> None`
341
+
342
+ Delete a document.
343
+
344
+ **Parameters:**
345
+
346
+ - `collection`: The collection name
347
+ - `id`: The document ID
348
+
349
+ #### `await client.list_collections() -> List[str]`
350
+
351
+ List all collections.
352
+
353
+ **Returns:**
354
+
355
+ - List of collection names
356
+
357
+ #### `await client.delete_collection(collection: str) -> None`
358
+
359
+ Delete a collection.
360
+
361
+ **Parameters:**
362
+
363
+ - `collection`: The collection name to delete
364
+
365
+ #### `await client.search(collection: str, query: dict) -> dict`
366
+
367
+ Perform full-text search on a collection.
368
+
369
+ **Parameters:**
370
+
371
+ - `collection`: The collection name
372
+ - `query`: Search query dictionary with fields like `query`, `fields`,
373
+ `weights`, `min_score`, `limit`
374
+
375
+ **Returns:**
376
+
377
+ - Search results with scores and matched records
378
+
379
+ #### `await client.create_collection(collection: str, schema: dict) -> None`
380
+
381
+ Create a collection with a schema.
382
+
383
+ **Parameters:**
384
+
385
+ - `collection`: The collection name
386
+ - `schema`: Schema definition dictionary
387
+
388
+ #### `await client.get_schema(collection: str) -> dict`
389
+
390
+ Get the schema for a collection.
391
+
392
+ **Parameters:**
393
+
394
+ - `collection`: The collection name
395
+
396
+ **Returns:**
397
+
398
+ - Schema definition dictionary
399
+
400
+ #### `await client.get_collection(collection: str) -> dict`
401
+
402
+ Get collection metadata including schema.
403
+
404
+ **Parameters:**
405
+
406
+ - `collection`: The collection name
407
+
408
+ **Returns:**
409
+
410
+ - Collection metadata dictionary
411
+
412
+ ## Examples
413
+
414
+ See the
415
+ [examples directory](https://github.com/ekoDB/ekodb/tree/main/examples/python)
416
+ for complete working examples:
417
+
418
+ - `client_simple_crud.py` - Basic CRUD operations
419
+ - `client_query_builder.py` - Complex queries with QueryBuilder
420
+ - `client_search.py` - Full-text search operations
421
+ - `client_schema.py` - Schema management
422
+ - `client_joins.py` - Join operations
423
+ - `client_batch_operations.py` - Batch operations
424
+ - `client_kv_operations.py` - Key-value operations
425
+ - And more...
426
+
427
+ ## Development
428
+
429
+ ### Building
430
+
431
+ ```bash
432
+ # Install maturin
433
+ pip install maturin
434
+
435
+ # Build and install in development mode
436
+ maturin develop
437
+
438
+ # Build release wheel
439
+ maturin build --release
440
+ ```
441
+
442
+ ### Testing
443
+
444
+ ```bash
445
+ # Run Python tests
446
+ pytest
447
+
448
+ # Run with coverage
449
+ pytest --cov=ekodb
450
+ ```
451
+
452
+ ## License
453
+
454
+ MIT OR Apache-2.0
455
+
456
+ ## Links
457
+
458
+ - [GitHub](https://github.com/ekoDB/ekodb)
459
+ - [Documentation](https://github.com/ekoDB/ekodb/tree/main/documentation)
460
+ - [Examples](https://github.com/ekoDB/ekodb/tree/main/examples/python)
461
+