lumera 0.4.19__py3-none-any.whl → 0.4.22__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/__init__.py CHANGED
@@ -21,6 +21,7 @@ from .sdk import (
21
21
  create_record,
22
22
  delete_collection,
23
23
  delete_record,
24
+ get_agent_run,
24
25
  get_collection,
25
26
  get_record,
26
27
  get_record_by_external_id,
@@ -28,6 +29,7 @@ from .sdk import (
28
29
  list_records,
29
30
  query_sql,
30
31
  replay_hook,
32
+ run_agent,
31
33
  save_to_lumera,
32
34
  update_collection,
33
35
  update_record,
@@ -52,6 +54,7 @@ __all__ = [
52
54
  "replay_hook",
53
55
  "query_sql",
54
56
  "run_agent",
57
+ "get_agent_run",
55
58
  "upload_lumera_file",
56
59
  "create_record",
57
60
  "update_record",
lumera/sdk.py CHANGED
@@ -4,6 +4,9 @@ from typing import Any, Iterable, Mapping, MutableMapping, Sequence, TypedDict
4
4
 
5
5
  import requests as _requests
6
6
 
7
+ from ._utils import (
8
+ API_BASE as _API_BASE,
9
+ )
7
10
  from ._utils import (
8
11
  LEGACY_MOUNT_ROOT as _LEGACY_MOUNT_ROOT,
9
12
  )
@@ -39,6 +42,9 @@ from ._utils import (
39
42
  from ._utils import (
40
43
  get_google_access_token as _get_google_access_token,
41
44
  )
45
+ from ._utils import (
46
+ get_lumera_token as _get_lumera_token,
47
+ )
42
48
  from ._utils import (
43
49
  log_timed as _log_timed,
44
50
  )
@@ -54,6 +60,7 @@ from ._utils import (
54
60
 
55
61
  # Expose shared symbols for backwards-compatible imports.
56
62
  requests = _requests
63
+ API_BASE = _API_BASE
57
64
  MOUNT_ROOT = _MOUNT_ROOT
58
65
  LEGACY_MOUNT_ROOT = _LEGACY_MOUNT_ROOT
59
66
  TOKEN_ENV = _TOKEN_ENV
@@ -61,6 +68,7 @@ LumeraAPIError = _LumeraAPIError
61
68
  RecordNotUniqueError = _RecordNotUniqueError
62
69
  get_access_token = _get_access_token
63
70
  get_google_access_token = _get_google_access_token
71
+ get_lumera_token = _get_lumera_token
64
72
  log_timed = _log_timed
65
73
  open_file = _open_file
66
74
  resolve_path = _resolve_path
@@ -359,8 +367,22 @@ def run_agent(
359
367
  status: str | None = None,
360
368
  error: str | None = None,
361
369
  provenance: Mapping[str, Any] | None = None,
370
+ external_id: str | None = None,
371
+ metadata: Mapping[str, Any] | None = None,
362
372
  ) -> dict[str, Any]:
363
- """Create an agent run and optionally upload files for file inputs."""
373
+ """Create an agent run and optionally upload files for file inputs.
374
+
375
+ Args:
376
+ agent_id: The automation/agent to run. Required.
377
+ inputs: Inputs payload (dict or JSON string). File refs are resolved automatically.
378
+ files: Mapping of input key -> path(s) to upload before run creation.
379
+ status: Optional initial status (defaults to ``queued``).
380
+ error: Optional error string to store alongside the initial status.
381
+ provenance: Custom provenance payload; falls back to environment-derived provenance.
382
+ external_id: Stable idempotency key. If provided, repeated calls with the same value
383
+ will return the existing run (server-side idempotency).
384
+ metadata: Arbitrary JSON metadata to persist with the run (e.g., callback_url).
385
+ """
364
386
 
365
387
  agent_id = agent_id.strip()
366
388
  if not agent_id:
@@ -390,6 +412,10 @@ def run_agent(
390
412
  payload["id"] = run_id
391
413
  if error is not None:
392
414
  payload["error"] = error
415
+ if external_id:
416
+ payload["external_id"] = external_id.strip()
417
+ if metadata is not None:
418
+ payload["metadata"] = _ensure_mapping(metadata, name="metadata")
393
419
  payload["lm_provenance"] = _ensure_mapping(
394
420
  provenance, name="provenance"
395
421
  ) or _default_provenance(agent_id, run_id)
@@ -400,6 +426,90 @@ def run_agent(
400
426
  return run
401
427
 
402
428
 
429
+ def get_agent_run(
430
+ agent_id: str | None = None,
431
+ *,
432
+ run_id: str | None = None,
433
+ external_id: str | None = None,
434
+ ) -> dict[str, Any]:
435
+ """Fetch an agent run by id or by agent_id + external_id idempotency key.
436
+
437
+ Args:
438
+ agent_id: Agent id for external_id lookup. Required when ``run_id`` is not provided.
439
+ run_id: Optional run id. When provided, this takes precedence over external_id lookup.
440
+ external_id: Optional idempotency key to look up the latest run for the agent.
441
+
442
+ Raises:
443
+ ValueError: If required identifiers are missing.
444
+ LumeraAPIError: If no matching run is found.
445
+ """
446
+
447
+ if run_id:
448
+ return _api_request("GET", f"agent-runs/{run_id}")
449
+
450
+ agent_id = agent_id.strip() if isinstance(agent_id, str) else ""
451
+ external_id = external_id.strip() if isinstance(external_id, str) else ""
452
+ if not agent_id:
453
+ raise ValueError("agent_id is required when run_id is not provided")
454
+ if not external_id:
455
+ raise ValueError("external_id is required when run_id is not provided")
456
+
457
+ resp = _api_request(
458
+ "GET",
459
+ "agent-runs",
460
+ params={"agent_id": agent_id, "external_id": external_id, "limit": 1},
461
+ )
462
+ runs = resp.get("agent_runs") if isinstance(resp, dict) else None
463
+ if runs and isinstance(runs, list) and runs and isinstance(runs[0], dict):
464
+ return runs[0]
465
+
466
+ url = _api_url("agent-runs")
467
+ raise _LumeraAPIError(404, "agent run not found", url=url, payload=None)
468
+
469
+
470
+ def update_agent_run(
471
+ run_id: str,
472
+ *,
473
+ result: Mapping[str, Any] | None = None,
474
+ status: str | None = None,
475
+ error: str | None = None,
476
+ metadata: Mapping[str, Any] | None = None,
477
+ ) -> dict[str, Any]:
478
+ """Update an agent run with result, status, or other fields.
479
+
480
+ Args:
481
+ run_id: The run id to update. Required.
482
+ result: Optional result payload to store (max 20KB).
483
+ status: Optional status update.
484
+ error: Optional error string.
485
+ metadata: Optional metadata update.
486
+
487
+ Returns:
488
+ The updated agent run record.
489
+ """
490
+ run_id = run_id.strip() if isinstance(run_id, str) else ""
491
+ if not run_id:
492
+ raise ValueError("run_id is required")
493
+
494
+ payload: dict[str, Any] = {}
495
+ if result is not None:
496
+ payload["result"] = _ensure_mapping(result, name="result")
497
+ if status is not None:
498
+ payload["status"] = status.strip()
499
+ if error is not None:
500
+ payload["error"] = error
501
+ if metadata is not None:
502
+ payload["metadata"] = _ensure_mapping(metadata, name="metadata")
503
+
504
+ if not payload:
505
+ raise ValueError("at least one field to update is required")
506
+
507
+ response = _api_request("PATCH", f"agent-runs/{run_id}", json_body=payload)
508
+ if not isinstance(response, dict):
509
+ raise RuntimeError("unexpected response payload")
510
+ return response
511
+
512
+
403
513
  def create_record(
404
514
  collection_id_or_name: str,
405
515
  payload: Mapping[str, Any] | None = None,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lumera
3
- Version: 0.4.19
3
+ Version: 0.4.22
4
4
  Summary: SDK for building on Lumera platform
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: requests
@@ -0,0 +1,8 @@
1
+ lumera/__init__.py,sha256=p8lX2fW4iFo3quxQCtRs8Gm3WxNmjEY8wLOqLAYWwXI,1467
2
+ lumera/_utils.py,sha256=QyAaphxXGEK8XNPO0ghKLgTOYhAxcF_j3W0T8StzjxA,23610
3
+ lumera/google.py,sha256=3IVNL1HaOtsTmunl0alnGFuUAkzQQRyCEA3CKjlPqO0,10183
4
+ lumera/sdk.py,sha256=oW3e8X-1kpDE4lm9uFyRDiF9mBM-0XK-9aB7pm2XgOE,25677
5
+ lumera-0.4.22.dist-info/METADATA,sha256=1I7AeCvgTT2i50zU9kguHMuAb4ihA1XZ4SV9Fl0tksw,1576
6
+ lumera-0.4.22.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
+ lumera-0.4.22.dist-info/top_level.txt,sha256=HgfK4XQkpMTnM2E5iWM4kB711FnYqUY9dglzib3pWlE,7
8
+ lumera-0.4.22.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- lumera/__init__.py,sha256=wiSDU8oEsyLWPx4aKjrOdRuG9xRCU2hx-2tl-0usQCI,1412
2
- lumera/_utils.py,sha256=QyAaphxXGEK8XNPO0ghKLgTOYhAxcF_j3W0T8StzjxA,23610
3
- lumera/google.py,sha256=3IVNL1HaOtsTmunl0alnGFuUAkzQQRyCEA3CKjlPqO0,10183
4
- lumera/sdk.py,sha256=rheDwUjT9Dcy6t7aAbHE8EiIbRe5dJnMGclZViLFMPU,21651
5
- lumera-0.4.19.dist-info/METADATA,sha256=vLezVVjgWKrkHK8LLOVchFAm9fYGq9j4EPEKccwN1V0,1576
6
- lumera-0.4.19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
- lumera-0.4.19.dist-info/top_level.txt,sha256=HgfK4XQkpMTnM2E5iWM4kB711FnYqUY9dglzib3pWlE,7
8
- lumera-0.4.19.dist-info/RECORD,,