digitalkin 1.0.4.dev5__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.
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/PKG-INFO +1 -1
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/services/filesystem_module.py +7 -6
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/pyproject.toml +44 -44
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/__version__.py +1 -1
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/action.py +1 -1
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/resilience/bulkhead.py +6 -5
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/redis/proto_streams.py +1 -1
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/_base_server.py +4 -4
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/module_server.py +3 -12
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/module_servicer.py +9 -5
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +3 -3
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +6 -6
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/file_history_mixin.py +4 -3
- digitalkin-1.0.4.dev6/src/digitalkin/mixins/filesystem_mixin.py +215 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/grpc_servers/models.py +37 -28
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/__init__.py +6 -0
- digitalkin-1.0.4.dev6/src/digitalkin/models/module/knowledge_files.py +87 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/services/__init__.py +4 -0
- digitalkin-1.0.4.dev6/src/digitalkin/models/services/filesystem.py +127 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/services/storage.py +3 -9
- digitalkin-1.0.4.dev6/src/digitalkin/models/settings/grpc_client.py +127 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/module.py +2 -17
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/profiling.py +1 -1
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/redis.py +1 -5
- digitalkin-1.0.4.dev6/src/digitalkin/models/settings/resilience.py +31 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/server/channel.py +3 -23
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/server/grpc.py +1 -1
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/server/server.py +2 -4
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/utils/channel.py +7 -45
- digitalkin-1.0.4.dev6/src/digitalkin/services/filesystem/__init__.py +19 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/filesystem/default_filesystem.py +24 -22
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/filesystem/filesystem_strategy.py +49 -49
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/filesystem/grpc_filesystem.py +18 -40
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/services_config.py +4 -16
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/development_mode_action.py +20 -12
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin.egg-info/PKG-INFO +1 -1
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin.egg-info/SOURCES.txt +3 -8
- digitalkin-1.0.4.dev5/src/digitalkin/mixins/filesystem_mixin.py +0 -46
- digitalkin-1.0.4.dev5/src/digitalkin/models/settings/certificate.py +0 -90
- digitalkin-1.0.4.dev5/src/digitalkin/models/settings/client/__init__.py +0 -1
- digitalkin-1.0.4.dev5/src/digitalkin/models/settings/client/channel.py +0 -68
- digitalkin-1.0.4.dev5/src/digitalkin/models/settings/client/circuit_breaker.py +0 -19
- digitalkin-1.0.4.dev5/src/digitalkin/models/settings/client/client.py +0 -55
- digitalkin-1.0.4.dev5/src/digitalkin/models/settings/client/grpc.py +0 -148
- digitalkin-1.0.4.dev5/src/digitalkin/models/settings/resilience.py +0 -61
- digitalkin-1.0.4.dev5/src/digitalkin/services/filesystem/__init__.py +0 -7
- digitalkin-1.0.4.dev5/src/digitalkin/utils/env_manager.py +0 -139
- digitalkin-1.0.4.dev5/src/digitalkin/utils/env_template.py +0 -233
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/LICENSE +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/README.md +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/base_server/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/base_server/mock/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/base_server/mock/mock_pb2.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/base_server/server_async_insecure.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/base_server/server_async_secure.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/base_server/server_sync_insecure.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/base_server/server_sync_secure.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/bench_module/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/bench_module/echo_module.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/bench_module/models/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/bench_module/models/input.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/bench_module/models/output.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/bench_module/models/secret.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/bench_module/models/setup.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/bench_module/server.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/bench_module/triggers/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/bench_module/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/modules/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/modules/archetype_with_tools_module.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/modules/cpu_intensive_module.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/modules/dynamic_setup_module.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/modules/minimal_llm_module.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/modules/text_transform_module.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/monitoring/tests/test_metrics.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/redis_demo/client.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/redis_demo/echo_module.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/redis_demo/models/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/redis_demo/models/input.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/redis_demo/models/output.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/redis_demo/models/secret.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/redis_demo/models/setup.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/redis_demo/server.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/redis_demo/triggers/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/redis_demo/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/examples/services/storage_module.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/setup.cfg +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/agno_adapter.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/agui_tools.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/hitl.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/models.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/module_toolkit.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/base.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/chat_history.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/defaults.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/base.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/kins/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/kins/action.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/kins/kit.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/loader/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/loader/action.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/loader/kit.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/services/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/services/action.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/services/kit.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/tools/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/tools/action.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/registry/tools/kit.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/community/agno/toolkits/user_profile.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/common/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/common/factories.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/job_manager/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/profiling/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/profiling/step_timer.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/profiling/task_profiler.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/resilience/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/module_runner.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/redis/redis_client.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/redis/redis_signal.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/redis/redis_state.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/task_executor.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/core/task_manager/task_session.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/gateway_servicer.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/interceptors/permission.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/interceptors/request_ids.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/m2m_call_registry.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/stream_registry.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/stream_session.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/logger.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/agui_mixin.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/base_mixin.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/cost_mixin.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/logger_mixin.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/mixins/storage_mixin.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/core/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/core/job_manager_models.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/core/redis.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/core/task_monitor.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/events/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/events/agent_events.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/grpc_servers/stream_error_codes.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/grpc_servers/types.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/ag_ui.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/base_types.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/loaded_tools.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/module.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/module_context.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/module_types.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/request_metadata.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/select_schema.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/setup_types.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/tool_cache.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/tool_reference.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/module/utility.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/services/cost.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/services/registry.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/services/services.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/gateway.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/log.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/queue.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/registry.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/server/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/server/servicer.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/task_manager.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/settings/utils/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/utils/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/_base_module.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/archetype_module.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/tool_module.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/trigger_handler.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/triggers/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/py.typed +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/base_strategy.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/communication/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/communication/communication_strategy.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/communication/default_communication.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/communication/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/communication/grpc_communication.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/cost/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/cost/cost_strategy.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/cost/default_cost.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/cost/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/cost/grpc_cost.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/filesystem/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/identity/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/identity/default_identity.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/identity/identity_strategy.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/registry/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/registry/default_registry.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/registry/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/registry/grpc_registry.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/registry/registry_models.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/registry/registry_strategy.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/secret/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/secret/default_secret.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/secret/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/secret/grpc_secret.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/secret/secret_strategy.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/services_models.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/setup/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/setup/default_setup.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/setup/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/setup/grpc_setup.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/setup/setup_strategy.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/storage/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/storage/default_storage.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/storage/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/storage/grpc_storage.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/storage/storage_strategy.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/task_manager/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/task_manager/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/user_profile/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/user_profile/default_user_profile.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/user_profile/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/user_profile/grpc_user_profile.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/services/user_profile/user_profile_strategy.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/__init__.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/arg_parser.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/conditional_schema.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/exceptions.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/json_structure.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/llm_ready_schema.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/package_discover.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/proto_utils.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/schema_splitter.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/utils/setup_content_validator.py +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin.egg-info/dependency_links.txt +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin.egg-info/requires.txt +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin.egg-info/top_level.txt +0 -0
- {digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/tests/test_exceptions.py +0 -0
|
@@ -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
|
|
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
|
-
|
|
122
|
+
type=FileType.DOCUMENT,
|
|
122
123
|
content_type="text/plain",
|
|
123
|
-
metadata={"
|
|
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(
|
|
180
|
+
filters=FileFilter(names=["example_output.txt"]),
|
|
180
181
|
)
|
|
181
182
|
for file in files:
|
|
182
|
-
await module.filesystem.update_file(file.id,
|
|
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.
|
|
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.
|
|
44
|
+
version = "1.0.4.dev6"
|
|
45
45
|
|
|
46
46
|
[project.optional-dependencies]
|
|
47
47
|
agno = [ "agno>=2.6" ]
|
|
@@ -208,15 +208,15 @@ version = "1.0.4.dev5"
|
|
|
208
208
|
]
|
|
209
209
|
|
|
210
210
|
ignore = [
|
|
211
|
-
"
|
|
212
|
-
"
|
|
213
|
-
"
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"
|
|
217
|
-
"
|
|
218
|
-
"
|
|
219
|
-
"
|
|
211
|
+
"any-type", # Allow typing.Any — gRPC stubs, callbacks, and dynamic APIs require it
|
|
212
|
+
"missing-trailing-comma", # Disable because of formatter incompatibility
|
|
213
|
+
"docstring-extraneous-exception", # Allow extraneous-exception in docstring
|
|
214
|
+
"unused-import", # Allow unused imports — used for availability checks
|
|
215
|
+
"invalid-function-name", # Allow PascalCase methods — gRPC servicer convention
|
|
216
|
+
"import-outside-top-level", # Allow lazy imports — needed to break circular dependencies
|
|
217
|
+
"bad-dunder-method-name", # Allow __get_pydantic_core_schema__ — Pydantic dunder hook
|
|
218
|
+
"hardcoded-password-string", # Hardcoded-password
|
|
219
|
+
"suspicious-pickle-import", # Allow pickle import
|
|
220
220
|
]
|
|
221
221
|
|
|
222
222
|
fixable = [ "ALL" ]
|
|
@@ -226,40 +226,40 @@ version = "1.0.4.dev5"
|
|
|
226
226
|
|
|
227
227
|
[tool.ruff.lint.per-file-ignores]
|
|
228
228
|
"tests/**/*.py" = [
|
|
229
|
-
"
|
|
230
|
-
"
|
|
231
|
-
"
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
"
|
|
235
|
-
"
|
|
236
|
-
"
|
|
237
|
-
"
|
|
238
|
-
"
|
|
239
|
-
"
|
|
240
|
-
"
|
|
241
|
-
"
|
|
242
|
-
"
|
|
243
|
-
"
|
|
244
|
-
"
|
|
245
|
-
"
|
|
246
|
-
"
|
|
247
|
-
"
|
|
248
|
-
"
|
|
249
|
-
"
|
|
250
|
-
"
|
|
251
|
-
"
|
|
252
|
-
"
|
|
253
|
-
"
|
|
254
|
-
"
|
|
255
|
-
"
|
|
256
|
-
"
|
|
257
|
-
"
|
|
258
|
-
"
|
|
259
|
-
"
|
|
260
|
-
"
|
|
261
|
-
"
|
|
262
|
-
"
|
|
229
|
+
"missing-type-function-argument",
|
|
230
|
+
"missing-type-args",
|
|
231
|
+
"missing-type-kwargs",
|
|
232
|
+
"missing-return-type-undocumented-public-function",
|
|
233
|
+
"any-type",
|
|
234
|
+
"unused-function-argument",
|
|
235
|
+
"unused-method-argument",
|
|
236
|
+
"complex-structure",
|
|
237
|
+
"undocumented-public-module",
|
|
238
|
+
"undocumented-public-class",
|
|
239
|
+
"undocumented-public-method",
|
|
240
|
+
"undocumented-public-function",
|
|
241
|
+
"undocumented-public-init",
|
|
242
|
+
"undocumented-param",
|
|
243
|
+
"docstring-missing-returns",
|
|
244
|
+
"docstring-missing-exception",
|
|
245
|
+
"line-too-long",
|
|
246
|
+
"commented-out-code",
|
|
247
|
+
"boolean-type-hint-positional-argument",
|
|
248
|
+
"boolean-default-value-positional-argument",
|
|
249
|
+
"logging-f-string",
|
|
250
|
+
"invalid-function-name",
|
|
251
|
+
"try-except-in-loop",
|
|
252
|
+
"import-private-name",
|
|
253
|
+
"too-many-return-statements",
|
|
254
|
+
"too-many-branches",
|
|
255
|
+
"too-many-locals",
|
|
256
|
+
"too-many-statements",
|
|
257
|
+
"too-many-nested-blocks",
|
|
258
|
+
"magic-value-comparison",
|
|
259
|
+
"no-self-use",
|
|
260
|
+
"assert",
|
|
261
|
+
"private-member-access",
|
|
262
|
+
"raise-vanilla-class",
|
|
263
263
|
]
|
|
264
264
|
|
|
265
265
|
[tool.ruff.lint.pylint]
|
|
@@ -147,7 +147,7 @@ class SearchAction(RegistryAction):
|
|
|
147
147
|
"tags": setup.tags,
|
|
148
148
|
"visibility": setup.visibility.value if setup.visibility else None,
|
|
149
149
|
"status": setup.status.value if setup.status else None,
|
|
150
|
-
"
|
|
150
|
+
"description": (setup.documentation or "")[: self._DOC_PREVIEW_CHARS],
|
|
151
151
|
}
|
|
152
152
|
# Only service setups carry a map. Omitting the key rather than rendering an empty
|
|
153
153
|
# one keeps the feature out of the tools and kins surfaces entirely.
|
|
@@ -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
|
|
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
|
-
#
|
|
65
|
-
#
|
|
66
|
-
|
|
67
|
-
max_concurrent =
|
|
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
|
-
``
|
|
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
|
-
|
|
262
|
-
|
|
263
|
-
|
|
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:
|
{digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/module_server.py
RENAMED
|
@@ -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
|
|
96
|
+
RuntimeError: If DIGITALKIN_REDIS_URL is not set.
|
|
106
97
|
"""
|
|
107
|
-
redis_url =
|
|
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)
|
{digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/module_servicer.py
RENAMED
|
@@ -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
|
|
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 =
|
|
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")
|
|
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("", "", "")
|
{digitalkin-1.0.4.dev5 → digitalkin-1.0.4.dev6}/src/digitalkin/grpc_servers/utils/circuit_breaker.py
RENAMED
|
@@ -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.
|
|
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
|
-
``
|
|
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 =
|
|
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.
|
|
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
|
|
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
|
-
|
|
273
|
-
eff_timeout = timeout if timeout is not None else
|
|
274
|
-
max_retries =
|
|
275
|
-
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.
|
|
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[
|
|
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:
|
|
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)
|