iii-sdk 0.19.7.dev1__tar.gz → 0.20.0.dev1__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 (75) hide show
  1. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/PKG-INFO +2 -2
  2. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/pyproject.toml +3 -3
  3. iii_sdk-0.20.0.dev1/src/iii/__init__.py +44 -0
  4. iii_sdk-0.20.0.dev1/src/iii/channel.py +7 -0
  5. iii_sdk-0.20.0.dev1/src/iii/engine.py +6 -0
  6. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/src/iii/errors.py +6 -6
  7. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/src/iii/format_utils.py +2 -2
  8. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/src/iii/helpers.py +2 -2
  9. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/src/iii/iii.py +36 -36
  10. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/src/iii/iii_constants.py +25 -4
  11. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/src/iii/iii_types.py +3 -231
  12. iii_sdk-0.20.0.dev1/src/iii/internal.py +5 -0
  13. iii_sdk-0.20.0.dev1/src/iii/protocol.py +25 -0
  14. iii_sdk-0.20.0.dev1/src/iii/runtime.py +6 -0
  15. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/src/iii/state.py +2 -9
  16. iii_sdk-0.20.0.dev1/src/iii/stream.py +54 -0
  17. iii_sdk-0.20.0.dev1/src/iii/trigger.py +6 -0
  18. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/src/iii/triggers.py +3 -3
  19. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/src/iii/types.py +6 -26
  20. iii_sdk-0.20.0.dev1/src/iii/utils.py +25 -0
  21. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_api_triggers.py +9 -9
  22. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_baggage_span_processor.py +1 -1
  23. iii_sdk-0.20.0.dev1/tests/test_channel_submodule.py +14 -0
  24. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_context_propagation.py +1 -1
  25. iii_sdk-0.20.0.dev1/tests/test_engine_constants.py +20 -0
  26. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_errors.py +35 -20
  27. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_helpers.py +3 -3
  28. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_hold_process.py +6 -6
  29. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_http_external_functions_integration.py +4 -4
  30. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_iii_registration_dedup.py +7 -7
  31. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_init_api.py +3 -3
  32. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_logger_function_ids.py +1 -1
  33. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_logger_otel.py +8 -8
  34. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_payload.py +1 -1
  35. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_rbac_workers.py +11 -10
  36. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_register_function_args.py +7 -8
  37. iii_sdk-0.20.0.dev1/tests/test_runtime_submodule.py +15 -0
  38. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_span_ops.py +1 -1
  39. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_stream_models.py +1 -1
  40. iii_sdk-0.20.0.dev1/tests/test_stream_types.py +15 -0
  41. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_streams.py +2 -2
  42. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_sync_api.py +4 -3
  43. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_telemetry.py +6 -6
  44. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_telemetry_exporters.py +2 -2
  45. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_telemetry_types.py +1 -1
  46. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_trace_helpers.py +1 -1
  47. iii_sdk-0.20.0.dev1/tests/test_trigger_submodule.py +31 -0
  48. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_trigger_type_lifecycle.py +2 -1
  49. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/uv.lock +8 -6
  50. iii_sdk-0.19.7.dev1/src/iii/__init__.py +0 -120
  51. iii_sdk-0.19.7.dev1/src/iii/stream.py +0 -333
  52. iii_sdk-0.19.7.dev1/src/iii/utils.py +0 -61
  53. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/.gitignore +0 -0
  54. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/README.md +0 -0
  55. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/src/iii/channels.py +0 -0
  56. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/src/iii/otel_worker_gauges.py +0 -0
  57. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/src/iii/worker_metrics.py +0 -0
  58. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/conftest.py +0 -0
  59. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_async_api.py +0 -0
  60. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_bridge.py +0 -0
  61. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_channel_close_delay.py +0 -0
  62. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_data_channels.py +0 -0
  63. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_format_utils.py +0 -0
  64. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_healthcheck.py +0 -0
  65. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_invocation_exception.py +0 -0
  66. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_middleware.py +0 -0
  67. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_pubsub.py +0 -0
  68. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_queue_integration.py +0 -0
  69. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_state.py +0 -0
  70. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_streams_runtime_annotations.py +0 -0
  71. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_trigger_metadata.py +0 -0
  72. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_trigger_registration_error.py +0 -0
  73. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_utils.py +0 -0
  74. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_worker_metadata.py +0 -0
  75. {iii_sdk-0.19.7.dev1 → iii_sdk-0.20.0.dev1}/tests/test_worker_metrics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iii-sdk
3
- Version: 0.19.7.dev1
3
+ Version: 0.20.0.dev1
4
4
  Summary: III SDK for Python
5
5
  Project-URL: Homepage, https://github.com/iii-hq/iii
6
6
  Project-URL: Repository, https://github.com/iii-hq/iii
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
16
  Requires-Python: >=3.10
17
- Requires-Dist: iii-observability==0.19.7.dev1
17
+ Requires-Dist: iii-helpers==0.20.0.dev1
18
18
  Requires-Dist: opentelemetry-api>=1.25
19
19
  Requires-Dist: pydantic>=2.0
20
20
  Requires-Dist: websockets>=12.0
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "iii-sdk"
7
- version = "0.19.7.dev1"
7
+ version = "0.20.0.dev1"
8
8
  description = "III SDK for Python"
9
9
  authors = [{ name = "III" }]
10
10
  license = { text = "Apache-2.0" }
@@ -23,7 +23,7 @@ dependencies = [
23
23
  "websockets>=12.0",
24
24
  "pydantic>=2.0",
25
25
  "opentelemetry-api>=1.25",
26
- "iii-observability==0.19.7.dev1",
26
+ "iii-helpers==0.20.0.dev1",
27
27
  ]
28
28
 
29
29
  [project.urls]
@@ -31,7 +31,7 @@ Homepage = "https://github.com/iii-hq/iii"
31
31
  Repository = "https://github.com/iii-hq/iii"
32
32
 
33
33
  [tool.uv.sources]
34
- iii-observability = { path = "../observability", editable = true }
34
+ iii-helpers = { path = "../helpers", editable = true }
35
35
 
36
36
  [project.optional-dependencies]
37
37
  dev = [
@@ -0,0 +1,44 @@
1
+ """III SDK for Python."""
2
+
3
+ from iii_helpers.queue import EnqueueResult
4
+
5
+ from .errors import InvocationError
6
+ from .iii import TriggerAction, register_worker
7
+ from .iii_constants import (
8
+ InitOptions,
9
+ TelemetryOptions,
10
+ )
11
+ from .iii_types import (
12
+ MiddlewareFunctionInput,
13
+ TriggerActionEnqueue,
14
+ TriggerActionVoid,
15
+ )
16
+ from .stream import IStream
17
+ from .types import (
18
+ IIIClient,
19
+ StreamRequest,
20
+ StreamResponse,
21
+ )
22
+
23
+ __all__ = [
24
+ # Errors
25
+ "InvocationError",
26
+ # Core
27
+ "InitOptions",
28
+ "register_worker",
29
+ "TelemetryOptions",
30
+ "TriggerAction",
31
+ # RBAC types
32
+ "MiddlewareFunctionInput",
33
+ # Message types
34
+ "TriggerActionEnqueue",
35
+ "TriggerActionVoid",
36
+ # Queue
37
+ "EnqueueResult",
38
+ # Types
39
+ "IIIClient",
40
+ "StreamRequest",
41
+ "StreamResponse",
42
+ # Stream
43
+ "IStream",
44
+ ]
@@ -0,0 +1,7 @@
1
+ """Public channel types."""
2
+
3
+ from .channels import ChannelReader, ChannelWriter
4
+ from .iii_types import StreamChannelRef
5
+ from .types import Channel
6
+
7
+ __all__ = ["Channel", "ChannelReader", "ChannelWriter", "StreamChannelRef"]
@@ -0,0 +1,6 @@
1
+ """Engine constants and handler types."""
2
+
3
+ from .iii_constants import EngineFunctions, EngineTriggers
4
+ from .types import RemoteFunctionHandler
5
+
6
+ __all__ = ["EngineFunctions", "EngineTriggers", "RemoteFunctionHandler"]
@@ -3,13 +3,13 @@ from __future__ import annotations
3
3
  from typing import Any
4
4
 
5
5
 
6
- class IIIInvocationError(Exception):
6
+ class InvocationError(Exception):
7
7
  """Raised when an invocation dispatched by the SDK fails.
8
8
 
9
9
  Inspect ``err.code`` to react to a specific category (e.g.
10
10
  ``'FORBIDDEN'`` for RBAC denials, ``'TIMEOUT'`` for timeouts). Catch
11
11
  this class to handle every rejection. ``except Exception`` continues to
12
- work because ``IIIInvocationError`` inherits from ``Exception``.
12
+ work because ``InvocationError`` inherits from ``Exception``.
13
13
 
14
14
  Attributes are read-only after construction. ``stacktrace`` is the
15
15
  engine-side trace when the remote handler raised; it may include
@@ -38,8 +38,8 @@ def _wrap_wire_error(
38
38
  *,
39
39
  function_id: str | None,
40
40
  invocation_id: str | None,
41
- ) -> IIIInvocationError:
42
- """Convert a wire ``ErrorBody``-shaped dict into an ``IIIInvocationError``.
41
+ ) -> InvocationError:
42
+ """Convert a wire ``ErrorBody``-shaped dict into an ``InvocationError``.
43
43
 
44
44
  The ``code`` field distinguishes categories (e.g. ``'FORBIDDEN'``,
45
45
  ``'TIMEOUT'``). Malformed shapes (non-dict, missing fields, non-string
@@ -56,7 +56,7 @@ def _wrap_wire_error(
56
56
  raw_stacktrace = error.get("stacktrace")
57
57
  stacktrace = raw_stacktrace if isinstance(raw_stacktrace, str) else None
58
58
 
59
- return IIIInvocationError(
59
+ return InvocationError(
60
60
  code=code,
61
61
  message=message,
62
62
  function_id=function_id,
@@ -64,7 +64,7 @@ def _wrap_wire_error(
64
64
  invocation_id=invocation_id,
65
65
  )
66
66
 
67
- return IIIInvocationError(
67
+ return InvocationError(
68
68
  code="UNKNOWN",
69
69
  message=str(error),
70
70
  function_id=function_id,
@@ -44,7 +44,7 @@ def _to_json_schema(annotation: Any) -> dict[str, Any] | None:
44
44
  if annotation is inspect.Parameter.empty or annotation is Any:
45
45
  return None
46
46
 
47
- # Handle Optional[X] produce {"type": ["<inner>", "null"]}
47
+ # Handle Optional[X], produce {"type": ["<inner>", "null"]}
48
48
  is_opt, inner = _is_optional(annotation)
49
49
  if is_opt:
50
50
  inner_schema = _to_json_schema(inner)
@@ -82,7 +82,7 @@ def _to_json_schema(annotation: Any) -> dict[str, Any] | None:
82
82
  schema_dict["additionalProperties"] = value_schema
83
83
  return schema_dict
84
84
 
85
- # Handle Pydantic BaseModel use its built-in JSON Schema generation
85
+ # Handle Pydantic BaseModel, use its built-in JSON Schema generation
86
86
  if _is_pydantic_model(annotation):
87
87
  model_schema: dict[str, Any] = annotation.model_json_schema()
88
88
  return model_schema
@@ -34,7 +34,7 @@ class _IIIWithHelperShims(IIIClient, Protocol):
34
34
 
35
35
  The free functions below delegate to these private methods on the
36
36
  concrete :class:`III` instance. Defining the Protocol here mirrors the
37
- Node SDK's ``IIIWithHelperShims`` intersection type callers see the
37
+ Node SDK's ``IIIWithHelperShims`` intersection type, callers see the
38
38
  public :class:`IIIClient` Protocol; helpers see the shims internally.
39
39
  """
40
40
 
@@ -46,7 +46,7 @@ class _IIIWithHelperShims(IIIClient, Protocol):
46
46
 
47
47
  def _helpers_create_stream(
48
48
  self, stream_name: str, stream: IStream[Any]
49
- ) -> None: ... # noqa: D401internal shim, generic erased at the boundary
49
+ ) -> None: ... # noqa: D401 (internal shim, generic erased at the boundary)
50
50
 
51
51
 
52
52
  def create_channel(iii: IIIClient, buffer_size: int | None = None) -> Channel:
@@ -14,11 +14,19 @@ from importlib.metadata import version
14
14
  from typing import Any, Awaitable, Callable, Coroutine, TypeVar, cast
15
15
 
16
16
  import websockets
17
- from iii_observability import OtelConfig
17
+ from iii_helpers.http import HttpInvocationConfig
18
+ from iii_helpers.observability import OtelConfig
19
+ from iii_helpers.stream import (
20
+ StreamDeleteInput,
21
+ StreamGetInput,
22
+ StreamListGroupsInput,
23
+ StreamListInput,
24
+ StreamSetInput,
25
+ )
18
26
  from websockets.asyncio.client import ClientConnection
19
27
 
20
28
  from .channels import ChannelReader, ChannelWriter
21
- from .errors import IIIInvocationError, _wrap_wire_error
29
+ from .errors import InvocationError, _wrap_wire_error
22
30
  from .format_utils import extract_request_format, extract_response_format
23
31
  from .iii_constants import (
24
32
  DEFAULT_RECONNECTION_CONFIG,
@@ -28,7 +36,6 @@ from .iii_constants import (
28
36
  InitOptions,
29
37
  )
30
38
  from .iii_types import (
31
- HttpInvocationConfig,
32
39
  InvocationResultMessage,
33
40
  InvokeFunctionMessage,
34
41
  MessageType,
@@ -47,14 +54,7 @@ from .iii_types import (
47
54
  UnregisterTriggerMessage,
48
55
  UnregisterTriggerTypeMessage,
49
56
  )
50
- from .stream import (
51
- IStream,
52
- StreamDeleteInput,
53
- StreamGetInput,
54
- StreamListGroupsInput,
55
- StreamListInput,
56
- StreamSetInput,
57
- )
57
+ from .stream import IStream
58
58
  from .triggers import Trigger, TriggerConfig, TriggerHandler, TriggerTypeRef
59
59
  from .types import Channel, RemoteFunctionData, RemoteTriggerTypeData, is_channel_ref
60
60
 
@@ -83,7 +83,7 @@ def _detect_project_name(cwd: str | None = None) -> str | None:
83
83
  when both signals are unavailable (e.g. cwd is the filesystem root, or
84
84
  the Python runtime has no TOML parser and no readable cwd basename).
85
85
 
86
- No directory walking only inspects ``cwd`` itself, so the SDK never
86
+ No directory walking, only inspects ``cwd`` itself, so the SDK never
87
87
  reads files outside the user's explicit working directory.
88
88
  """
89
89
  try:
@@ -142,7 +142,7 @@ class III:
142
142
 
143
143
  Examples:
144
144
  >>> from iii import register_worker, InitOptions
145
- >>> iii = register_worker('ws://localhost:49134', InitOptions(worker_name='my-worker'))
145
+ >>> worker = register_worker('ws://localhost:49134', InitOptions(worker_name='my-worker'))
146
146
  """
147
147
 
148
148
  def __init__(self, address: str, options: InitOptions | None = None) -> None:
@@ -207,9 +207,9 @@ class III:
207
207
  instance must not be reused.
208
208
 
209
209
  Examples:
210
- >>> iii = register_worker('ws://localhost:49134')
210
+ >>> worker = register_worker('ws://localhost:49134')
211
211
  >>> # ... do work ...
212
- >>> iii.shutdown()
212
+ >>> worker.shutdown()
213
213
  """
214
214
  self._run_on_loop(self.shutdown_async())
215
215
  self._loop.call_soon_threadsafe(self._loop.stop)
@@ -224,7 +224,7 @@ class III:
224
224
  from an async context.
225
225
  """
226
226
  self._running = True
227
- from iii_observability.telemetry import attach_event_loop, init_otel
227
+ from iii_helpers.observability.telemetry import attach_event_loop, init_otel
228
228
 
229
229
  loop = asyncio.get_running_loop()
230
230
  otel_cfg: OtelConfig | None = None
@@ -247,9 +247,9 @@ class III:
247
247
  instance must not be reused.
248
248
 
249
249
  Examples:
250
- >>> iii = register_worker('ws://localhost:49134')
250
+ >>> worker = register_worker('ws://localhost:49134')
251
251
  >>> # ... do work ...
252
- >>> await iii.shutdown_async()
252
+ >>> await worker.shutdown_async()
253
253
  """
254
254
  self._running = False
255
255
 
@@ -265,7 +265,7 @@ class III:
265
265
  for invocation_id, pending in list(self._pending.items()):
266
266
  if not pending.future.done():
267
267
  pending.future.set_exception(
268
- IIIInvocationError(
268
+ InvocationError(
269
269
  code="SHUTDOWN",
270
270
  message="iii is shutting down",
271
271
  function_id=pending.function_id,
@@ -280,7 +280,7 @@ class III:
280
280
 
281
281
  self._set_connection_state("disconnected")
282
282
 
283
- from iii_observability.telemetry import shutdown_otel_async
283
+ from iii_helpers.observability.telemetry import shutdown_otel_async
284
284
 
285
285
  await shutdown_otel_async()
286
286
 
@@ -502,7 +502,7 @@ class III:
502
502
  tracer = trace.get_tracer("iii-python-sdk")
503
503
  import os
504
504
 
505
- from iii_observability import redact_and_truncate, resolve_max_bytes_from_env
505
+ from iii_helpers.observability import redact_and_truncate, resolve_max_bytes_from_env
506
506
 
507
507
  trace_payloads = os.environ.get("III_DISABLE_TRACE_PAYLOADS", "").lower() not in (
508
508
  "1",
@@ -800,7 +800,7 @@ class III:
800
800
  ``register_function`` methods.
801
801
 
802
802
  Examples:
803
- >>> webhook = iii.register_trigger_type(
803
+ >>> webhook = worker.register_trigger_type(
804
804
  ... RegisterTriggerTypeInput(
805
805
  ... id="webhook",
806
806
  ... description="Webhook trigger",
@@ -853,8 +853,8 @@ class III:
853
853
  trigger_type: A ``RegisterTriggerTypeInput`` or dict with ``id`` and optional ``description``.
854
854
 
855
855
  Examples:
856
- >>> iii.unregister_trigger_type({"id": "webhook", "description": "Webhook trigger"})
857
- >>> iii.unregister_trigger_type(RegisterTriggerTypeInput(id="webhook", description="Webhook trigger"))
856
+ >>> worker.unregister_trigger_type({"id": "webhook", "description": "Webhook trigger"})
857
+ >>> worker.unregister_trigger_type(RegisterTriggerTypeInput(id="webhook", description="Webhook trigger"))
858
858
  """
859
859
  if isinstance(trigger_type, dict):
860
860
  type_id = trigger_type["id"]
@@ -878,12 +878,12 @@ class III:
878
878
  the engine as part of the registration message.
879
879
 
880
880
  Examples:
881
- >>> trigger = iii.register_trigger({
881
+ >>> trigger = worker.register_trigger({
882
882
  ... 'type': 'http',
883
883
  ... 'function_id': 'greet',
884
884
  ... 'config': {'api_path': '/greet', 'http_method': 'GET'}
885
885
  ... })
886
- >>> trigger = iii.register_trigger(RegisterTriggerInput(
886
+ >>> trigger = worker.register_trigger(RegisterTriggerInput(
887
887
  ... type="http", function_id="greet",
888
888
  ... config={'api_path': '/greet', 'http_method': 'GET'}
889
889
  ... ))
@@ -967,7 +967,7 @@ class III:
967
967
  Examples:
968
968
  >>> def greet(data):
969
969
  ... return {'message': f"Hello, {data['name']}!"}
970
- >>> fn = iii.register_function("greet", greet, description="Greets a user")
970
+ >>> fn = worker.register_function("greet", greet, description="Greets a user")
971
971
  >>> fn.unregister()
972
972
 
973
973
  >>> from pydantic import BaseModel
@@ -977,7 +977,7 @@ class III:
977
977
  ... message: str
978
978
  >>> async def greet(data: GreetInput) -> GreetOutput:
979
979
  ... return GreetOutput(message=f"Hello, {data.name}!")
980
- >>> fn = iii.register_function("greet", greet, description="Greets a user")
980
+ >>> fn = worker.register_function("greet", greet, description="Greets a user")
981
981
  """
982
982
  if not isinstance(function_id, str):
983
983
  raise TypeError(
@@ -1081,13 +1081,13 @@ class III:
1081
1081
  actions.
1082
1082
 
1083
1083
  Raises:
1084
- IIIInvocationError: For any engine rejection. Inspect ``code``:
1084
+ InvocationError: For any engine rejection. Inspect ``code``:
1085
1085
  ``'TIMEOUT'`` if the invocation timed out, ``'FORBIDDEN'`` if
1086
1086
  RBAC denied it.
1087
1087
 
1088
1088
  Examples:
1089
- >>> result = iii.trigger({'function_id': 'greet', 'payload': {'name': 'World'}})
1090
- >>> iii.trigger({'function_id': 'notify', 'payload': {}, 'action': TriggerAction.Void()})
1089
+ >>> result = worker.trigger({'function_id': 'greet', 'payload': {'name': 'World'}})
1090
+ >>> worker.trigger({'function_id': 'notify', 'payload': {}, 'action': TriggerAction.Void()})
1091
1091
  """
1092
1092
  return self._run_on_loop(self.trigger_async(request))
1093
1093
 
@@ -1108,7 +1108,7 @@ class III:
1108
1108
  The result of the function invocation, or ``None`` for void calls.
1109
1109
 
1110
1110
  Raises:
1111
- IIIInvocationError: For any engine rejection. Inspect ``code``:
1111
+ InvocationError: For any engine rejection. Inspect ``code``:
1112
1112
  ``'TIMEOUT'`` if the invocation timed out, ``'FORBIDDEN'`` if
1113
1113
  RBAC denied it.
1114
1114
 
@@ -1171,7 +1171,7 @@ class III:
1171
1171
  return await asyncio.wait_for(future, timeout=timeout_secs)
1172
1172
  except asyncio.TimeoutError:
1173
1173
  self._pending.pop(invocation_id, None)
1174
- raise IIIInvocationError(
1174
+ raise InvocationError(
1175
1175
  code="TIMEOUT",
1176
1176
  message=f"invocation timed out after {timeout_ms}ms",
1177
1177
  function_id=function_id,
@@ -1308,8 +1308,8 @@ class TriggerAction:
1308
1308
 
1309
1309
  Examples:
1310
1310
  >>> from iii import TriggerAction
1311
- >>> iii.trigger({'function_id': 'process', 'payload': {}, 'action': TriggerAction.Enqueue(queue='jobs')})
1312
- >>> iii.trigger({'function_id': 'notify', 'payload': {}, 'action': TriggerAction.Void()})
1311
+ >>> worker.trigger({'function_id': 'process', 'payload': {}, 'action': TriggerAction.Enqueue(queue='jobs')})
1312
+ >>> worker.trigger({'function_id': 'notify', 'payload': {}, 'action': TriggerAction.Void()})
1313
1313
  """
1314
1314
 
1315
1315
  @staticmethod
@@ -1344,7 +1344,7 @@ def register_worker(address: str, options: InitOptions | None = None) -> III:
1344
1344
 
1345
1345
  Examples:
1346
1346
  >>> from iii import register_worker, InitOptions
1347
- >>> iii = register_worker('ws://localhost:49134', InitOptions(worker_name='my-worker'))
1347
+ >>> worker = register_worker('ws://localhost:49134', InitOptions(worker_name='my-worker'))
1348
1348
  """
1349
1349
  client = III(address, options)
1350
1350
  client._wait_until_connected()
@@ -1,9 +1,9 @@
1
1
  """Constants and configuration types for the III SDK (mirrors iii-constants.ts)."""
2
2
 
3
3
  from dataclasses import dataclass
4
- from typing import Any, Callable, Literal
4
+ from typing import Any, Callable, Final, Literal
5
5
 
6
- from iii_observability import OtelConfig, ReconnectionConfig
6
+ from iii_helpers.observability import OtelConfig, ReconnectionConfig
7
7
 
8
8
  IIIConnectionState = Literal["disconnected", "connecting", "connected", "reconnecting", "failed"]
9
9
 
@@ -26,7 +26,7 @@ class FunctionRef:
26
26
 
27
27
  @dataclass
28
28
  class TelemetryOptions:
29
- """Telemetry metadata to be reported to the engine.
29
+ """Worker metadata reported to the engine.
30
30
 
31
31
  Attributes:
32
32
  language: Programming language of the worker (e.g. ``python``).
@@ -54,7 +54,7 @@ class InitOptions:
54
54
  reconnection_config: WebSocket reconnection behavior.
55
55
  otel: OpenTelemetry configuration. Enabled by default.
56
56
  Set ``{'enabled': False}`` or env ``OTEL_ENABLED=false`` to disable.
57
- telemetry: Internal telemetry metadata.
57
+ telemetry: Internal worker metadata reported to the engine.
58
58
  """
59
59
 
60
60
  worker_name: str | None = None
@@ -65,3 +65,24 @@ class InitOptions:
65
65
  otel: OtelConfig | dict[str, Any] | None = None
66
66
  headers: dict[str, str] | None = None
67
67
  telemetry: TelemetryOptions | None = None
68
+
69
+
70
+ class EngineFunctions:
71
+ """Engine function ids for internal operations (parity with the Node SDK)."""
72
+
73
+ LIST_FUNCTIONS: Final[str] = "engine::functions::list"
74
+ INFO_FUNCTIONS: Final[str] = "engine::functions::info"
75
+ LIST_WORKERS: Final[str] = "engine::workers::list"
76
+ INFO_WORKERS: Final[str] = "engine::workers::info"
77
+ LIST_TRIGGERS: Final[str] = "engine::triggers::list"
78
+ INFO_TRIGGERS: Final[str] = "engine::triggers::info"
79
+ LIST_REGISTERED_TRIGGERS: Final[str] = "engine::registered-triggers::list"
80
+ INFO_REGISTERED_TRIGGERS: Final[str] = "engine::registered-triggers::info"
81
+ REGISTER_WORKER: Final[str] = "engine::workers::register"
82
+
83
+
84
+ class EngineTriggers:
85
+ """Engine trigger ids (parity with the Node SDK)."""
86
+
87
+ FUNCTIONS_AVAILABLE: Final[str] = "engine::functions-available"
88
+ LOG: Final[str] = "log"