lumera 0.5.1__py3-none-any.whl → 0.5.3__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.
- lumera/pb.py +205 -3
- lumera/sdk.py +7 -7
- {lumera-0.5.1.dist-info → lumera-0.5.3.dist-info}/METADATA +2 -2
- {lumera-0.5.1.dist-info → lumera-0.5.3.dist-info}/RECORD +6 -6
- {lumera-0.5.1.dist-info → lumera-0.5.3.dist-info}/WHEEL +0 -0
- {lumera-0.5.1.dist-info → lumera-0.5.3.dist-info}/top_level.txt +0 -0
lumera/pb.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Record operations for Lumera
|
|
2
|
+
Record and collection operations for Lumera.
|
|
3
3
|
|
|
4
4
|
This module provides a clean interface for working with Lumera collections,
|
|
5
5
|
using the `pb.` namespace convention familiar from automation contexts.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Record functions:
|
|
8
8
|
search() - Query records with filters, pagination, sorting
|
|
9
9
|
get() - Get single record by ID
|
|
10
10
|
get_by_external_id() - Get record by external_id field
|
|
@@ -14,6 +14,14 @@ Available functions:
|
|
|
14
14
|
delete() - Delete record
|
|
15
15
|
iter_all() - Iterate all matching records (auto-pagination)
|
|
16
16
|
|
|
17
|
+
Collection functions:
|
|
18
|
+
list_collections() - List all collections
|
|
19
|
+
get_collection() - Get collection by name
|
|
20
|
+
ensure_collection() - Create or update collection (idempotent)
|
|
21
|
+
create_collection() - Create new collection
|
|
22
|
+
update_collection() - Update collection schema
|
|
23
|
+
delete_collection() - Delete collection
|
|
24
|
+
|
|
17
25
|
Filter Syntax:
|
|
18
26
|
Filters can be passed as dict or JSON string to search() and iter_all().
|
|
19
27
|
|
|
@@ -40,9 +48,10 @@ Example:
|
|
|
40
48
|
>>> deposit = pb.get("deposits", "rec_abc123")
|
|
41
49
|
"""
|
|
42
50
|
|
|
43
|
-
from typing import Any, Iterator, Mapping
|
|
51
|
+
from typing import Any, Iterator, Mapping, Sequence
|
|
44
52
|
|
|
45
53
|
__all__ = [
|
|
54
|
+
# Record operations
|
|
46
55
|
"search",
|
|
47
56
|
"get",
|
|
48
57
|
"get_by_external_id",
|
|
@@ -51,24 +60,47 @@ __all__ = [
|
|
|
51
60
|
"upsert",
|
|
52
61
|
"delete",
|
|
53
62
|
"iter_all",
|
|
63
|
+
# Collection operations
|
|
64
|
+
"list_collections",
|
|
65
|
+
"get_collection",
|
|
66
|
+
"ensure_collection",
|
|
67
|
+
"create_collection",
|
|
68
|
+
"update_collection",
|
|
69
|
+
"delete_collection",
|
|
54
70
|
]
|
|
55
71
|
|
|
56
72
|
# Import underlying SDK functions (prefixed with _ to indicate internal use)
|
|
73
|
+
from .exceptions import LumeraAPIError
|
|
74
|
+
from .sdk import (
|
|
75
|
+
create_collection as _create_collection,
|
|
76
|
+
)
|
|
57
77
|
from .sdk import (
|
|
58
78
|
create_record as _create_record,
|
|
59
79
|
)
|
|
80
|
+
from .sdk import (
|
|
81
|
+
delete_collection as _delete_collection,
|
|
82
|
+
)
|
|
60
83
|
from .sdk import (
|
|
61
84
|
delete_record as _delete_record,
|
|
62
85
|
)
|
|
86
|
+
from .sdk import (
|
|
87
|
+
get_collection as _get_collection,
|
|
88
|
+
)
|
|
63
89
|
from .sdk import (
|
|
64
90
|
get_record as _get_record,
|
|
65
91
|
)
|
|
66
92
|
from .sdk import (
|
|
67
93
|
get_record_by_external_id as _get_record_by_external_id,
|
|
68
94
|
)
|
|
95
|
+
from .sdk import (
|
|
96
|
+
list_collections as _list_collections,
|
|
97
|
+
)
|
|
69
98
|
from .sdk import (
|
|
70
99
|
list_records as _list_records,
|
|
71
100
|
)
|
|
101
|
+
from .sdk import (
|
|
102
|
+
update_collection as _update_collection,
|
|
103
|
+
)
|
|
72
104
|
from .sdk import (
|
|
73
105
|
update_record as _update_record,
|
|
74
106
|
)
|
|
@@ -314,3 +346,173 @@ def iter_all(
|
|
|
314
346
|
break
|
|
315
347
|
|
|
316
348
|
page += 1
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
# =============================================================================
|
|
352
|
+
# Collection Management Functions
|
|
353
|
+
# =============================================================================
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def list_collections() -> list[dict[str, Any]]:
|
|
357
|
+
"""List all collections.
|
|
358
|
+
|
|
359
|
+
Returns:
|
|
360
|
+
List of collection objects with id, name, schema, etc.
|
|
361
|
+
|
|
362
|
+
Example:
|
|
363
|
+
>>> collections = pb.list_collections()
|
|
364
|
+
>>> for col in collections:
|
|
365
|
+
... print(col["name"])
|
|
366
|
+
"""
|
|
367
|
+
result = _list_collections()
|
|
368
|
+
return result.get("items", [])
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
def get_collection(name: str) -> dict[str, Any] | None:
|
|
372
|
+
"""Get a collection by name.
|
|
373
|
+
|
|
374
|
+
Args:
|
|
375
|
+
name: Collection name
|
|
376
|
+
|
|
377
|
+
Returns:
|
|
378
|
+
Collection object if found, None if not found
|
|
379
|
+
|
|
380
|
+
Example:
|
|
381
|
+
>>> col = pb.get_collection("deposits")
|
|
382
|
+
>>> if col:
|
|
383
|
+
... print(col["schema"])
|
|
384
|
+
"""
|
|
385
|
+
try:
|
|
386
|
+
return _get_collection(name)
|
|
387
|
+
except LumeraAPIError as e:
|
|
388
|
+
if e.status_code == 404:
|
|
389
|
+
return None
|
|
390
|
+
raise
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def create_collection(
|
|
394
|
+
name: str,
|
|
395
|
+
schema: Sequence[dict[str, Any]],
|
|
396
|
+
*,
|
|
397
|
+
indexes: Sequence[str] | None = None,
|
|
398
|
+
) -> dict[str, Any]:
|
|
399
|
+
"""Create a new collection.
|
|
400
|
+
|
|
401
|
+
Args:
|
|
402
|
+
name: Collection name (must not start with '_')
|
|
403
|
+
schema: List of field definitions. Each field is a dict with:
|
|
404
|
+
- name: Field name (required)
|
|
405
|
+
- type: Field type (required): text, number, bool, date, json,
|
|
406
|
+
relation, select, editor, lumera_file
|
|
407
|
+
- required: Whether field is required (default False)
|
|
408
|
+
- options: Type-specific options (e.g., collectionId for relations)
|
|
409
|
+
indexes: Optional list of index definitions
|
|
410
|
+
|
|
411
|
+
Returns:
|
|
412
|
+
Created collection object
|
|
413
|
+
|
|
414
|
+
Example:
|
|
415
|
+
>>> col = pb.create_collection("deposits", [
|
|
416
|
+
... {"name": "amount", "type": "number", "required": True},
|
|
417
|
+
... {"name": "status", "type": "text"},
|
|
418
|
+
... {"name": "account_id", "type": "relation",
|
|
419
|
+
... "options": {"collectionId": "accounts"}}
|
|
420
|
+
... ])
|
|
421
|
+
"""
|
|
422
|
+
return _create_collection(name, schema=schema, indexes=indexes)
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def update_collection(
|
|
426
|
+
name: str,
|
|
427
|
+
schema: Sequence[dict[str, Any]],
|
|
428
|
+
*,
|
|
429
|
+
indexes: Sequence[str] | None = None,
|
|
430
|
+
) -> dict[str, Any]:
|
|
431
|
+
"""Update a collection's schema.
|
|
432
|
+
|
|
433
|
+
Args:
|
|
434
|
+
name: Collection name
|
|
435
|
+
schema: New schema (replaces existing user fields)
|
|
436
|
+
indexes: Optional new indexes
|
|
437
|
+
|
|
438
|
+
Returns:
|
|
439
|
+
Updated collection object
|
|
440
|
+
|
|
441
|
+
Example:
|
|
442
|
+
>>> col = pb.update_collection("deposits", [
|
|
443
|
+
... {"name": "amount", "type": "number", "required": True},
|
|
444
|
+
... {"name": "status", "type": "text"},
|
|
445
|
+
... {"name": "notes", "type": "text"} # New field
|
|
446
|
+
... ])
|
|
447
|
+
"""
|
|
448
|
+
return _update_collection(name, schema=schema, indexes=indexes)
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def delete_collection(name: str) -> None:
|
|
452
|
+
"""Delete a collection.
|
|
453
|
+
|
|
454
|
+
Args:
|
|
455
|
+
name: Collection name to delete
|
|
456
|
+
|
|
457
|
+
Raises:
|
|
458
|
+
LumeraAPIError: If collection doesn't exist or is protected
|
|
459
|
+
|
|
460
|
+
Example:
|
|
461
|
+
>>> pb.delete_collection("old_deposits")
|
|
462
|
+
"""
|
|
463
|
+
_delete_collection(name)
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
def ensure_collection(
|
|
467
|
+
name: str,
|
|
468
|
+
schema: Sequence[dict[str, Any]],
|
|
469
|
+
*,
|
|
470
|
+
update_schema: bool = False,
|
|
471
|
+
indexes: Sequence[str] | None = None,
|
|
472
|
+
) -> dict[str, Any]:
|
|
473
|
+
"""Ensure a collection exists with the given schema (idempotent).
|
|
474
|
+
|
|
475
|
+
This is the recommended way to set up collections in automation scripts.
|
|
476
|
+
Safe to call multiple times - will not fail if collection already exists.
|
|
477
|
+
|
|
478
|
+
Args:
|
|
479
|
+
name: Collection name
|
|
480
|
+
schema: List of field definitions
|
|
481
|
+
update_schema: If True, update existing collection's schema.
|
|
482
|
+
If False (default), leave existing collection unchanged.
|
|
483
|
+
indexes: Optional list of index definitions
|
|
484
|
+
|
|
485
|
+
Returns:
|
|
486
|
+
Collection object (created, updated, or existing)
|
|
487
|
+
|
|
488
|
+
Behavior:
|
|
489
|
+
- Collection doesn't exist → create it
|
|
490
|
+
- Collection exists, update_schema=False → return existing (no-op)
|
|
491
|
+
- Collection exists, update_schema=True → update schema
|
|
492
|
+
|
|
493
|
+
Example:
|
|
494
|
+
>>> # Safe to run multiple times
|
|
495
|
+
>>> col = pb.ensure_collection("deposits", [
|
|
496
|
+
... {"name": "amount", "type": "number", "required": True},
|
|
497
|
+
... {"name": "status", "type": "text"},
|
|
498
|
+
... ])
|
|
499
|
+
>>>
|
|
500
|
+
>>> # Update schema if collection exists
|
|
501
|
+
>>> col = pb.ensure_collection("deposits", [
|
|
502
|
+
... {"name": "amount", "type": "number", "required": True},
|
|
503
|
+
... {"name": "status", "type": "text"},
|
|
504
|
+
... {"name": "notes", "type": "text"}, # Add new field
|
|
505
|
+
... ], update_schema=True)
|
|
506
|
+
"""
|
|
507
|
+
existing = get_collection(name)
|
|
508
|
+
|
|
509
|
+
if existing is None:
|
|
510
|
+
# Collection doesn't exist, create it
|
|
511
|
+
return create_collection(name, schema, indexes=indexes)
|
|
512
|
+
|
|
513
|
+
if update_schema:
|
|
514
|
+
# Update existing collection's schema
|
|
515
|
+
return update_collection(name, schema, indexes=indexes)
|
|
516
|
+
|
|
517
|
+
# Collection exists and update_schema=False, return as-is
|
|
518
|
+
return existing
|
lumera/sdk.py
CHANGED
|
@@ -268,15 +268,15 @@ def list_records(
|
|
|
268
268
|
limit: Alternative to ``per_page`` for cursor-style queries.
|
|
269
269
|
offset: Starting offset for cursor-style queries.
|
|
270
270
|
sort: Optional sort expression (e.g. ``"-created"``).
|
|
271
|
-
filter:
|
|
272
|
-
|
|
273
|
-
sequence. Structured filters mirror the Page Builder helpers, e.g.:
|
|
271
|
+
filter: Filter as dict (JSON object). String filters are NOT supported.
|
|
272
|
+
Use dict syntax with optional comparison operators:
|
|
274
273
|
|
|
275
|
-
*
|
|
276
|
-
*
|
|
274
|
+
* Simple equality: ``{"status": "pending"}``
|
|
275
|
+
* Comparison: ``{"amount": {"gt": 1000}}`` (gt, gte, lt, lte, eq)
|
|
276
|
+
* OR logic: ``{"or": [{"status": "a"}, {"status": "b"}]}``
|
|
277
|
+
* AND (implicit): ``{"status": "active", "amount": {"gt": 100}}``
|
|
277
278
|
|
|
278
|
-
The SDK JSON-encodes
|
|
279
|
-
tenant-aware expressions automatically.
|
|
279
|
+
The SDK JSON-encodes the filter for the API.
|
|
280
280
|
expand: Optional comma-separated list of relation fields to expand.
|
|
281
281
|
Expanded relations are included inline in the record response.
|
|
282
282
|
Example: ``"user_id,company_id"`` or ``"line_items_via_deposit_id"``
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lumera
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.3
|
|
4
4
|
Summary: SDK for building on Lumera platform
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Requires-Dist: requests
|
|
@@ -26,7 +26,7 @@ Requires-Dist: openai-agents<1.0.0,>=0.6.5; extra == "full"
|
|
|
26
26
|
Requires-Dist: openpyxl==3.1.5; extra == "full"
|
|
27
27
|
Requires-Dist: pandas==2.3.0; extra == "full"
|
|
28
28
|
Requires-Dist: pdfplumber; extra == "full"
|
|
29
|
-
Requires-Dist: pydantic
|
|
29
|
+
Requires-Dist: pydantic<3.0.0,>=2.12.3; extra == "full"
|
|
30
30
|
Requires-Dist: PyGithub==2.6.1; extra == "full"
|
|
31
31
|
Requires-Dist: python-dotenv==1.1.0; extra == "full"
|
|
32
32
|
Requires-Dist: pyzmq; extra == "full"
|
|
@@ -4,10 +4,10 @@ lumera/exceptions.py,sha256=bNsx4iYaroAAGsYxErfELC2B5ZJ3w5lVa1kKdIx5s9g,2173
|
|
|
4
4
|
lumera/google.py,sha256=3IVNL1HaOtsTmunl0alnGFuUAkzQQRyCEA3CKjlPqO0,10183
|
|
5
5
|
lumera/llm.py,sha256=pUTZK7t3GTK0vfxMI1PJgJwNendyuiJc5MB1pUj2vxE,14412
|
|
6
6
|
lumera/locks.py,sha256=8l_qxb8nrxge7YJ-ApUTJ5MeYpIdxDeEa94Eim9O-YM,6806
|
|
7
|
-
lumera/pb.py,sha256=
|
|
8
|
-
lumera/sdk.py,sha256=
|
|
7
|
+
lumera/pb.py,sha256=E8TRw7mQ9i0vpmC46azwT7O7EP2w7w4O5ZgcrQyInyI,14915
|
|
8
|
+
lumera/sdk.py,sha256=6Vw0f5MX-yjmy7KBZzEYNdjtXk2P4Oxibpa_UpcM7bs,26859
|
|
9
9
|
lumera/storage.py,sha256=kQQJYVRnxcpDZQ_gB2iZy6anb3hyZN7b8a_oNuE2yYE,8191
|
|
10
|
-
lumera-0.5.
|
|
11
|
-
lumera-0.5.
|
|
12
|
-
lumera-0.5.
|
|
13
|
-
lumera-0.5.
|
|
10
|
+
lumera-0.5.3.dist-info/METADATA,sha256=6aLRahUomaWUUSfqSzj2_8fwTSLt08nW3BrERVVnf-Q,1611
|
|
11
|
+
lumera-0.5.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
+
lumera-0.5.3.dist-info/top_level.txt,sha256=HgfK4XQkpMTnM2E5iWM4kB711FnYqUY9dglzib3pWlE,7
|
|
13
|
+
lumera-0.5.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|