digitalkin 1.0.4.dev4__tar.gz → 1.0.4.dev6__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 (275) hide show
  1. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/PKG-INFO +1 -1
  2. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/services/filesystem_module.py +7 -6
  3. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/pyproject.toml +1 -1
  4. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/__version__.py +1 -1
  5. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/resilience/bulkhead.py +6 -5
  6. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/redis/proto_streams.py +1 -1
  7. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/_base_server.py +4 -4
  8. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/module_server.py +3 -12
  9. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/module_servicer.py +9 -5
  10. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +3 -3
  11. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +6 -6
  12. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/file_history_mixin.py +4 -3
  13. digitalkin-1.0.4.dev6/src/digitalkin/mixins/filesystem_mixin.py +215 -0
  14. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/grpc_servers/models.py +37 -28
  15. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/__init__.py +6 -0
  16. digitalkin-1.0.4.dev6/src/digitalkin/models/module/knowledge_files.py +87 -0
  17. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/services/__init__.py +4 -0
  18. digitalkin-1.0.4.dev6/src/digitalkin/models/services/filesystem.py +127 -0
  19. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/services/storage.py +3 -9
  20. digitalkin-1.0.4.dev6/src/digitalkin/models/settings/grpc_client.py +127 -0
  21. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/module.py +2 -17
  22. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/profiling.py +1 -1
  23. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/redis.py +1 -5
  24. digitalkin-1.0.4.dev6/src/digitalkin/models/settings/resilience.py +31 -0
  25. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/server/channel.py +3 -23
  26. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/server/grpc.py +1 -1
  27. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/server/server.py +2 -4
  28. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/utils/channel.py +7 -45
  29. digitalkin-1.0.4.dev6/src/digitalkin/services/filesystem/__init__.py +19 -0
  30. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/filesystem/default_filesystem.py +24 -22
  31. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/filesystem/filesystem_strategy.py +49 -49
  32. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/filesystem/grpc_filesystem.py +18 -40
  33. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/services_config.py +4 -16
  34. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/development_mode_action.py +18 -10
  35. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin.egg-info/PKG-INFO +1 -1
  36. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin.egg-info/SOURCES.txt +3 -8
  37. digitalkin-1.0.4.dev4/src/digitalkin/mixins/filesystem_mixin.py +0 -46
  38. digitalkin-1.0.4.dev4/src/digitalkin/models/settings/certificate.py +0 -90
  39. digitalkin-1.0.4.dev4/src/digitalkin/models/settings/client/__init__.py +0 -1
  40. digitalkin-1.0.4.dev4/src/digitalkin/models/settings/client/channel.py +0 -68
  41. digitalkin-1.0.4.dev4/src/digitalkin/models/settings/client/circuit_breaker.py +0 -19
  42. digitalkin-1.0.4.dev4/src/digitalkin/models/settings/client/client.py +0 -55
  43. digitalkin-1.0.4.dev4/src/digitalkin/models/settings/client/grpc.py +0 -148
  44. digitalkin-1.0.4.dev4/src/digitalkin/models/settings/resilience.py +0 -61
  45. digitalkin-1.0.4.dev4/src/digitalkin/services/filesystem/__init__.py +0 -7
  46. digitalkin-1.0.4.dev4/src/digitalkin/utils/env_manager.py +0 -139
  47. digitalkin-1.0.4.dev4/src/digitalkin/utils/env_template.py +0 -233
  48. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/LICENSE +0 -0
  49. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/README.md +0 -0
  50. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/base_server/__init__.py +0 -0
  51. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/base_server/mock/__init__.py +0 -0
  52. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/base_server/mock/mock_pb2.py +0 -0
  53. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
  54. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/base_server/server_async_insecure.py +0 -0
  55. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/base_server/server_async_secure.py +0 -0
  56. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/base_server/server_sync_insecure.py +0 -0
  57. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/base_server/server_sync_secure.py +0 -0
  58. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/bench_module/__init__.py +0 -0
  59. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/bench_module/echo_module.py +0 -0
  60. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/bench_module/models/__init__.py +0 -0
  61. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/bench_module/models/input.py +0 -0
  62. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/bench_module/models/output.py +0 -0
  63. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/bench_module/models/secret.py +0 -0
  64. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/bench_module/models/setup.py +0 -0
  65. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/bench_module/server.py +0 -0
  66. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/bench_module/triggers/__init__.py +0 -0
  67. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/bench_module/triggers/message_trigger.py +0 -0
  68. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/modules/__init__.py +0 -0
  69. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/modules/archetype_with_tools_module.py +0 -0
  70. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/modules/cpu_intensive_module.py +0 -0
  71. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/modules/dynamic_setup_module.py +0 -0
  72. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/modules/minimal_llm_module.py +0 -0
  73. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/modules/text_transform_module.py +0 -0
  74. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
  75. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
  76. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
  77. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
  78. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
  79. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/monitoring/tests/test_metrics.py +0 -0
  80. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/redis_demo/client.py +0 -0
  81. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/redis_demo/echo_module.py +0 -0
  82. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/redis_demo/models/__init__.py +0 -0
  83. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/redis_demo/models/input.py +0 -0
  84. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/redis_demo/models/output.py +0 -0
  85. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/redis_demo/models/secret.py +0 -0
  86. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/redis_demo/models/setup.py +0 -0
  87. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/redis_demo/server.py +0 -0
  88. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/redis_demo/triggers/__init__.py +0 -0
  89. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/redis_demo/triggers/message_trigger.py +0 -0
  90. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/examples/services/storage_module.py +0 -0
  91. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/setup.cfg +0 -0
  92. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/__init__.py +0 -0
  93. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/__init__.py +0 -0
  94. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/__init__.py +0 -0
  95. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/agno_adapter.py +0 -0
  96. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/agui_tools.py +0 -0
  97. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/hitl.py +0 -0
  98. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/models.py +0 -0
  99. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/module_toolkit.py +0 -0
  100. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/__init__.py +0 -0
  101. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/base.py +0 -0
  102. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/chat_history.py +0 -0
  103. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/defaults.py +0 -0
  104. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/__init__.py +0 -0
  105. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/action.py +0 -0
  106. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/base.py +0 -0
  107. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/kins/__init__.py +0 -0
  108. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/kins/action.py +0 -0
  109. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/kins/kit.py +0 -0
  110. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/loader/__init__.py +0 -0
  111. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/loader/action.py +0 -0
  112. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/loader/kit.py +0 -0
  113. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/services/__init__.py +0 -0
  114. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/services/action.py +0 -0
  115. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/services/kit.py +0 -0
  116. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/tools/__init__.py +0 -0
  117. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/tools/action.py +0 -0
  118. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/tools/kit.py +0 -0
  119. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/user_profile.py +0 -0
  120. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/__init__.py +0 -0
  121. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/common/__init__.py +0 -0
  122. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/common/factories.py +0 -0
  123. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/exceptions.py +0 -0
  124. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/job_manager/__init__.py +0 -0
  125. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
  126. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
  127. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/profiling/__init__.py +0 -0
  128. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/profiling/step_timer.py +0 -0
  129. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/profiling/task_profiler.py +0 -0
  130. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/resilience/__init__.py +0 -0
  131. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
  132. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/__init__.py +0 -0
  133. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
  134. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
  135. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/module_runner.py +0 -0
  136. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
  137. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/redis/redis_client.py +0 -0
  138. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +0 -0
  139. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/redis/redis_signal.py +0 -0
  140. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/redis/redis_state.py +0 -0
  141. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
  142. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/task_executor.py +0 -0
  143. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/task_session.py +0 -0
  144. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/exceptions.py +0 -0
  145. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/__init__.py +0 -0
  146. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/exceptions.py +0 -0
  147. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/gateway_servicer.py +0 -0
  148. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
  149. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/interceptors/permission.py +0 -0
  150. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/interceptors/request_ids.py +0 -0
  151. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/m2m_call_registry.py +0 -0
  152. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/stream_registry.py +0 -0
  153. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/stream_session.py +0 -0
  154. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
  155. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +0 -0
  156. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
  157. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
  158. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/logger.py +0 -0
  159. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/__init__.py +0 -0
  160. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/agui_mixin.py +0 -0
  161. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/base_mixin.py +0 -0
  162. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/cost_mixin.py +0 -0
  163. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/logger_mixin.py +0 -0
  164. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/storage_mixin.py +0 -0
  165. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/__init__.py +0 -0
  166. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/core/__init__.py +0 -0
  167. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/core/job_manager_models.py +0 -0
  168. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/core/redis.py +0 -0
  169. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/core/task_monitor.py +0 -0
  170. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/events/__init__.py +0 -0
  171. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/events/agent_events.py +0 -0
  172. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
  173. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
  174. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
  175. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/grpc_servers/stream_error_codes.py +0 -0
  176. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/grpc_servers/types.py +0 -0
  177. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/ag_ui.py +0 -0
  178. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/base_types.py +0 -0
  179. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/loaded_tools.py +0 -0
  180. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/module.py +0 -0
  181. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/module_context.py +0 -0
  182. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/module_types.py +0 -0
  183. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/request_metadata.py +0 -0
  184. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/select_schema.py +0 -0
  185. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/setup_types.py +0 -0
  186. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/tool_cache.py +0 -0
  187. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/tool_reference.py +0 -0
  188. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/utility.py +0 -0
  189. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/services/cost.py +0 -0
  190. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/services/registry.py +0 -0
  191. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/services/services.py +0 -0
  192. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/__init__.py +0 -0
  193. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/gateway.py +0 -0
  194. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/log.py +0 -0
  195. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/queue.py +0 -0
  196. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/registry.py +0 -0
  197. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/server/__init__.py +0 -0
  198. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/server/servicer.py +0 -0
  199. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/task_manager.py +0 -0
  200. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/utils/__init__.py +0 -0
  201. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/utils/__init__.py +0 -0
  202. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
  203. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/__init__.py +0 -0
  204. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/_base_module.py +0 -0
  205. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/archetype_module.py +0 -0
  206. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/tool_module.py +0 -0
  207. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/trigger_handler.py +0 -0
  208. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/triggers/__init__.py +0 -0
  209. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
  210. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
  211. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
  212. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/py.typed +0 -0
  213. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/__init__.py +0 -0
  214. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/base_strategy.py +0 -0
  215. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/communication/__init__.py +0 -0
  216. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/communication/communication_strategy.py +0 -0
  217. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/communication/default_communication.py +0 -0
  218. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/communication/exceptions.py +0 -0
  219. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/communication/grpc_communication.py +0 -0
  220. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/cost/__init__.py +0 -0
  221. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/cost/cost_strategy.py +0 -0
  222. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/cost/default_cost.py +0 -0
  223. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/cost/exceptions.py +0 -0
  224. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/cost/grpc_cost.py +0 -0
  225. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/filesystem/exceptions.py +0 -0
  226. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/identity/__init__.py +0 -0
  227. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/identity/default_identity.py +0 -0
  228. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/identity/identity_strategy.py +0 -0
  229. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/registry/__init__.py +0 -0
  230. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/registry/default_registry.py +0 -0
  231. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/registry/exceptions.py +0 -0
  232. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/registry/grpc_registry.py +0 -0
  233. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/registry/registry_models.py +0 -0
  234. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/registry/registry_strategy.py +0 -0
  235. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/secret/__init__.py +0 -0
  236. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/secret/default_secret.py +0 -0
  237. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/secret/exceptions.py +0 -0
  238. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/secret/grpc_secret.py +0 -0
  239. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/secret/secret_strategy.py +0 -0
  240. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/services_models.py +0 -0
  241. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/setup/__init__.py +0 -0
  242. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/setup/default_setup.py +0 -0
  243. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/setup/exceptions.py +0 -0
  244. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/setup/grpc_setup.py +0 -0
  245. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/setup/setup_strategy.py +0 -0
  246. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/storage/__init__.py +0 -0
  247. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/storage/default_storage.py +0 -0
  248. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/storage/exceptions.py +0 -0
  249. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/storage/grpc_storage.py +0 -0
  250. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/storage/storage_strategy.py +0 -0
  251. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/task_manager/__init__.py +0 -0
  252. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
  253. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/task_manager/exceptions.py +0 -0
  254. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
  255. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
  256. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/user_profile/__init__.py +0 -0
  257. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/user_profile/default_user_profile.py +0 -0
  258. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/user_profile/exceptions.py +0 -0
  259. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/user_profile/grpc_user_profile.py +0 -0
  260. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/services/user_profile/user_profile_strategy.py +0 -0
  261. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/__init__.py +0 -0
  262. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/arg_parser.py +0 -0
  263. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/conditional_schema.py +0 -0
  264. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/dynamic_schema.py +0 -0
  265. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/exceptions.py +0 -0
  266. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/json_structure.py +0 -0
  267. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/llm_ready_schema.py +0 -0
  268. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/package_discover.py +0 -0
  269. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/proto_utils.py +0 -0
  270. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/schema_splitter.py +0 -0
  271. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/setup_content_validator.py +0 -0
  272. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin.egg-info/dependency_links.txt +0 -0
  273. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin.egg-info/requires.txt +0 -0
  274. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/src/digitalkin.egg-info/top_level.txt +0 -0
  275. {digitalkin-1.0.4.dev4 → digitalkin-1.0.4.dev6}/tests/test_exceptions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalkin
3
- Version: 1.0.4.dev4
3
+ Version: 1.0.4.dev6
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
@@ -10,7 +10,8 @@ from pydantic import BaseModel, Field
10
10
  from digitalkin.logger import logger
11
11
  from digitalkin.models.module import ModuleStatus
12
12
  from digitalkin.modules.archetype_module import ArchetypeModule
13
- from digitalkin.services.filesystem.filesystem_strategy import FileFilter, UploadFileData
13
+ from digitalkin.models.services.filesystem import FileType
14
+ from digitalkin.services.filesystem import FileFilter, UploadFileData
14
15
  from digitalkin.services.services_config import ServicesConfig
15
16
  from digitalkin.services.services_models import ServicesMode
16
17
 
@@ -118,9 +119,9 @@ class ExampleModule(ArchetypeModule[ExampleInput, ExampleOutput, ExampleSetup, E
118
119
  file = UploadFileData(
119
120
  content=b"%s\n%s" % (processed_message.encode(), str(processed_number).encode()),
120
121
  name="example_output.txt",
121
- file_type="text/plain",
122
+ type=FileType.DOCUMENT,
122
123
  content_type="text/plain",
123
- metadata={"example_key": "example_value"},
124
+ metadata={"sdk_created": True},
124
125
  replace_if_exists=True,
125
126
  )
126
127
 
@@ -176,10 +177,10 @@ async def test_module() -> None:
176
177
  # Check the storage
177
178
  if module.status == ModuleStatus.STOPPED:
178
179
  files, _nb_results = await module.filesystem.get_files(
179
- filters=FileFilter(name="example_output.txt", context="test-mission-123"),
180
+ filters=FileFilter(names=["example_output.txt"]),
180
181
  )
181
182
  for file in files:
182
- await module.filesystem.update_file(file.id, file_type="updated")
183
+ await module.filesystem.update_file(file.id, type=FileType.OTHER)
183
184
  # module.filesystem.delete_files(filters=FileFilter(name="example_output.txt", context="test-mission-123"), permanent=True)
184
185
 
185
186
  logger.info("Retrieved file: %s with ID: %s", file.name, file.id)
@@ -188,7 +189,7 @@ async def test_module() -> None:
188
189
  if file_record:
189
190
  logger.info("File ID: %s", file_record.id)
190
191
  logger.info("File name: %s", file_record.name)
191
- logger.info("File type: %s", file_record.file_type)
192
+ logger.info("File type: %s", file_record.type)
192
193
  logger.info("File status: %s", file_record.status)
193
194
  logger.info("File content: %s", file_record.content.decode())
194
195
  except Exception:
@@ -41,7 +41,7 @@
41
41
  "pydantic>=2.12.4",
42
42
  "redis[hiredis]>=7.4.0,<9",
43
43
  ]
44
- version = "1.0.4.dev4"
44
+ version = "1.0.4.dev6"
45
45
 
46
46
  [project.optional-dependencies]
47
47
  agno = [ "agno>=2.6" ]
@@ -5,4 +5,4 @@ from importlib.metadata import PackageNotFoundError, version
5
5
  try:
6
6
  __version__ = version("digitalkin")
7
7
  except PackageNotFoundError:
8
- __version__ = "1.0.4.dev4"
8
+ __version__ = "1.0.4.dev6"
@@ -15,12 +15,13 @@ Usage in ModuleContext or service wrapper::
15
15
  from __future__ import annotations
16
16
 
17
17
  import asyncio
18
+ import os
18
19
  from typing import ClassVar
19
20
 
20
21
  from typing_extensions import Self
21
22
 
22
23
  from digitalkin.core.exceptions import BulkheadFullError
23
- from digitalkin.models.settings.resilience import BulkheadServiceSettings, get_bulkhead_settings
24
+ from digitalkin.models.settings.resilience import get_bulkhead_settings
24
25
 
25
26
 
26
27
  class Bulkhead:
@@ -61,10 +62,10 @@ class Bulkhead:
61
62
  del cls._instances[oldest]
62
63
 
63
64
  settings = get_bulkhead_settings()
64
- # The override carries the service id in the variable name; the settings
65
- # class builds that prefix itself, so nothing here touches the environment.
66
- override = BulkheadServiceSettings(service_id).max
67
- max_concurrent = override if override is not None else settings.default_max
65
+ # Per-service override has a dynamic env-var suffix, so it cannot be a
66
+ # static settings field — read it directly, falling back to the setting.
67
+ env_max = os.environ.get(f"DIGITALKIN_BULKHEAD_{service_id.upper()}_MAX")
68
+ max_concurrent = int(env_max) if env_max is not None else settings.default_max
68
69
 
69
70
  inst = cls(
70
71
  service_id=service_id,
@@ -43,7 +43,7 @@ class ProtoStreamReader:
43
43
  """Initialize proto stream reader.
44
44
 
45
45
  Cursor TTL comes from ``GatewayStreamSettings.redis_cursor_ttl`` (env
46
- ``DIGITALKIN_GATEWAY_STREAM_REDIS_CURSOR_TTL``).
46
+ ``DIGITALKIN_REDIS_CURSOR_TTL``).
47
47
 
48
48
  Args:
49
49
  task_id: Unique task identifier.
@@ -35,7 +35,6 @@ from digitalkin.logger import logger
35
35
  from digitalkin.models.grpc_servers.types import GrpcServer, ServiceDescriptor, T
36
36
  from digitalkin.models.settings.server.server import get_server_settings
37
37
  from digitalkin.models.settings.utils.channel import ControlFlow, SecurityMode
38
- from digitalkin.utils.env_manager import EnvManager
39
38
 
40
39
 
41
40
  class BaseServer(abc.ABC):
@@ -258,9 +257,10 @@ class BaseServer(abc.ABC):
258
257
  Raises:
259
258
  SecurityError: If credentials are missing or unreadable.
260
259
  """
261
- # Explicit SERVER_CHANNEL_CREDENTIALS__* paths, else the CERTIFICATE_CERT_VOLUME
262
- # directory; the resolution itself raises when the key or certificate is absent.
263
- creds = EnvManager.server_credentials()
260
+ creds = get_server_settings().channel.credentials
261
+ if not creds:
262
+ msg = "Credentials must be provided for secure server"
263
+ raise SecurityError(msg)
264
264
 
265
265
  try: # ruff: ignore[too-many-statements-in-try-clause]
266
266
  if creds.key_path and creds.cert_path:
@@ -1,5 +1,6 @@
1
1
  """Module gRPC server implementation for DigitalKin."""
2
2
 
3
+ import os
3
4
  from collections.abc import Sequence
4
5
  from typing import TYPE_CHECKING, Any
5
6
 
@@ -14,12 +15,9 @@ from digitalkin.grpc_servers.gateway_servicer import GatewayServicer
14
15
  from digitalkin.grpc_servers.module_servicer import ModuleServicer
15
16
  from digitalkin.logger import logger
16
17
  from digitalkin.models.grpc_servers.models import ClientConfig
17
- from digitalkin.models.services.services import ServicesMode
18
- from digitalkin.models.settings.redis import get_redis_settings
19
18
  from digitalkin.models.settings.server.server import get_server_settings
20
19
  from digitalkin.modules._base_module import BaseModule
21
20
  from digitalkin.services.registry import GrpcRegistry
22
- from digitalkin.utils.env_manager import EnvManager
23
21
 
24
22
  if TYPE_CHECKING:
25
23
  from digitalkin.services.registry import RegistryStrategy
@@ -42,11 +40,6 @@ class ModuleServer(BaseServer):
42
40
  ) -> None:
43
41
  """Initialize the module server.
44
42
 
45
- In remote mode an omitted ``client_config`` is built from the
46
- environment, so a module no longer declares one to reach the registry
47
- and the services provider. Local mode keeps it unset: there is no
48
- registry to register with.
49
-
50
43
  Args:
51
44
  module_class: The module class to serve.
52
45
  client_config: Client configuration for services and registry.
@@ -56,8 +49,6 @@ class ModuleServer(BaseServer):
56
49
 
57
50
  super().__init__(interceptors=all_interceptors or None)
58
51
  self.module_class = module_class
59
- if client_config is None and EnvManager.services_mode() == ServicesMode.REMOTE:
60
- client_config = EnvManager.client_config()
61
52
  self.client_config = client_config
62
53
  self.registry: RegistryStrategy | None = None
63
54
  self.module_servicer: ModuleServicer | None = None
@@ -102,9 +93,9 @@ class ModuleServer(BaseServer):
102
93
  dispatcher process, queue, or Redis stream for dispatch.
103
94
 
104
95
  Raises:
105
- RuntimeError: If DIGITALKIN_REDIS_URL resolves to an empty URL.
96
+ RuntimeError: If DIGITALKIN_REDIS_URL is not set.
106
97
  """
107
- redis_url = get_redis_settings().pool.url.get_secret_value()
98
+ redis_url = os.environ.get("DIGITALKIN_REDIS_URL")
108
99
  if not redis_url:
109
100
  msg = "DIGITALKIN_REDIS_URL is required. The gateway needs Redis for stream persistence."
110
101
  raise RuntimeError(msg)
@@ -2,6 +2,7 @@
2
2
 
3
3
  import asyncio
4
4
  import json
5
+ import os
5
6
  import time
6
7
  from argparse import ArgumentParser, Namespace
7
8
  from collections.abc import Awaitable, Callable
@@ -27,7 +28,6 @@ from digitalkin.models.module.module import ModuleCodeModel
27
28
  from digitalkin.models.module.setup_types import SetupModel
28
29
  from digitalkin.models.services.services import ServicesMode
29
30
  from digitalkin.models.settings.gateway import get_gateway_settings
30
- from digitalkin.models.settings.redis import get_redis_settings
31
31
  from digitalkin.models.settings.server.servicer import get_module_servicer_settings
32
32
  from digitalkin.modules._base_module import BaseModule
33
33
  from digitalkin.services.registry import GrpcRegistry, RegistryStrategy
@@ -37,7 +37,6 @@ from digitalkin.services.setup.setup_strategy import SetupStrategy, SetupVersion
37
37
  from digitalkin.services.user_profile import DefaultUserProfile, GrpcUserProfile, UserProfileStrategy
38
38
  from digitalkin.utils.arg_parser import ArgParser
39
39
  from digitalkin.utils.development_mode_action import DevelopmentModeMappingAction
40
- from digitalkin.utils.env_manager import EnvManager
41
40
 
42
41
 
43
42
  class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
@@ -56,7 +55,9 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
56
55
  parser.add_argument(
57
56
  "-d",
58
57
  "--dev-mode",
58
+ env_var="SERVICE_MODE",
59
59
  choices=ServicesMode.__members__,
60
+ default="local",
60
61
  action=DevelopmentModeMappingAction,
61
62
  dest="services_mode",
62
63
  help="Define Module Service configurations for endpoints",
@@ -69,13 +70,13 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
69
70
  module_class: The module type to serve.
70
71
 
71
72
  Raises:
72
- RuntimeError: If DIGITALKIN_REDIS_URL resolves to an empty URL.
73
+ RuntimeError: If DIGITALKIN_REDIS_URL is not set.
73
74
  """
74
75
  super().__init__()
75
76
  module_class.discover()
76
77
  self.module_class = module_class
77
78
 
78
- redis_url = get_redis_settings().pool.url.get_secret_value()
79
+ redis_url = os.environ.get("DIGITALKIN_REDIS_URL")
79
80
  if not redis_url:
80
81
  msg = "DIGITALKIN_REDIS_URL is required"
81
82
  raise RuntimeError(msg)
@@ -89,7 +90,10 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
89
90
  # Access-control client gating the setup cache. Always built, always called (fail-closed).
90
91
  if self.args.services_mode == ServicesMode.REMOTE:
91
92
  up_cfg = self.module_class.services_config_params.get("user_profile") or {}
92
- up_client_config = up_cfg.get("client_config") or EnvManager.client_config()
93
+ up_client_config = up_cfg.get("client_config")
94
+ if not up_client_config:
95
+ msg = "user_profile client_config is required for setup access control"
96
+ raise RuntimeError(msg)
93
97
  self.user_profile = GrpcUserProfile("", "", "", up_client_config)
94
98
  else:
95
99
  self.user_profile = DefaultUserProfile("", "", "")
@@ -15,7 +15,7 @@ from typing import ClassVar
15
15
  from digitalkin.grpc_servers.exceptions import CircuitOpenError
16
16
  from digitalkin.logger import logger
17
17
  from digitalkin.models.grpc_servers.circuit_breaker import CBState
18
- from digitalkin.models.settings.client.client import get_client_settings
18
+ from digitalkin.models.settings.grpc_client import get_circuit_breaker_settings
19
19
 
20
20
 
21
21
  class CircuitBreaker:
@@ -45,7 +45,7 @@ class CircuitBreaker:
45
45
  """Get existing circuit breaker for a service or create one.
46
46
 
47
47
  Thresholds come from ``CircuitBreakerSettings`` (env
48
- ``CLIENT_CIRCUIT_BREAKER_FAIL_MAX``, ``CLIENT_CIRCUIT_BREAKER_RESET_TIMEOUT``).
48
+ ``DIGITALKIN_CB_FAIL_MAX``, ``DIGITALKIN_CB_RESET_TIMEOUT``).
49
49
 
50
50
  Args:
51
51
  service_id: Service identifier.
@@ -54,7 +54,7 @@ class CircuitBreaker:
54
54
  Circuit breaker for this service.
55
55
  """
56
56
  if service_id not in cls._instances:
57
- settings = get_client_settings().circuit_breaker
57
+ settings = get_circuit_breaker_settings()
58
58
  cls._instances[service_id] = cls(service_id, settings.fail_max, settings.reset_timeout)
59
59
  return cls._instances[service_id]
60
60
 
@@ -21,7 +21,7 @@ from digitalkin.grpc_servers.interceptors.request_ids import RequestIdClientInte
21
21
  from digitalkin.grpc_servers.utils.circuit_breaker import CircuitBreaker
22
22
  from digitalkin.logger import logger
23
23
  from digitalkin.models.grpc_servers.models import ClientConfig
24
- from digitalkin.models.settings.client.client import get_client_settings
24
+ from digitalkin.models.settings.grpc_client import get_grpc_client_settings
25
25
  from digitalkin.models.settings.utils.channel import SecurityMode
26
26
 
27
27
 
@@ -240,7 +240,7 @@ class GrpcClientWrapper:
240
240
 
241
241
  Retries on transient errors (UNAVAILABLE, INTERNAL, DEADLINE_EXCEEDED)
242
242
  with exponential backoff. Retry count and backoff base are configurable
243
- via CLIENT_MAX_RETRIES and CLIENT_BACKOFF_BASE_MS.
243
+ via DIGITALKIN_GRPC_QUERY_MAX_RETRIES and DIGITALKIN_GRPC_QUERY_BACKOFF_BASE_MS.
244
244
 
245
245
  Arguments:
246
246
  query_endpoint: rpc query name (e.g., "GetSetup", "CreateSetupVersion")
@@ -269,10 +269,10 @@ class GrpcClientWrapper:
269
269
  error_msg = f"[gRPC-client:{self.service_name}.{query_endpoint}] {e}"
270
270
  raise ServerError(error_msg) from e
271
271
 
272
- client_settings = get_client_settings()
273
- eff_timeout = timeout if timeout is not None else client_settings.timeout
274
- max_retries = client_settings.max_retries
275
- backoff_base_ms = client_settings.backoff_base_ms
272
+ grpc_settings = get_grpc_client_settings()
273
+ eff_timeout = timeout if timeout is not None else grpc_settings.timeout
274
+ max_retries = grpc_settings.max_retries
275
+ backoff_base_ms = grpc_settings.backoff_base_ms
276
276
  backoff_delays = tuple(backoff_base_ms / 1000 * (2**i) for i in range(max_retries))
277
277
  last_error: grpc.RpcError | None = None
278
278
 
@@ -10,7 +10,8 @@ from digitalkin.logger import logger
10
10
  from digitalkin.mixins.logger_mixin import LoggerMixin
11
11
  from digitalkin.mixins.storage_mixin import StorageMixin
12
12
  from digitalkin.models.module.module_context import ModuleContext
13
- from digitalkin.models.services.storage import FileHistory, FileModel
13
+ from digitalkin.models.services.filesystem import FileMetadata
14
+ from digitalkin.models.services.storage import FileHistory
14
15
  from digitalkin.models.settings.module import get_module_settings
15
16
 
16
17
 
@@ -84,7 +85,7 @@ class FileHistoryMixin(StorageMixin, LoggerMixin):
84
85
  self._fh_cache[history_key] = history
85
86
  return history
86
87
 
87
- async def append_files_history(self, context: ModuleContext, files: list[FileModel]) -> None:
88
+ async def append_files_history(self, context: ModuleContext, files: list[FileMetadata]) -> None:
88
89
  """Append files to file history.
89
90
 
90
91
  Files are added to the in-memory cache immediately. A storage
@@ -93,7 +94,7 @@ class FileHistoryMixin(StorageMixin, LoggerMixin):
93
94
 
94
95
  Args:
95
96
  context: Module context containing storage strategy.
96
- files: List of file models to append.
97
+ files: Files to append.
97
98
  """
98
99
  history_key = self._get_fh_history_key(context)
99
100
  file_history = await self.load_file_history(context)
@@ -0,0 +1,215 @@
1
+ """Filesystem Mixin to ease filesystem use."""
2
+
3
+ from digitalkin.logger import logger
4
+ from digitalkin.models.module.module_context import ModuleContext
5
+ from digitalkin.models.services.filesystem import FileMetadata, FileType, FileUploadMetadata
6
+ from digitalkin.models.services.services import Context
7
+ from digitalkin.models.services.storage import Visibility
8
+ from digitalkin.services.filesystem.filesystem_strategy import FileFilter, FilesystemRecord, UploadFileData
9
+
10
+
11
+ class FilesystemMixin:
12
+ """Mixin providing filesystem operations through the filesystem strategy.
13
+
14
+ This mixin wraps filesystem strategy calls to provide a cleaner API
15
+ for file operations in trigger handlers.
16
+ """
17
+
18
+ @staticmethod
19
+ async def upload_files(
20
+ context: ModuleContext, files: list[UploadFileData]
21
+ ) -> tuple[list[FilesystemRecord], int, int]:
22
+ """Upload files using the filesystem strategy.
23
+
24
+ Args:
25
+ context: Module context containing the filesystem strategy
26
+ files: List of files to upload
27
+
28
+ Returns:
29
+ Tuple of (all_files, succeeded_files, failed_files)
30
+
31
+ Raises:
32
+ FilesystemServiceError: If upload operation fails
33
+ """
34
+ return await context.filesystem.upload_files(files)
35
+
36
+ @staticmethod
37
+ async def upload_file(
38
+ context: ModuleContext,
39
+ name: str,
40
+ content: bytes,
41
+ content_type: str,
42
+ type: FileType | None = None, # Matches the canonical field name # ruff: ignore[builtin-argument-shadowing]
43
+ visibility: Visibility = Visibility.UNSPECIFIED,
44
+ *,
45
+ sdk_created: bool = False,
46
+ ) -> FileMetadata | None:
47
+ """Upload a single file, inferring its type from the MIME type when not given.
48
+
49
+ Args:
50
+ context: Module context containing the filesystem strategy
51
+ name: The name of the file
52
+ content: The content of the file
53
+ content_type: The MIME type of the file
54
+ type: The category of the file; inferred from `content_type` when omitted
55
+ visibility: Read-access scope; UNSPECIFIED lets the service default it
56
+ sdk_created: Whether this file is a module deliverable
57
+
58
+ Returns:
59
+ The uploaded file, or None when the upload failed.
60
+ """
61
+ try:
62
+ records, _uploaded, failed = await context.filesystem.upload_files([
63
+ UploadFileData(
64
+ content=content,
65
+ name=name,
66
+ type=type or FileType.from_content_type(content_type),
67
+ content_type=content_type,
68
+ metadata=FileUploadMetadata(sdk_created=sdk_created, filename=name),
69
+ replace_if_exists=True,
70
+ visibility=visibility,
71
+ )
72
+ ])
73
+ except Exception:
74
+ logger.exception("Failed to upload file '%s' (%s)", name, content_type)
75
+ return None
76
+ if failed or not records:
77
+ logger.error("Upload rejected for file '%s' (%s)", name, content_type)
78
+ return None
79
+ return records[0]
80
+
81
+ @staticmethod
82
+ async def get_file(
83
+ context: ModuleContext,
84
+ file_id: str,
85
+ file_context: Context = Context.MISSIONS,
86
+ *,
87
+ include_content: bool = True,
88
+ ) -> FilesystemRecord:
89
+ """Retrieve a file by ID, with its content by default.
90
+
91
+ Args:
92
+ context: Module context containing the filesystem strategy
93
+ file_id: Unique identifier for the file
94
+ file_context: The owner context to look the file up in
95
+ include_content: Whether to include file content in the response
96
+
97
+ Returns:
98
+ File object with metadata and optionally content
99
+
100
+ Raises:
101
+ FilesystemServiceError: If file retrieval fails
102
+ """
103
+ return await context.filesystem.get_file(file_id, context=file_context, include_content=include_content)
104
+
105
+ @staticmethod
106
+ async def get_files(
107
+ context: ModuleContext,
108
+ filters: FileFilter,
109
+ *,
110
+ include_content: bool = False,
111
+ ) -> list[FilesystemRecord]:
112
+ """List files matching the given filters.
113
+
114
+ Args:
115
+ context: Module context containing the filesystem strategy
116
+ filters: Filter criteria for the files
117
+ include_content: Whether to include file content in the response
118
+
119
+ Returns:
120
+ Matching file records, empty when the lookup fails.
121
+ """
122
+ try:
123
+ records, _total = await context.filesystem.get_files(filters, include_content=include_content)
124
+ except Exception:
125
+ logger.exception("Failed to list files")
126
+ return []
127
+ return records
128
+
129
+ @staticmethod
130
+ async def delete_file(
131
+ context: ModuleContext,
132
+ file_id: str,
133
+ file_context: Context = Context.MISSIONS,
134
+ *,
135
+ permanent: bool = False,
136
+ ) -> bool:
137
+ """Delete a file.
138
+
139
+ Args:
140
+ context: Module context containing the filesystem strategy
141
+ file_id: Unique identifier for the file
142
+ file_context: The owner context to look the file up in
143
+ permanent: Whether to permanently delete the file
144
+
145
+ Returns:
146
+ True when the file was deleted.
147
+ """
148
+ try:
149
+ results, _deleted, _failed = await context.filesystem.delete_files(
150
+ FileFilter(context=file_context, file_ids=[file_id]),
151
+ permanent=permanent,
152
+ )
153
+ except Exception:
154
+ logger.exception("Failed to delete file '%s'", file_id)
155
+ return False
156
+ return results.get(file_id, False)
157
+
158
+ @staticmethod
159
+ async def resolve_files(
160
+ context: ModuleContext,
161
+ files: list[FileMetadata],
162
+ file_context: Context = Context.MISSIONS,
163
+ ) -> list[FileMetadata]:
164
+ """Backfill empty fields from what the filesystem service holds.
165
+
166
+ A setup form may submit little more than an id; the persisted entry has to stay
167
+ displayable, so anything the caller left empty is filled from the stored record.
168
+ A file the service cannot return is kept as submitted rather than dropped.
169
+
170
+ Args:
171
+ context: Module context containing the filesystem strategy
172
+ files: The files as submitted
173
+ file_context: The owner context the files live in; setup-time uploads are
174
+ scoped to the setup, not the mission
175
+
176
+ Returns:
177
+ The files, with empty fields filled in where the service could resolve them.
178
+ """
179
+ resolved: list[FileMetadata] = []
180
+ for file in files:
181
+ try:
182
+ record = await context.filesystem.get_file(file.id, context=file_context, include_content=False)
183
+ except Exception:
184
+ logger.warning("Could not resolve file '%s'; keeping it as submitted", file.id, exc_info=True)
185
+ resolved.append(file)
186
+ continue
187
+ resolved.append(
188
+ file.model_copy(
189
+ update={
190
+ "name": file.name or record.name,
191
+ "type": file.type if file.type is not FileType.UNSPECIFIED else record.type,
192
+ "content_type": file.content_type or record.content_type,
193
+ "size_bytes": file.size_bytes or record.size_bytes,
194
+ "file_url": file.file_url or record.file_url,
195
+ }
196
+ )
197
+ )
198
+ return resolved
199
+
200
+ @staticmethod
201
+ async def set_visibility(context: ModuleContext, file_id: str, visibility: Visibility) -> FilesystemRecord:
202
+ """Change the read-access scope of an already uploaded file.
203
+
204
+ Visibility is otherwise write-once at upload time, so this is the only way to
205
+ widen or narrow access to a file the module has already produced.
206
+
207
+ Args:
208
+ context: Module context containing the filesystem strategy
209
+ file_id: Unique identifier for the file
210
+ visibility: The new read-access scope; UNSPECIFIED leaves it unchanged
211
+
212
+ Returns:
213
+ The updated file record.
214
+ """
215
+ return await context.filesystem.update_file(file_id, visibility=visibility)
@@ -1,15 +1,43 @@
1
1
  """Data models for gRPC server configurations."""
2
2
 
3
+ from enum import Enum
3
4
  from pathlib import Path
4
5
  from typing import Any
5
6
 
7
+ import grpc
6
8
  from pydantic import BaseModel, Field, ValidationInfo, field_validator
7
9
 
8
10
  from digitalkin.grpc_servers.exceptions import ConfigurationError, SecurityError
9
- from digitalkin.models.settings.client.client import get_client_settings
10
- from digitalkin.models.settings.utils.channel import ControlFlow, GrpcCompression, SecurityMode
11
+ from digitalkin.models.settings.grpc_client import get_grpc_channel_settings, get_grpc_retry_settings
12
+ from digitalkin.models.settings.utils.channel import ControlFlow, SecurityMode
11
13
 
12
- __all__ = ["ChannelConfig", "ClientConfig", "ClientCredentials", "GrpcCompression", "RetryPolicy"]
14
+
15
+ class GrpcCompression(str, Enum):
16
+ """gRPC compression algorithm.
17
+
18
+ Attributes:
19
+ NONE: No compression
20
+ GZIP: Gzip compression
21
+ DEFLATE: Deflate compression
22
+ """
23
+
24
+ NONE = "none"
25
+ GZIP = "gzip"
26
+ DEFLATE = "deflate"
27
+
28
+ def to_grpc(self) -> grpc.Compression:
29
+ """Convert to grpc.Compression enum.
30
+
31
+ Returns:
32
+ The corresponding grpc.Compression value.
33
+ """
34
+ match self:
35
+ case GrpcCompression.NONE:
36
+ return grpc.Compression.NoCompression
37
+ case GrpcCompression.GZIP:
38
+ return grpc.Compression.Gzip
39
+ case GrpcCompression.DEFLATE:
40
+ return grpc.Compression.Deflate
13
41
 
14
42
 
15
43
  class RetryPolicy(BaseModel):
@@ -54,9 +82,9 @@ class RetryPolicy(BaseModel):
54
82
  """Build a retry policy with backoff values sourced from the environment.
55
83
 
56
84
  Returns:
57
- Retry policy populated from ``GrpcClientRetrySettings``.
85
+ Retry policy populated from ``GrpcRetrySettings``.
58
86
  """
59
- settings = get_client_settings().retry
87
+ settings = get_grpc_retry_settings()
60
88
  return cls(
61
89
  max_attempts=settings.max_attempts,
62
90
  initial_backoff=settings.initial_backoff,
@@ -177,13 +205,9 @@ class ChannelConfig(BaseModel):
177
205
  class ClientConfig(ChannelConfig):
178
206
  """Base configuration for gRPC clients.
179
207
 
180
- Every default is sourced from ``ClientSettings`` (env prefixes ``CLIENT_``,
181
- ``CLIENT_CHANNEL_``, ``CLIENT_GRPC_``), so a deployment configures its
182
- clients through the environment and only overrides per-target values here.
183
-
184
208
  Attributes:
185
- host: Host address the client dials
186
- port: Port the client dials
209
+ host: Host address to bind the client to
210
+ port: Port to listen on
187
211
  mode: Client operation mode (sync/async)
188
212
  security: Security mode (secure/insecure)
189
213
  credentials: Client credentials for secure mode
@@ -192,28 +216,13 @@ class ClientConfig(ChannelConfig):
192
216
  compression: gRPC compression algorithm for channel-level compression
193
217
  """
194
218
 
195
- host: str = Field(
196
- default_factory=lambda: get_client_settings().channel.host,
197
- description="Host address the client dials",
198
- )
199
- port: int = Field(default_factory=lambda: get_client_settings().channel.port, description="Port the client dials")
200
- mode: ControlFlow = Field(
201
- default_factory=lambda: get_client_settings().channel.communication_mode,
202
- description="Client operation mode (sync/async)",
203
- )
204
- security: SecurityMode = Field(
205
- default_factory=lambda: get_client_settings().channel.security,
206
- description="Security mode (secure/insecure)",
207
- )
208
219
  credentials: ClientCredentials | None = Field(None, description="Client credentials for secure mode")
209
220
  retry_policy: RetryPolicy = Field(
210
221
  default_factory=RetryPolicy.from_settings, description="Retry policy for failed RPCs"
211
222
  )
212
- compression: GrpcCompression = Field(
213
- default_factory=lambda: get_client_settings().grpc.compression, description="gRPC compression algorithm"
214
- )
223
+ compression: GrpcCompression = Field(GrpcCompression.GZIP, description="gRPC compression algorithm")
215
224
  channel_options: list[tuple[str, Any]] = Field(
216
- default_factory=lambda: get_client_settings().grpc.options,
225
+ default_factory=lambda: get_grpc_channel_settings().to_channel_options(),
217
226
  description="Resilient gRPC channel options with DNS re-resolution, keepalive, and retries",
218
227
  )
219
228