lumera 0.5.2__tar.gz → 0.5.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lumera
3
- Version: 0.5.2
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
@@ -1,10 +1,10 @@
1
1
  """
2
- Record operations for Lumera collections.
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
- Available functions:
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lumera
3
- Version: 0.5.2
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lumera"
3
- version = "0.5.2"
3
+ version = "0.5.3"
4
4
  description = "SDK for building on Lumera platform"
5
5
  requires-python = ">=3.11"
6
6
  dependencies = [
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes