iii-sdk 0.11.0.dev10__tar.gz → 0.11.1.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 (55) hide show
  1. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/PKG-INFO +1 -1
  2. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/pyproject.toml +1 -1
  3. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/iii.py +1 -0
  4. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/iii_types.py +4 -0
  5. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/telemetry_exporters.py +2 -2
  6. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_telemetry_exporters.py +26 -0
  7. iii_sdk-0.11.1.dev1/tests/test_worker_metadata.py +33 -0
  8. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/uv.lock +6 -12
  9. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/.gitignore +0 -0
  10. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/README.md +0 -0
  11. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/__init__.py +0 -0
  12. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/channels.py +0 -0
  13. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/format_utils.py +0 -0
  14. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/iii_constants.py +0 -0
  15. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/logger.py +0 -0
  16. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/otel_worker_gauges.py +0 -0
  17. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/state.py +0 -0
  18. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/stream.py +0 -0
  19. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/telemetry.py +0 -0
  20. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/telemetry_types.py +0 -0
  21. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/triggers.py +0 -0
  22. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/types.py +0 -0
  23. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/utils.py +0 -0
  24. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/src/iii/worker_metrics.py +0 -0
  25. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/conftest.py +0 -0
  26. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_api_triggers.py +0 -0
  27. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_async_api.py +0 -0
  28. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_bridge.py +0 -0
  29. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_channel_close_delay.py +0 -0
  30. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_context_propagation.py +0 -0
  31. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_data_channels.py +0 -0
  32. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_format_utils.py +0 -0
  33. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_healthcheck.py +0 -0
  34. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_hold_process.py +0 -0
  35. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_http_external_functions_integration.py +0 -0
  36. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_iii_registration_dedup.py +0 -0
  37. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_init_api.py +0 -0
  38. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_invocation_exception.py +0 -0
  39. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_logger_function_ids.py +0 -0
  40. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_logger_otel.py +0 -0
  41. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_middleware.py +0 -0
  42. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_pubsub.py +0 -0
  43. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_queue_integration.py +0 -0
  44. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_rbac_workers.py +0 -0
  45. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_register_function_args.py +0 -0
  46. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_state.py +0 -0
  47. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_streams.py +0 -0
  48. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_streams_runtime_annotations.py +0 -0
  49. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_sync_api.py +0 -0
  50. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_telemetry.py +0 -0
  51. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_telemetry_types.py +0 -0
  52. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_trace_helpers.py +0 -0
  53. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_trigger_metadata.py +0 -0
  54. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.dev1}/tests/test_utils.py +0 -0
  55. {iii_sdk-0.11.0.dev10 → iii_sdk-0.11.1.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.11.0.dev10
3
+ Version: 0.11.1.dev1
4
4
  Summary: III SDK for Python
5
5
  Project-URL: Homepage, https://github.com/iii-hq/sdk
6
6
  Project-URL: Repository, https://github.com/iii-hq/sdk
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "iii-sdk"
7
- version = "0.11.0.dev10"
7
+ version = "0.11.1.dev1"
8
8
  description = "III SDK for Python"
9
9
  authors = [{ name = "III" }]
10
10
  license = { text = "Apache-2.0" }
@@ -1291,6 +1291,7 @@ class III:
1291
1291
  "name": worker_name,
1292
1292
  "os": f"{platform.system()} {platform.release()} ({platform.machine()})",
1293
1293
  "pid": os.getpid(),
1294
+ "isolation": os.environ.get("III_ISOLATION") or None,
1294
1295
  "telemetry": telemetry,
1295
1296
  }
1296
1297
 
@@ -636,6 +636,10 @@ class WorkerInfo(BaseModel):
636
636
  function_count: int = Field(description="Number of registered functions.")
637
637
  functions: list[str] = Field(description="List of registered function IDs.")
638
638
  active_invocations: int = Field(description="Number of currently executing invocations.")
639
+ isolation: str | None = Field(
640
+ default=None,
641
+ description="Self-reported isolation context (e.g. ``libkrun``, ``docker``, ``k8s``).",
642
+ )
639
643
 
640
644
 
641
645
  class StreamChannelRef(BaseModel):
@@ -395,8 +395,8 @@ def _serialize_metrics(metrics_data: Any) -> bytes:
395
395
  scope_metrics_json.append(
396
396
  {
397
397
  "scope": {
398
- "name": scope.name if scope else "",
399
- "version": scope.version if scope else "",
398
+ "name": (scope.name if scope else "") or "",
399
+ "version": (scope.version if scope else "") or "",
400
400
  },
401
401
  "metrics": metrics_json,
402
402
  }
@@ -179,6 +179,32 @@ def test_pre_start_buffer_drops_oldest_when_full():
179
179
  assert last == str(SharedEngineConnection.MAX_QUEUE).encode()
180
180
 
181
181
 
182
+ def test_serialize_metrics_emits_empty_string_for_missing_scope_version():
183
+ """Regression: meter_provider.get_meter(name) produces scope.version=None in
184
+ the Python OTel SDK. The serializer must emit "" (not JSON null) so the Rust
185
+ engine's String deserializer doesn't reject the payload.
186
+ """
187
+ from iii.telemetry_exporters import _serialize_metrics
188
+ from opentelemetry.sdk.metrics import MeterProvider
189
+ from opentelemetry.sdk.metrics.export import InMemoryMetricReader
190
+ from opentelemetry.sdk.resources import Resource
191
+
192
+ reader = InMemoryMetricReader()
193
+ resource = Resource.create({"service.name": "iii-py-test"})
194
+ provider = MeterProvider(resource=resource, metric_readers=[reader])
195
+ meter = provider.get_meter("iii-py-test") # no version argument
196
+ counter = meter.create_counter("test.counter")
197
+ counter.add(1, {"k": "v"})
198
+
199
+ payload = _serialize_metrics(reader.get_metrics_data()).decode()
200
+ parsed = json.loads(payload)
201
+
202
+ scope = parsed["resourceMetrics"][0]["scopeMetrics"][0]["scope"]
203
+ assert scope["name"] == "iii-py-test"
204
+ assert scope["version"] == ""
205
+ assert scope["version"] is not None
206
+
207
+
182
208
  @pytest.mark.asyncio
183
209
  async def test_start_drains_pre_start_buffer_into_queue():
184
210
  """start() moves buffered frames into the asyncio queue."""
@@ -0,0 +1,33 @@
1
+ from __future__ import annotations
2
+
3
+ import pytest
4
+
5
+ from iii import InitOptions
6
+ from iii.iii import III
7
+
8
+
9
+ def _call_metadata_method() -> dict[str, object]:
10
+ stub = III.__new__(III)
11
+ stub._options = InitOptions()
12
+ return stub._get_worker_metadata()
13
+
14
+
15
+ def test_get_worker_metadata_isolation_is_none_when_env_unset(
16
+ monkeypatch: pytest.MonkeyPatch,
17
+ ) -> None:
18
+ monkeypatch.delenv("III_ISOLATION", raising=False)
19
+
20
+ metadata = _call_metadata_method()
21
+
22
+ assert "isolation" in metadata
23
+ assert metadata["isolation"] is None
24
+
25
+
26
+ def test_get_worker_metadata_forwards_iii_isolation_env_var(
27
+ monkeypatch: pytest.MonkeyPatch,
28
+ ) -> None:
29
+ monkeypatch.setenv("III_ISOLATION", "docker")
30
+
31
+ metadata = _call_metadata_method()
32
+
33
+ assert metadata["isolation"] == "docker"
@@ -500,9 +500,11 @@ wheels = [
500
500
 
501
501
  [[package]]
502
502
  name = "iii-sdk"
503
- version = "0.10.0"
503
+ version = "0.11.0.dev9"
504
504
  source = { editable = "." }
505
505
  dependencies = [
506
+ { name = "opentelemetry-api" },
507
+ { name = "opentelemetry-sdk" },
506
508
  { name = "pydantic" },
507
509
  { name = "websockets" },
508
510
  ]
@@ -513,17 +515,11 @@ dev = [
513
515
  { name = "anyio" },
514
516
  { name = "griffe" },
515
517
  { name = "mypy" },
516
- { name = "opentelemetry-api" },
517
- { name = "opentelemetry-sdk" },
518
518
  { name = "pytest" },
519
519
  { name = "pytest-asyncio" },
520
520
  { name = "pytest-cov" },
521
521
  { name = "ruff" },
522
522
  ]
523
- otel = [
524
- { name = "opentelemetry-api" },
525
- { name = "opentelemetry-sdk" },
526
- ]
527
523
 
528
524
  [package.metadata]
529
525
  requires-dist = [
@@ -531,10 +527,8 @@ requires-dist = [
531
527
  { name = "anyio", marker = "extra == 'dev'", specifier = ">=4.0" },
532
528
  { name = "griffe", marker = "extra == 'dev'", specifier = ">=1.0" },
533
529
  { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.8" },
534
- { name = "opentelemetry-api", marker = "extra == 'dev'", specifier = ">=1.25" },
535
- { name = "opentelemetry-api", marker = "extra == 'otel'", specifier = ">=1.25" },
536
- { name = "opentelemetry-sdk", marker = "extra == 'dev'", specifier = ">=1.25" },
537
- { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.25" },
530
+ { name = "opentelemetry-api", specifier = ">=1.25" },
531
+ { name = "opentelemetry-sdk", specifier = ">=1.25" },
538
532
  { name = "pydantic", specifier = ">=2.0" },
539
533
  { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0" },
540
534
  { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.23" },
@@ -542,7 +536,7 @@ requires-dist = [
542
536
  { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.2" },
543
537
  { name = "websockets", specifier = ">=12.0" },
544
538
  ]
545
- provides-extras = ["otel", "dev"]
539
+ provides-extras = ["dev"]
546
540
 
547
541
  [[package]]
548
542
  name = "importlib-metadata"
File without changes
File without changes