digitalkin 0.3.3.dev9__tar.gz → 0.3.5.dev0__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 (165) hide show
  1. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/PKG-INFO +2 -2
  2. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/modules/archetype_with_tools_module.py +3 -2
  3. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/pyproject.toml +3 -3
  4. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/__version__.py +1 -1
  5. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/grpc_servers/_base_server.py +56 -48
  6. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/grpc_servers/module_server.py +7 -11
  7. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +9 -9
  8. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/grpc_servers/models.py +2 -154
  9. digitalkin-0.3.5.dev0/src/digitalkin/models/settings/__init__.py +1 -0
  10. digitalkin-0.3.5.dev0/src/digitalkin/models/settings/server/__init__.py +1 -0
  11. digitalkin-0.3.5.dev0/src/digitalkin/models/settings/server/channel.py +36 -0
  12. digitalkin-0.3.5.dev0/src/digitalkin/models/settings/server/grpc.py +99 -0
  13. digitalkin-0.3.5.dev0/src/digitalkin/models/settings/server/server.py +47 -0
  14. digitalkin-0.3.5.dev0/src/digitalkin/models/settings/utils/__init__.py +1 -0
  15. digitalkin-0.3.5.dev0/src/digitalkin/models/settings/utils/channel.py +148 -0
  16. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin.egg-info/PKG-INFO +2 -2
  17. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin.egg-info/SOURCES.txt +7 -0
  18. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin.egg-info/requires.txt +1 -1
  19. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/LICENSE +0 -0
  20. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/README.md +0 -0
  21. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/base_server/__init__.py +0 -0
  22. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/base_server/mock/__init__.py +0 -0
  23. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/base_server/mock/mock_pb2.py +0 -0
  24. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
  25. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/base_server/server_async_insecure.py +0 -0
  26. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/base_server/server_async_secure.py +0 -0
  27. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/base_server/server_sync_insecure.py +0 -0
  28. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/base_server/server_sync_secure.py +0 -0
  29. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/modules/__init__.py +0 -0
  30. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/modules/cpu_intensive_module.py +0 -0
  31. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/modules/dynamic_setup_module.py +0 -0
  32. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/modules/minimal_llm_module.py +0 -0
  33. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/modules/text_transform_module.py +0 -0
  34. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
  35. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
  36. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
  37. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
  38. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
  39. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/monitoring/tests/test_metrics.py +0 -0
  40. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/services/filesystem_module.py +0 -0
  41. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/examples/services/storage_module.py +0 -0
  42. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/setup.cfg +0 -0
  43. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/__init__.py +0 -0
  44. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/__init__.py +0 -0
  45. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/common/__init__.py +0 -0
  46. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/common/factories.py +0 -0
  47. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/job_manager/__init__.py +0 -0
  48. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
  49. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
  50. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/job_manager/taskiq_broker.py +0 -0
  51. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/job_manager/taskiq_job_manager.py +0 -0
  52. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/profiling/__init__.py +0 -0
  53. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/profiling/asyncio_monitor.py +0 -0
  54. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/profiling/task_profiler.py +0 -0
  55. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/task_manager/__init__.py +0 -0
  56. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
  57. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
  58. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
  59. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/task_manager/task_executor.py +0 -0
  60. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/core/task_manager/task_session.py +0 -0
  61. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/grpc_servers/__init__.py +0 -0
  62. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/grpc_servers/module_servicer.py +0 -0
  63. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
  64. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/grpc_servers/utils/exceptions.py +0 -0
  65. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +0 -0
  66. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
  67. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/logger.py +0 -0
  68. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/mixins/__init__.py +0 -0
  69. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/mixins/base_mixin.py +0 -0
  70. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/mixins/callback_mixin.py +0 -0
  71. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/mixins/chat_history_mixin.py +0 -0
  72. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/mixins/cost_mixin.py +0 -0
  73. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/mixins/file_history_mixin.py +0 -0
  74. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
  75. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/mixins/logger_mixin.py +0 -0
  76. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/mixins/storage_mixin.py +0 -0
  77. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/__init__.py +0 -0
  78. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/core/__init__.py +0 -0
  79. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/core/job_manager_models.py +0 -0
  80. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/core/task_monitor.py +0 -0
  81. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
  82. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/grpc_servers/types.py +0 -0
  83. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/module/__init__.py +0 -0
  84. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/module/base_types.py +0 -0
  85. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/module/module.py +0 -0
  86. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/module/module_context.py +0 -0
  87. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/module/module_types.py +0 -0
  88. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/module/request_metadata.py +0 -0
  89. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/module/select_schema.py +0 -0
  90. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/module/setup_types.py +0 -0
  91. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/module/tool_cache.py +0 -0
  92. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/module/tool_reference.py +0 -0
  93. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/module/utility.py +0 -0
  94. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/services/__init__.py +0 -0
  95. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/services/cost.py +0 -0
  96. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/services/registry.py +0 -0
  97. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/models/services/storage.py +0 -0
  98. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/modules/__init__.py +0 -0
  99. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/modules/_base_module.py +0 -0
  100. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/modules/archetype_module.py +0 -0
  101. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/modules/tool_module.py +0 -0
  102. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/modules/trigger_handler.py +0 -0
  103. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/modules/triggers/__init__.py +0 -0
  104. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
  105. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
  106. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
  107. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/py.typed +0 -0
  108. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/__init__.py +0 -0
  109. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/agent/__init__.py +0 -0
  110. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/agent/agent_strategy.py +0 -0
  111. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/agent/default_agent.py +0 -0
  112. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/base_strategy.py +0 -0
  113. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/communication/__init__.py +0 -0
  114. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/communication/communication_strategy.py +0 -0
  115. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/communication/default_communication.py +0 -0
  116. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/communication/grpc_communication.py +0 -0
  117. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/cost/__init__.py +0 -0
  118. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/cost/cost_strategy.py +0 -0
  119. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/cost/default_cost.py +0 -0
  120. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/cost/grpc_cost.py +0 -0
  121. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/filesystem/__init__.py +0 -0
  122. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
  123. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/filesystem/filesystem_strategy.py +0 -0
  124. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/filesystem/grpc_filesystem.py +0 -0
  125. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/identity/__init__.py +0 -0
  126. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/identity/default_identity.py +0 -0
  127. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/identity/identity_strategy.py +0 -0
  128. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/registry/__init__.py +0 -0
  129. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/registry/default_registry.py +0 -0
  130. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/registry/exceptions.py +0 -0
  131. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/registry/grpc_registry.py +0 -0
  132. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/registry/registry_models.py +0 -0
  133. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/registry/registry_strategy.py +0 -0
  134. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/services_config.py +0 -0
  135. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/services_models.py +0 -0
  136. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/setup/__init__.py +0 -0
  137. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/setup/default_setup.py +0 -0
  138. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/setup/grpc_setup.py +0 -0
  139. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/setup/setup_strategy.py +0 -0
  140. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/snapshot/__init__.py +0 -0
  141. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/snapshot/default_snapshot.py +0 -0
  142. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/snapshot/snapshot_strategy.py +0 -0
  143. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/storage/__init__.py +0 -0
  144. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/storage/default_storage.py +0 -0
  145. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/storage/grpc_storage.py +0 -0
  146. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/storage/storage_strategy.py +0 -0
  147. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/task_manager/__init__.py +0 -0
  148. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
  149. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/task_manager/grpc_task_manager.py +0 -0
  150. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
  151. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/user_profile/__init__.py +0 -0
  152. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/user_profile/default_user_profile.py +0 -0
  153. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/user_profile/grpc_user_profile.py +0 -0
  154. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/services/user_profile/user_profile_strategy.py +0 -0
  155. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/utils/__init__.py +0 -0
  156. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/utils/arg_parser.py +0 -0
  157. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/utils/conditional_schema.py +0 -0
  158. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/utils/development_mode_action.py +0 -0
  159. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/utils/dynamic_schema.py +0 -0
  160. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/utils/llm_ready_schema.py +0 -0
  161. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/utils/package_discover.py +0 -0
  162. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/utils/proto_utils.py +0 -0
  163. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin/utils/schema_splitter.py +0 -0
  164. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin.egg-info/dependency_links.txt +0 -0
  165. {digitalkin-0.3.3.dev9 → digitalkin-0.3.5.dev0}/src/digitalkin.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalkin
3
- Version: 0.3.3.dev9
3
+ Version: 0.3.5.dev0
4
4
  Summary: SDK to build kin used in DigitalKin
5
5
  Author-email: "DigitalKin.ai" <contact@digitalkin.ai>
6
6
  License: Attribution-NonCommercial-ShareAlike 4.0 International
@@ -453,7 +453,7 @@ Requires-Python: >=3.10
453
453
  Description-Content-Type: text/markdown
454
454
  License-File: LICENSE
455
455
  Requires-Dist: agentic-mesh-protocol==0.2.3
456
- Requires-Dist: anyio==4.12.1
456
+ Requires-Dist: anyio==4.13.0
457
457
  Requires-Dist: grpcio-health-checking==1.78.0
458
458
  Requires-Dist: grpcio-reflection==1.78.0
459
459
  Requires-Dist: grpcio-status==1.78.0
@@ -5,10 +5,11 @@ from typing import Any, ClassVar, Literal
5
5
 
6
6
  from pydantic import BaseModel, Field
7
7
 
8
- from digitalkin.models.grpc_servers.models import ClientConfig, SecurityMode, ServerMode
8
+ from digitalkin.models.grpc_servers.models import ClientConfig
9
9
  from digitalkin.models.module.module_context import ModuleContext
10
10
  from digitalkin.models.module.setup_types import SetupModel
11
11
  from digitalkin.models.module.tool_reference import ToolReference
12
+ from digitalkin.models.settings.utils.channel import ControlFlow, SecurityMode
12
13
  from digitalkin.modules._base_module import BaseModule # noqa: PLC2701
13
14
  from digitalkin.services.services_models import ServicesStrategy
14
15
 
@@ -98,7 +99,7 @@ class ArchetypeSecret(BaseModel):
98
99
  client_config = ClientConfig(
99
100
  host="[::]",
100
101
  port=50152,
101
- mode=ServerMode.ASYNC,
102
+ mode=ControlFlow.ASYNC,
102
103
  security=SecurityMode.INSECURE,
103
104
  credentials=None,
104
105
  )
@@ -28,13 +28,13 @@
28
28
 
29
29
  dependencies = [
30
30
  "agentic-mesh-protocol==0.2.3",
31
- "anyio==4.12.1",
31
+ "anyio==4.13.0",
32
32
  "grpcio-health-checking==1.78.0",
33
33
  "grpcio-reflection==1.78.0",
34
34
  "grpcio-status==1.78.0",
35
35
  "pydantic==2.12.5",
36
36
  ]
37
- version = "0.3.3.dev9"
37
+ version = "0.3.5.dev0"
38
38
 
39
39
  [project.optional-dependencies]
40
40
  profiling = [
@@ -60,7 +60,7 @@
60
60
 
61
61
  [dependency-groups]
62
62
  dev = [
63
- "build==1.4.0",
63
+ "build==1.4.1",
64
64
  "bump-my-version==1.2.7",
65
65
  "cryptography==46.0.5",
66
66
  "mypy==1.19.1",
@@ -5,4 +5,4 @@ from importlib.metadata import PackageNotFoundError, version
5
5
  try:
6
6
  __version__ = version("digitalkin")
7
7
  except PackageNotFoundError:
8
- __version__ = "0.3.3.dev9"
8
+ __version__ = "0.3.5.dev0"
@@ -6,7 +6,7 @@ import os
6
6
  from collections.abc import Callable, Sequence
7
7
  from concurrent import futures
8
8
  from pathlib import Path
9
- from typing import Any, cast
9
+ from typing import Any, ClassVar, cast
10
10
 
11
11
  import grpc
12
12
  from grpc import aio as grpc_aio
@@ -20,8 +20,9 @@ from digitalkin.grpc_servers.utils.exceptions import (
20
20
  )
21
21
  from digitalkin.grpc_servers.utils.grpc_client_wrapper import GrpcClientWrapper
22
22
  from digitalkin.logger import logger
23
- from digitalkin.models.grpc_servers.models import SecurityMode, ServerConfig, ServerMode
24
23
  from digitalkin.models.grpc_servers.types import GrpcServer, ServiceDescriptor, T
24
+ from digitalkin.models.settings.server.server import ServerSettings
25
+ from digitalkin.models.settings.utils.channel import ControlFlow, SecurityMode
25
26
 
26
27
 
27
28
  class BaseServer(abc.ABC):
@@ -32,25 +33,23 @@ class BaseServer(abc.ABC):
32
33
  communication modes.
33
34
 
34
35
  Attributes:
35
- config: The server configuration.
36
36
  server: The gRPC server instance (either sync or async).
37
37
  _servicers: List of registered servicers.
38
38
  _service_names: List of service names for reflection.
39
39
  _health_servicer: Optional health check servicer.
40
40
  """
41
41
 
42
+ _server_settings: ClassVar[ServerSettings] = ServerSettings()
43
+
42
44
  def __init__(
43
45
  self,
44
- config: ServerConfig,
45
46
  interceptors: Sequence[Any] | None = None,
46
47
  ) -> None:
47
48
  """Initialize the base gRPC server.
48
49
 
49
50
  Args:
50
- config: The server configuration.
51
51
  interceptors: Optional sequence of gRPC server interceptors.
52
52
  """
53
- self.config = config
54
53
  self.server: GrpcServer | None = None
55
54
  self._servicers: list[Any] = []
56
55
  self._service_names: list[str] = [] # Track service names for reflection
@@ -119,7 +118,7 @@ class BaseServer(abc.ABC):
119
118
  Raises:
120
119
  ReflectionError: If reflection initialization fails.
121
120
  """
122
- if not self.config.enable_reflection or self.server is None or not self._service_names:
121
+ if not self._server_settings.reflection or self.server is None or not self._service_names:
123
122
  return
124
123
 
125
124
  try:
@@ -194,17 +193,17 @@ class BaseServer(abc.ABC):
194
193
  logger.warning("Failed to enable health service: %s", e)
195
194
 
196
195
  def _create_server(self) -> GrpcServer:
197
- """Create a gRPC server instance based on the configuration.
196
+ """Create a gRPC server instance based on the server settings.
198
197
 
199
198
  Returns:
200
199
  A configured gRPC server instance.
201
200
 
202
201
  Raises:
203
- ConfigurationError: If the server configuration is invalid.
202
+ ConfigurationError: If the server settings are invalid.
204
203
  """
205
204
  try:
206
205
  # Create the server based on mode
207
- grpc_compression = self.config.compression.to_grpc()
206
+ grpc_compression = self._server_settings.grpc.compression.to_grpc()
208
207
 
209
208
  # Machine capabilities
210
209
  try:
@@ -215,36 +214,36 @@ class BaseServer(abc.ABC):
215
214
  logger.info("CPU count: %d", cpu_count)
216
215
 
217
216
  # Compute defaults from machine capabilities, overridable via env vars
218
- max_concurrent_rpcs = int(os.environ.get("DIGITALKIN_MAX_CONCURRENT_RPCS", str(cpu_count * 200)))
219
- thread_pool_workers = int(os.environ.get("DIGITALKIN_THREAD_POOL_WORKERS", str(min(4, cpu_count))))
220
217
 
221
218
  logger.info(
222
- "gRPC server config: cpus=%d, max_concurrent_rpcs=%d, thread_pool_workers=%d, mode=%s",
219
+ "gRPC server settings.server: cpus=%d, max_concurrent_rpcs=%d, thread_pool_workers=%d, mode=%s",
223
220
  cpu_count,
224
- max_concurrent_rpcs,
225
- thread_pool_workers,
226
- self.config.mode.value,
221
+ self._server_settings.max_concurrent_rpcs,
222
+ self._server_settings.thread_pool_workers,
223
+ self._server_settings.channel.communication_mode.value,
227
224
  )
228
225
 
229
- if self.config.mode == ServerMode.ASYNC:
226
+ if self._server_settings.channel.communication_mode == ControlFlow.ASYNC:
230
227
  server = grpc_aio.server(
231
- options=self.config.server_options,
228
+ options=self._server_settings.grpc.options,
232
229
  compression=grpc_compression,
233
230
  interceptors=self._interceptors or None,
234
- maximum_concurrent_rpcs=max_concurrent_rpcs,
235
- migration_thread_pool=futures.ThreadPoolExecutor(max_workers=thread_pool_workers),
231
+ maximum_concurrent_rpcs=self._server_settings.max_concurrent_rpcs,
232
+ migration_thread_pool=futures.ThreadPoolExecutor(
233
+ max_workers=self._server_settings.thread_pool_workers
234
+ ),
236
235
  )
237
236
  else:
238
237
  server = grpc.server( # type: ignore[assignment] # sync grpc.Server assigned to GrpcServer union
239
- futures.ThreadPoolExecutor(max_workers=self.config.max_workers),
240
- options=self.config.server_options,
238
+ futures.ThreadPoolExecutor(max_workers=self._server_settings.max_workers),
239
+ options=self._server_settings.grpc.options,
241
240
  compression=grpc_compression,
242
241
  interceptors=self._interceptors or None,
243
- maximum_concurrent_rpcs=max_concurrent_rpcs,
242
+ maximum_concurrent_rpcs=self._server_settings.max_concurrent_rpcs,
244
243
  )
245
244
 
246
245
  # Add the appropriate port
247
- if self.config.security == SecurityMode.SECURE:
246
+ if self._server_settings.channel.security == SecurityMode.SECURE:
248
247
  self._add_secure_port(server)
249
248
  else:
250
249
  self._add_insecure_port(server)
@@ -264,19 +263,26 @@ class BaseServer(abc.ABC):
264
263
  Raises:
265
264
  SecurityError: If credentials are not configured correctly.
266
265
  """
267
- if not self.config.credentials:
266
+ if not self._server_settings.channel.credentials:
268
267
  msg = "Credentials must be provided for secure server"
269
268
  raise SecurityError(msg)
270
269
 
271
270
  try:
272
271
  # Read key and certificate files
273
- private_key = Path(self.config.credentials.server_key_path).read_bytes()
274
- certificate_chain = Path(self.config.credentials.server_cert_path).read_bytes()
272
+ if (
273
+ self._server_settings.channel.credentials.key_path
274
+ and self._server_settings.channel.credentials.cert_path
275
+ ):
276
+ private_key = Path(self._server_settings.channel.credentials.key_path).read_bytes()
277
+ certificate_chain = Path(self._server_settings.channel.credentials.cert_path).read_bytes()
278
+ else:
279
+ msg = "Key path and certificate path must be provided for secure server"
280
+ raise SecurityError(msg)
275
281
 
276
282
  # Read root certificate if provided
277
283
  root_certificates = None
278
- if self.config.credentials.root_cert_path:
279
- root_certificates = Path(self.config.credentials.root_cert_path).read_bytes()
284
+ if self._server_settings.channel.credentials.root_cert_path:
285
+ root_certificates = Path(self._server_settings.channel.credentials.root_cert_path).read_bytes()
280
286
  except OSError as e:
281
287
  msg = f"Failed to read credential files: {e}"
282
288
  raise SecurityError(msg) from e
@@ -290,16 +296,16 @@ class BaseServer(abc.ABC):
290
296
  )
291
297
 
292
298
  # Add secure port to server
293
- if self.config.mode == ServerMode.ASYNC:
299
+ if self._server_settings.channel.communication_mode == ControlFlow.ASYNC:
294
300
  async_server = cast("grpc_aio.Server", server)
295
- async_server.add_secure_port(self.config.address, server_credentials)
301
+ async_server.add_secure_port(self._server_settings.channel.address, server_credentials)
296
302
  else:
297
303
  sync_server = cast("grpc.Server", server)
298
- sync_server.add_secure_port(self.config.address, server_credentials)
304
+ sync_server.add_secure_port(self._server_settings.channel.address, server_credentials)
299
305
 
300
- logger.debug("Added secure port %s", self.config.address)
306
+ logger.debug("Added secure port %s", self._server_settings.channel.address)
301
307
  except Exception as e:
302
- msg = f"Failed to configure secure port: {e}"
308
+ msg = f"Failed to configure with actual settings secure port: {e}"
303
309
  raise SecurityError(msg) from e
304
310
 
305
311
  def _add_insecure_port(self, server: GrpcServer) -> None:
@@ -312,14 +318,14 @@ class BaseServer(abc.ABC):
312
318
  ConfigurationError: If adding the insecure port fails.
313
319
  """
314
320
  try:
315
- if self.config.mode == ServerMode.ASYNC:
321
+ if self._server_settings.channel.communication_mode == ControlFlow.ASYNC:
316
322
  async_server = cast("grpc_aio.Server", server)
317
- async_server.add_insecure_port(self.config.address)
323
+ async_server.add_insecure_port(self._server_settings.channel.address)
318
324
  else:
319
325
  sync_server = cast("grpc.Server", server)
320
- sync_server.add_insecure_port(self.config.address)
326
+ sync_server.add_insecure_port(self._server_settings.channel.address)
321
327
 
322
- logger.debug("Added insecure port %s", self.config.address)
328
+ logger.debug("Added insecure port %s", self._server_settings.channel.address)
323
329
  except Exception as e:
324
330
  msg = f"Failed to add insecure port: {e}"
325
331
  raise ConfigurationError(msg) from e
@@ -343,9 +349,11 @@ class BaseServer(abc.ABC):
343
349
  self._add_reflection()
344
350
 
345
351
  # Start the server
346
- logger.debug("Starting gRPC server on %s", self.config.address, extra={"config": self.config})
352
+ logger.debug(
353
+ "Starting gRPC server on %s", self._server_settings.channel.address, extra={"config": ServerSettings}
354
+ )
347
355
  try:
348
- if self.config.mode == ServerMode.ASYNC:
356
+ if self._server_settings.channel.communication_mode == ControlFlow.ASYNC:
349
357
  # For async server, use the event loop
350
358
  loop = asyncio.get_event_loop()
351
359
  if loop.is_closed():
@@ -356,7 +364,7 @@ class BaseServer(abc.ABC):
356
364
  # For sync server, directly call start
357
365
  sync_server = cast("grpc.Server", self.server)
358
366
  sync_server.start()
359
- logger.debug("✅ gRPC server started on %s", self.config.address)
367
+ logger.debug("✅ gRPC server started on %s", self._server_settings.channel.address)
360
368
  except Exception as e:
361
369
  logger.exception("❎ Error starting server")
362
370
  msg = f"Failed to start server: {e}"
@@ -393,15 +401,15 @@ class BaseServer(abc.ABC):
393
401
  self._add_reflection()
394
402
 
395
403
  # Start the server
396
- logger.debug("Starting gRPC server on %s", self.config.address)
404
+ logger.debug("Starting gRPC server on %s", self._server_settings.channel.address)
397
405
  try:
398
- if self.config.mode == ServerMode.ASYNC:
406
+ if self._server_settings.channel.communication_mode == ControlFlow.ASYNC:
399
407
  await self._start_async()
400
408
  else:
401
409
  # For sync server in async context
402
410
  sync_server = cast("grpc.Server", self.server)
403
411
  sync_server.start()
404
- logger.debug("✅ gRPC server started on %s", self.config.address)
412
+ logger.debug("✅ gRPC server started on %s", self._server_settings.channel.address)
405
413
  except Exception as e:
406
414
  logger.exception("❎ Error starting server")
407
415
  msg = f"Failed to start server: {e}"
@@ -431,7 +439,7 @@ class BaseServer(abc.ABC):
431
439
  return
432
440
 
433
441
  logger.debug("Stopping gRPC server...")
434
- if self.config.mode == ServerMode.ASYNC:
442
+ if self._server_settings.channel.communication_mode == ControlFlow.ASYNC:
435
443
  # We'll use a different approach that works whether we're in a running event loop or not
436
444
  try:
437
445
  # Get the current event loop
@@ -507,7 +515,7 @@ class BaseServer(abc.ABC):
507
515
  return
508
516
 
509
517
  logger.debug("Stopping gRPC server asynchronously...")
510
- if self.config.mode == ServerMode.ASYNC:
518
+ if self._server_settings.channel.communication_mode == ControlFlow.ASYNC:
511
519
  await self._stop_async(grace)
512
520
  else:
513
521
  # For sync server, we can just call stop
@@ -533,7 +541,7 @@ class BaseServer(abc.ABC):
533
541
  logger.warning("Attempted to wait for termination, but no server is running")
534
542
  return
535
543
 
536
- if self.config.mode == ServerMode.SYNC:
544
+ if self._server_settings.channel.communication_mode == ControlFlow.SYNC:
537
545
  # For sync server
538
546
  sync_server = cast("grpc.Server", self.server)
539
547
  sync_server.wait_for_termination()
@@ -548,7 +556,7 @@ class BaseServer(abc.ABC):
548
556
 
549
557
  This method should only be used with async servers.
550
558
  """
551
- if self.config.mode == ServerMode.SYNC:
559
+ if self._server_settings.channel.communication_mode == ControlFlow.SYNC:
552
560
  logger.warning(
553
561
  "Called await_termination on sync server. Use wait_for_termination instead for sync servers.",
554
562
  )
@@ -13,7 +13,6 @@ from digitalkin.grpc_servers.module_servicer import ModuleServicer
13
13
  from digitalkin.logger import logger
14
14
  from digitalkin.models.grpc_servers.models import (
15
15
  ClientConfig,
16
- ModuleServerConfig,
17
16
  )
18
17
  from digitalkin.modules._base_module import BaseModule
19
18
  from digitalkin.services.registry import GrpcRegistry
@@ -38,7 +37,6 @@ class ModuleServer(BaseServer):
38
37
  def __init__(
39
38
  self,
40
39
  module_class: type[BaseModule],
41
- server_config: ModuleServerConfig,
42
40
  client_config: ClientConfig | None = None,
43
41
  interceptors: Sequence[Any] | None = None,
44
42
  ) -> None:
@@ -46,13 +44,11 @@ class ModuleServer(BaseServer):
46
44
 
47
45
  Args:
48
46
  module_class: The module instance to be served.
49
- server_config: Server configuration.
50
47
  client_config: Client configuration used by services and registry connection.
51
48
  interceptors: Optional sequence of gRPC server interceptors.
52
49
  """
53
- super().__init__(server_config, interceptors=interceptors)
50
+ super().__init__(interceptors=interceptors)
54
51
  self.module_class = module_class
55
- self.server_config = server_config
56
52
  self.client_config = client_config
57
53
  self.module_servicer: ModuleServicer | None = None
58
54
  self.registry: RegistryStrategy | None = None
@@ -108,7 +104,7 @@ class ModuleServer(BaseServer):
108
104
  """Start the module server and register with the registry if configured."""
109
105
  import asyncio
110
106
 
111
- logger.info("Starting module server", extra={"server_config": self.server_config})
107
+ logger.info("Starting module server", extra={"server_config": self._server_settings})
112
108
  super().start()
113
109
 
114
110
  try:
@@ -119,7 +115,7 @@ class ModuleServer(BaseServer):
119
115
 
120
116
  async def start_async(self) -> None:
121
117
  """Start the module server and register with the registry if configured."""
122
- logger.info("Starting module server", extra={"server_config": self.server_config})
118
+ logger.info("Starting module server", extra={"server_config": self._server_settings})
123
119
  await super().start_async()
124
120
 
125
121
  # module_servicer is now set by _register_servicers() during super().start_async()
@@ -191,14 +187,14 @@ class ModuleServer(BaseServer):
191
187
  )
192
188
  return
193
189
 
194
- advertise_address = self.server_config.advertise_host or self.server_config.host
190
+ advertise_address = self._server_settings.channel.advertise_host or self._server_settings.channel.host
195
191
 
196
192
  logger.info(
197
193
  "Attempting to register module with registry",
198
194
  extra={
199
195
  "module_id": module_id,
200
196
  "address": advertise_address,
201
- "port": self.server_config.port,
197
+ "port": self._server_settings.channel.port,
202
198
  "version": version,
203
199
  },
204
200
  )
@@ -206,7 +202,7 @@ class ModuleServer(BaseServer):
206
202
  result = await self.registry.register(
207
203
  module_id=module_id,
208
204
  address=advertise_address,
209
- port=self.server_config.port,
205
+ port=self._server_settings.channel.port,
210
206
  version=version,
211
207
  )
212
208
 
@@ -216,7 +212,7 @@ class ModuleServer(BaseServer):
216
212
  extra={
217
213
  "module_id": result.module_id,
218
214
  "address": advertise_address,
219
- "port": self.server_config.port,
215
+ "port": self._server_settings.channel.port,
220
216
  },
221
217
  )
222
218
  else:
@@ -11,7 +11,8 @@ import grpc.aio
11
11
 
12
12
  from digitalkin.grpc_servers.utils.exceptions import ServerError
13
13
  from digitalkin.logger import logger
14
- from digitalkin.models.grpc_servers.models import ClientConfig, SecurityMode
14
+ from digitalkin.models.grpc_servers.models import ClientConfig
15
+ from digitalkin.models.settings.utils.channel import SecurityMode
15
16
 
16
17
 
17
18
  class GrpcClientWrapper:
@@ -31,6 +32,13 @@ class GrpcClientWrapper:
31
32
  _channel_cache_key: str | None = None
32
33
  _channel_cache: ClassVar[dict[str, grpc.aio.Channel]] = {}
33
34
  _ref_counts: ClassVar[dict[str, int]] = {}
35
+ _RETRYABLE_CODES: ClassVar[set[grpc.StatusCode]] = {
36
+ grpc.StatusCode.UNAVAILABLE,
37
+ grpc.StatusCode.INTERNAL,
38
+ grpc.StatusCode.DEADLINE_EXCEEDED,
39
+ }
40
+ _QUERY_MAX_RETRIES: ClassVar[int] = int(os.environ.get("DIGITALKIN_GRPC_QUERY_MAX_RETRIES", "2"))
41
+ _QUERY_BACKOFF_BASE_MS: ClassVar[float] = float(os.environ.get("DIGITALKIN_GRPC_QUERY_BACKOFF_BASE_MS", "50"))
34
42
 
35
43
  @staticmethod
36
44
  def _build_channel_credentials(config: ClientConfig) -> grpc.ChannelCredentials | None:
@@ -140,14 +148,6 @@ class GrpcClientWrapper:
140
148
  cls._channel_cache.clear()
141
149
  cls._ref_counts.clear()
142
150
 
143
- _RETRYABLE_CODES: ClassVar[set[grpc.StatusCode]] = {
144
- grpc.StatusCode.UNAVAILABLE,
145
- grpc.StatusCode.INTERNAL,
146
- grpc.StatusCode.DEADLINE_EXCEEDED,
147
- }
148
- _QUERY_MAX_RETRIES: ClassVar[int] = int(os.environ.get("DIGITALKIN_GRPC_QUERY_MAX_RETRIES", "2"))
149
- _QUERY_BACKOFF_BASE_MS: ClassVar[float] = float(os.environ.get("DIGITALKIN_GRPC_QUERY_BACKOFF_BASE_MS", "50"))
150
-
151
151
  async def exec_grpc_query(
152
152
  self,
153
153
  query_endpoint: str,
@@ -9,6 +9,7 @@ import grpc
9
9
  from pydantic import BaseModel, Field, ValidationInfo, field_validator
10
10
 
11
11
  from digitalkin.grpc_servers.utils.exceptions import ConfigurationError, SecurityError
12
+ from digitalkin.models.settings.utils.channel import ControlFlow, SecurityMode
12
13
 
13
14
 
14
15
  class GrpcCompression(str, Enum):
@@ -39,61 +40,6 @@ class GrpcCompression(str, Enum):
39
40
  return grpc.Compression.Deflate
40
41
 
41
42
 
42
- class ServerMode(str, Enum):
43
- """Enum for server operation mode."""
44
-
45
- SYNC = "sync"
46
- ASYNC = "async"
47
-
48
-
49
- class SecurityMode(str, Enum):
50
- """Enum for server security mode."""
51
-
52
- SECURE = "secure"
53
- INSECURE = "insecure"
54
-
55
-
56
- class ServerCredentials(BaseModel):
57
- """Model for server credentials in secure mode.
58
-
59
- Attributes:
60
- server_key_path: Path to the server private key
61
- server_cert_path: Path to the server certificate
62
- root_cert_path: Optional path to the root certificate
63
- """
64
-
65
- server_key_path: Path = Field(..., description="Path to the server private key")
66
- server_cert_path: Path = Field(..., description="Path to the server certificate")
67
- root_cert_path: Path | None = Field(None, description="Path to the root certificate")
68
-
69
- # Enable __slots__ for memory efficiency
70
- model_config = {
71
- "extra": "forbid",
72
- "arbitrary_types_allowed": True,
73
- "validate_assignment": True,
74
- "frozen": True,
75
- }
76
-
77
- @field_validator("server_key_path", "server_cert_path", "root_cert_path")
78
- @classmethod
79
- def check_path_exists(cls, v: Path | None) -> Path | None:
80
- """Validate that the file path exists.
81
-
82
- Args:
83
- v: Path to validate
84
-
85
- Returns:
86
- The validated path
87
-
88
- Raises:
89
- SecurityError: If the path does not exist
90
- """
91
- if v is not None and not v.exists():
92
- msg = f"File not found: {v}"
93
- raise SecurityError(msg)
94
- return v
95
-
96
-
97
43
  class RetryPolicy(BaseModel):
98
44
  """gRPC retry policy configuration for resilient connections.
99
45
 
@@ -202,7 +148,7 @@ class ChannelConfig(BaseModel):
202
148
  description="Host address to bind the client to",
203
149
  ) # Bind to all interfaces by design
204
150
  port: int = Field(50051, description="Port to listen on")
205
- mode: ServerMode = Field(ServerMode.SYNC, description="Client operation mode (sync/async)")
151
+ mode: ControlFlow = Field(ControlFlow.SYNC, description="Client operation mode (sync/async)")
206
152
  security: SecurityMode = Field(SecurityMode.INSECURE, description="Security mode (secure/insecure)")
207
153
 
208
154
  # Enable __slots__ for memory efficiency
@@ -315,101 +261,3 @@ class ClientConfig(ChannelConfig):
315
261
  Full list of gRPC channel options.
316
262
  """
317
263
  return [*self.channel_options, ("grpc.service_config", self.retry_policy.to_service_config_json())]
318
-
319
-
320
- class ServerConfig(ChannelConfig):
321
- """Base configuration for gRPC servers.
322
-
323
- Attributes:
324
- host: Host address to bind the server to
325
- port: Port to listen on
326
- max_workers: Maximum number of workers for sync mode
327
- mode: Server operation mode (sync/async)
328
- security: Security mode (secure/insecure)
329
- credentials: Server credentials for secure mode
330
- server_options: Additional server options
331
- enable_reflection: Enable reflection for the server
332
- compression: gRPC compression algorithm for server-level compression
333
- """
334
-
335
- max_workers: int = Field(10, description="Maximum number of workers for sync mode")
336
- credentials: ServerCredentials | None = Field(None, description="Server credentials for secure mode")
337
- compression: GrpcCompression = Field(GrpcCompression.GZIP, description="gRPC compression algorithm")
338
- server_options: list[tuple[str, Any]] = Field(
339
- default_factory=lambda: [
340
- ("grpc.max_receive_message_length", 100 * 1024 * 1024),
341
- ("grpc.max_send_message_length", 100 * 1024 * 1024),
342
- # === Server-Side Keepalive (Keeps Connections Alive Through Proxies) ===
343
- # Server sends keepalive pings to detect dead clients and keep
344
- # proxy connections (e.g. Railway) alive during long-running RPCs.
345
- (
346
- "grpc.keepalive_time_ms",
347
- int(os.environ.get("DIGITALKIN_GRPC_SERVER_KEEPALIVE_TIME_MS", "120000")),
348
- ),
349
- (
350
- "grpc.keepalive_timeout_ms",
351
- int(os.environ.get("DIGITALKIN_GRPC_SERVER_KEEPALIVE_TIMEOUT_MS", "20000")),
352
- ),
353
- # === Keepalive Permission (Required for Client Keepalive) ===
354
- # Allow clients to send keepalive pings without active RPCs
355
- # Without this, server rejects client keepalives with GOAWAY
356
- ("grpc.keepalive_permit_without_calls", True),
357
- # Allow unlimited pings without data (required for long-running streams)
358
- ("grpc.http2.max_pings_without_data", 0),
359
- # Minimum interval server allows between client pings
360
- # Prevents "too_many_pings" GOAWAY errors
361
- # Must match or be less than client's http2.min_time_between_pings_ms
362
- (
363
- "grpc.http2.min_ping_interval_without_data_ms",
364
- int(os.environ.get("DIGITALKIN_GRPC_SERVER_MIN_PING_INTERVAL_MS", "10000")),
365
- ),
366
- ],
367
- description="gRPC server options with keepalive support",
368
- )
369
- enable_reflection: bool = Field(default=True, description="Enable reflection for the server")
370
- enable_health_check: bool = Field(default=True, description="Enable health check service")
371
-
372
- @field_validator("credentials")
373
- @classmethod
374
- def validate_credentials(cls, v: ServerCredentials | None, info: ValidationInfo) -> ServerCredentials | None:
375
- """Validate that credentials are provided when in secure mode.
376
-
377
- Args:
378
- v: The credentials value
379
- info: ValidationInfo containing other field values
380
-
381
- Returns:
382
- The validated credentials
383
-
384
- Raises:
385
- ConfigurationError: If credentials are missing in secure mode
386
- """
387
- # Access security mode from the info.data dictionary
388
- security = info.data.get("security")
389
-
390
- if security == SecurityMode.SECURE and v is None:
391
- msg = "Credentials must be provided when using secure mode"
392
- raise ConfigurationError(msg)
393
- return v
394
-
395
-
396
- class ModuleServerConfig(ServerConfig):
397
- """Configuration for Module gRPC server.
398
-
399
- Attributes:
400
- advertise_host: Public hostname/IP sent to registry for discovery. Falls back to host if not set.
401
- """
402
-
403
- advertise_host: str | None = Field(
404
- None, description="Public hostname/IP sent to registry for discovery. Falls back to host if not set."
405
- )
406
-
407
-
408
- class RegistryServerConfig(ServerConfig):
409
- """Configuration for Registry gRPC server.
410
-
411
- Attributes:
412
- database_url: Database URL for registry data storage
413
- """
414
-
415
- database_url: str | None = Field(None, description="Database URL for registry data storage")
@@ -0,0 +1 @@
1
+ """This package contain settings of sdk."""
@@ -0,0 +1 @@
1
+ """Package for server settings."""