piphi-runtime-kit-python 0.4.4__tar.gz → 0.4.6__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 (56) hide show
  1. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/PKG-INFO +1 -1
  2. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/pyproject.toml +1 -1
  3. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/starter.py +43 -2
  4. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_starter.py +56 -0
  5. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/LICENSE +0 -0
  6. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/README.md +0 -0
  7. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/__init__.py +0 -0
  8. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/adapters/__init__.py +0 -0
  9. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/adapters/fastapi.py +0 -0
  10. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/fastapi.py +0 -0
  11. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/__init__.py +0 -0
  12. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/auth.py +0 -0
  13. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/config_sync.py +0 -0
  14. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/configuration.py +0 -0
  15. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/context.py +0 -0
  16. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/discovery.py +0 -0
  17. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/dispatch.py +0 -0
  18. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/errors.py +0 -0
  19. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/events.py +0 -0
  20. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/health.py +0 -0
  21. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/identity.py +0 -0
  22. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/lifespan.py +0 -0
  23. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/mqtt.py +0 -0
  24. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/registry.py +0 -0
  25. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/state.py +0 -0
  26. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/tasks.py +0 -0
  27. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/runtime/telemetry.py +0 -0
  28. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/src/piphi_runtime_kit_python/schemas.py +0 -0
  29. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/__init__.py +0 -0
  30. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_config_sync.py +0 -0
  31. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_fastapi_adapter.py +0 -0
  32. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_auth.py +0 -0
  33. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_auth_matrix.py +0 -0
  34. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_config_sync_matrix.py +0 -0
  35. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_configuration.py +0 -0
  36. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_configuration_matrix.py +0 -0
  37. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_delivery_errors.py +0 -0
  38. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_discovery.py +0 -0
  39. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_discovery_matrix.py +0 -0
  40. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_dispatch.py +0 -0
  41. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_dispatch_matrix.py +0 -0
  42. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_errors_matrix.py +0 -0
  43. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_events.py +0 -0
  44. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_events_matrix.py +0 -0
  45. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_health.py +0 -0
  46. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_identity.py +0 -0
  47. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_lifespan.py +0 -0
  48. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_mqtt.py +0 -0
  49. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_mqtt_matrix.py +0 -0
  50. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_registry.py +0 -0
  51. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_registry_matrix.py +0 -0
  52. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_support_matrix.py +0 -0
  53. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_tasks.py +0 -0
  54. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_telemetry.py +0 -0
  55. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_runtime_telemetry_matrix.py +0 -0
  56. {piphi_runtime_kit_python-0.4.4 → piphi_runtime_kit_python-0.4.6}/tests/test_schemas_matrix.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: piphi-runtime-kit-python
3
- Version: 0.4.4
3
+ Version: 0.4.6
4
4
  Summary: PiPhi Network runtime integration helpers
5
5
  Keywords: piphi,runtime,integration,iot
6
6
  Author-Email: KelvinSan <support@piphi.network>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "piphi-runtime-kit-python"
3
- version = "0.4.4"
3
+ version = "0.4.6"
4
4
  description = "PiPhi Network runtime integration helpers"
5
5
  authors = [
6
6
  { name = "KelvinSan", email = "support@piphi.network" },
@@ -3,15 +3,25 @@ from __future__ import annotations
3
3
  """Opinionated beginner-friendly starter helpers for PiPhi runtimes."""
4
4
 
5
5
  from dataclasses import dataclass, field
6
+ from pathlib import Path
6
7
  from typing import Any
7
8
 
8
- from .config_sync import ConfigSyncCoordinator
9
+ import httpx
10
+
11
+ from .config_sync import (
12
+ DEFAULT_RUNTIME_VOLUME_DIR,
13
+ ConfigSyncCoordinator,
14
+ RuntimeConfigRehydrateResult,
15
+ SnapshotApplyCallable,
16
+ rehydrate_runtime_configs,
17
+ )
9
18
  from .context import RuntimeContext
10
19
  from .events import DEFAULT_CORE_BASE_URL as DEFAULT_EVENTS_CORE_BASE_URL, EventClient
11
20
  from .health import build_runtime_diagnostics_response, build_runtime_health_response
21
+ from .lifespan import DEFAULT_CORE_CLIENT_TIMEOUT_SECONDS
12
22
  from .registry import RuntimeRegistry
13
23
  from .telemetry import DEFAULT_CORE_BASE_URL as DEFAULT_TELEMETRY_CORE_BASE_URL, TelemetryClient
14
- from ..schemas import RuntimeEntitiesResponse
24
+ from ..schemas import RuntimeConfig, RuntimeConfigSnapshot, RuntimeEntitiesResponse
15
25
 
16
26
 
17
27
  @dataclass(slots=True)
@@ -92,6 +102,37 @@ class RuntimeStarter:
92
102
  commands=commands,
93
103
  )
94
104
 
105
+ async def rehydrate_configs(
106
+ self,
107
+ *,
108
+ client: httpx.AsyncClient,
109
+ apply_snapshot: SnapshotApplyCallable,
110
+ config_model: type[RuntimeConfig] = RuntimeConfig,
111
+ snapshot_model: type[Any] = RuntimeConfigSnapshot,
112
+ timeout_seconds: float = DEFAULT_CORE_CLIENT_TIMEOUT_SECONDS,
113
+ snapshot_path: str | Path | None = None,
114
+ snapshot_volume_dir: str | Path = DEFAULT_RUNTIME_VOLUME_DIR,
115
+ raise_core_errors: bool = False,
116
+ ) -> RuntimeConfigRehydrateResult:
117
+ """Load startup configs from the mounted snapshot and then Core.
118
+
119
+ This is the recommended starter-level entry point. Integration authors
120
+ provide their typed config model and apply callback; the starter supplies
121
+ the shared runtime context and Core base URL.
122
+ """
123
+ return await rehydrate_runtime_configs(
124
+ runtime_context=self.runtime,
125
+ client=client,
126
+ apply_snapshot=apply_snapshot,
127
+ config_model=config_model,
128
+ snapshot_model=snapshot_model,
129
+ core_base_url=self.core_base_url,
130
+ timeout_seconds=timeout_seconds,
131
+ snapshot_path=snapshot_path,
132
+ snapshot_volume_dir=snapshot_volume_dir,
133
+ raise_core_errors=raise_core_errors,
134
+ )
135
+
95
136
 
96
137
  def build_entities_response(
97
138
  *,
@@ -1,4 +1,7 @@
1
+ import pytest
2
+
1
3
  from piphi_runtime_kit_python import (
4
+ RuntimeConfigSnapshot,
2
5
  RuntimeEntitiesResponse,
3
6
  RuntimeStarter,
4
7
  create_runtime_starter,
@@ -56,3 +59,56 @@ def test_runtime_starter_entities_response_wraps_runtime_entities() -> None:
56
59
  assert response.entities[0].available_commands[0].id == "toggle"
57
60
  assert response.capabilities == {"switch": {"kind": "action"}}
58
61
  assert response.commands == {"turn_on": {"description": "Turn on"}}
62
+
63
+
64
+ class _CoreConfigResponse:
65
+ def __init__(self, payload):
66
+ self.payload = payload
67
+
68
+ def raise_for_status(self) -> None:
69
+ return None
70
+
71
+ def json(self):
72
+ return self.payload
73
+
74
+
75
+ class _CoreConfigClient:
76
+ def __init__(self, payload):
77
+ self.payload = payload
78
+ self.requests: list[dict] = []
79
+
80
+ async def get(self, url: str, **kwargs):
81
+ self.requests.append({"url": url, **kwargs})
82
+ return _CoreConfigResponse(self.payload)
83
+
84
+
85
+ @pytest.mark.asyncio
86
+ async def test_runtime_starter_rehydrates_configs_with_shared_runtime_context() -> None:
87
+ starter = create_runtime_starter(
88
+ integration_id="demo-runtime",
89
+ integration_name="Demo Runtime",
90
+ core_base_url="http://core.local",
91
+ )
92
+ starter.runtime.auth.update(
93
+ container_id="container-1",
94
+ internal_token="secret-token",
95
+ )
96
+ client = _CoreConfigClient(
97
+ [{"config_data": {"id": "device-1", "name": "Kitchen"}}]
98
+ )
99
+ applied: list[list[str]] = []
100
+
101
+ async def apply_snapshot(snapshot: RuntimeConfigSnapshot) -> None:
102
+ applied.append([config.id for config in snapshot.configs])
103
+
104
+ result = await starter.rehydrate_configs(
105
+ client=client,
106
+ apply_snapshot=apply_snapshot,
107
+ )
108
+
109
+ assert result.core_applied is True
110
+ assert result.core_config_count == 1
111
+ assert applied == [["device-1"]]
112
+ assert client.requests[0]["url"] == (
113
+ "http://core.local/api/v2/integrations/config/fetch/all/by/container/internal"
114
+ )