digitalkin 1.0.0.dev20__tar.gz → 1.0.0.dev21__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.0.dev20 → digitalkin-1.0.0.dev21}/PKG-INFO +1 -1
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/pyproject.toml +1 -1
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/__version__.py +1 -1
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/community/agno/hitl.py +1 -1
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/exceptions.py +4 -0
- digitalkin-1.0.0.dev21/src/digitalkin/grpc_servers/interceptors/permission.py +103 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +2 -1
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +4 -1
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/modules/_base_module.py +35 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/setup/grpc_setup.py +4 -1
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/storage/grpc_storage.py +41 -1
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin.egg-info/PKG-INFO +1 -1
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin.egg-info/SOURCES.txt +1 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/LICENSE +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/README.md +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/mock/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/mock/mock_pb2.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/server_async_insecure.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/server_async_secure.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/server_sync_insecure.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/server_sync_secure.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/bench_module/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/bench_module/echo_module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/bench_module/models/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/bench_module/models/input.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/bench_module/models/output.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/bench_module/models/secret.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/bench_module/models/setup.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/bench_module/server.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/bench_module/triggers/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/bench_module/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/modules/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/modules/archetype_with_tools_module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/modules/cpu_intensive_module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/modules/dynamic_setup_module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/modules/minimal_llm_module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/modules/text_transform_module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/monitoring/tests/test_metrics.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/redis_demo/client.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/redis_demo/echo_module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/redis_demo/models/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/redis_demo/models/input.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/redis_demo/models/output.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/redis_demo/models/secret.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/redis_demo/models/setup.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/redis_demo/server.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/redis_demo/triggers/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/redis_demo/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/services/filesystem_module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/services/storage_module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/setup.cfg +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/community/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/community/agno/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/community/agno/agno_adapter.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/community/agno/agui_tools.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/community/agno/models.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/common/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/common/factories.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/exceptions.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/job_manager/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/profiling/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/profiling/step_timer.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/profiling/task_profiler.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/resilience/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/resilience/bulkhead.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/module_runner.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/redis/proto_streams.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/redis/redis_client.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/redis/redis_signal.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/redis/redis_state.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/task_executor.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/task_session.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/exceptions.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/_base_server.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/gateway_servicer.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/interceptors/request_ids.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/m2m_call_registry.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/module_server.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/module_servicer.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/stream_registry.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/stream_session.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/logger.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/mixins/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/mixins/agui_mixin.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/mixins/base_mixin.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/mixins/cost_mixin.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/mixins/file_history_mixin.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/mixins/logger_mixin.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/mixins/storage_mixin.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/core/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/core/job_manager_models.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/core/redis.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/core/task_monitor.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/events/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/events/agent_events.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/grpc_servers/models.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/grpc_servers/stream_error_codes.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/grpc_servers/types.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/module/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/module/ag_ui.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/module/base_types.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/module/module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/module/module_context.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/module/module_types.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/module/request_metadata.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/module/select_schema.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/module/setup_types.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/module/tool_cache.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/module/tool_reference.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/module/utility.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/services/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/services/cost.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/services/registry.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/services/services.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/services/storage.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/gateway.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/grpc_client.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/log.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/profiling.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/queue.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/redis.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/resilience.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/server/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/server/channel.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/server/grpc.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/server/server.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/server/servicer.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/task_manager.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/settings/utils/channel.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/modules/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/modules/archetype_module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/modules/tool_module.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/modules/trigger_handler.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/modules/triggers/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/py.typed +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/base_strategy.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/communication/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/communication/communication_strategy.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/communication/default_communication.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/communication/exceptions.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/communication/grpc_communication.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/cost/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/cost/cost_strategy.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/cost/default_cost.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/cost/exceptions.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/cost/grpc_cost.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/filesystem/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/filesystem/exceptions.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/filesystem/filesystem_strategy.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/filesystem/grpc_filesystem.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/identity/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/identity/default_identity.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/identity/identity_strategy.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/registry/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/registry/default_registry.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/registry/exceptions.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/registry/grpc_registry.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/registry/registry_models.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/registry/registry_strategy.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/services_config.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/services_models.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/setup/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/setup/default_setup.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/setup/exceptions.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/setup/setup_strategy.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/storage/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/storage/default_storage.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/storage/exceptions.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/storage/storage_strategy.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/task_manager/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/task_manager/exceptions.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/user_profile/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/user_profile/default_user_profile.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/user_profile/exceptions.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/user_profile/grpc_user_profile.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/user_profile/user_profile_strategy.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/utils/arg_parser.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/utils/conditional_schema.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/utils/development_mode_action.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/utils/exceptions.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/utils/llm_ready_schema.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/utils/package_discover.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/utils/proto_utils.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/utils/schema_splitter.py +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin.egg-info/dependency_links.txt +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin.egg-info/requires.txt +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin.egg-info/top_level.txt +0 -0
- {digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/tests/test_exceptions.py +0 -0
|
@@ -611,7 +611,7 @@ class AgnoHitlRunner:
|
|
|
611
611
|
stream: Any,
|
|
612
612
|
send: Callable[[BaseAgentRunEvent], Coroutine[Any, Any, None]],
|
|
613
613
|
thread_id: str,
|
|
614
|
-
run_output_cls: type,
|
|
614
|
+
run_output_cls: type[RunOutput],
|
|
615
615
|
) -> PauseInfo | None:
|
|
616
616
|
"""Drain an Agno stream, forward events, persist on pause.
|
|
617
617
|
|
|
@@ -19,6 +19,10 @@ class SecurityError(ServerError):
|
|
|
19
19
|
"""Error related to security configuration."""
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
class PermissionDeniedError(ServerError):
|
|
23
|
+
"""Remote service rejected the call with gRPC PERMISSION_DENIED."""
|
|
24
|
+
|
|
25
|
+
|
|
22
26
|
class ServerStateError(ServerError):
|
|
23
27
|
"""Error related to server state (e.g., already started, not started)."""
|
|
24
28
|
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Client-side permission middleware for gRPC service-data access.
|
|
2
|
+
|
|
3
|
+
A single cross-cutting interceptor: any unary call a backend rejects with
|
|
4
|
+
``PERMISSION_DENIED`` surfaces as :class:`PermissionDeniedError`, so callers
|
|
5
|
+
never handle permission per service. Attached on every channel, it covers all
|
|
6
|
+
data services and module-to-module calls uniformly.
|
|
7
|
+
|
|
8
|
+
The interceptor *returns* a terminal denied call rather than raising: raising a
|
|
9
|
+
non-``AioRpcError`` from an aio interceptor leaks into the intercepted call's
|
|
10
|
+
``__del__`` (grpc only swallows ``AioRpcError``/``CancelledError`` there), so we
|
|
11
|
+
mirror grpc's own ``UnaryUnaryCallResponse`` pattern and raise from ``__await__``.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from typing import TYPE_CHECKING, Any
|
|
17
|
+
|
|
18
|
+
import grpc
|
|
19
|
+
import grpc.aio
|
|
20
|
+
|
|
21
|
+
from digitalkin.grpc_servers.exceptions import PermissionDeniedError
|
|
22
|
+
from digitalkin.logger import logger
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from collections.abc import Awaitable, Callable
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class _DeniedUnaryUnaryCall(grpc.aio.UnaryUnaryCall):
|
|
29
|
+
"""A finished unary call that raises ``PermissionDeniedError`` when awaited."""
|
|
30
|
+
|
|
31
|
+
def __init__(self, method: str, details: str) -> None:
|
|
32
|
+
self._message = f"[{method}] {details or 'permission denied'}"
|
|
33
|
+
self._details = details
|
|
34
|
+
|
|
35
|
+
def cancel(self) -> bool: # noqa: PLR6301
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
def cancelled(self) -> bool: # noqa: PLR6301
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
def done(self) -> bool: # noqa: PLR6301
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
def add_done_callback(self, unused_callback: Any) -> None:
|
|
45
|
+
"""No-op: the call is already finished.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
unused_callback: Ignored; present to satisfy the call interface.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
def time_remaining(self) -> float | None: # noqa: PLR6301
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
async def initial_metadata(self) -> grpc.aio.Metadata: # noqa: PLR6301
|
|
55
|
+
return grpc.aio.Metadata()
|
|
56
|
+
|
|
57
|
+
async def trailing_metadata(self) -> grpc.aio.Metadata: # noqa: PLR6301
|
|
58
|
+
return grpc.aio.Metadata()
|
|
59
|
+
|
|
60
|
+
async def code(self) -> grpc.StatusCode: # noqa: PLR6301
|
|
61
|
+
return grpc.StatusCode.PERMISSION_DENIED
|
|
62
|
+
|
|
63
|
+
async def details(self) -> str:
|
|
64
|
+
return self._details
|
|
65
|
+
|
|
66
|
+
async def debug_error_string(self) -> None: # noqa: PLR6301
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
async def wait_for_connection(self) -> None:
|
|
70
|
+
"""No-op: the call already resolved to a permission denial."""
|
|
71
|
+
|
|
72
|
+
def __await__(self) -> Any:
|
|
73
|
+
raise PermissionDeniedError(self._message)
|
|
74
|
+
yield # unreachable; marks this method a generator so it is awaitable
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class PermissionClientInterceptor(grpc.aio.UnaryUnaryClientInterceptor):
|
|
78
|
+
"""Map a ``PERMISSION_DENIED`` unary reply to ``PermissionDeniedError``."""
|
|
79
|
+
|
|
80
|
+
async def intercept_unary_unary( # noqa: PLR6301
|
|
81
|
+
self,
|
|
82
|
+
continuation: Callable[[grpc.aio.ClientCallDetails, Any], Awaitable[Any]],
|
|
83
|
+
client_call_details: grpc.aio.ClientCallDetails,
|
|
84
|
+
request: Any,
|
|
85
|
+
) -> Any:
|
|
86
|
+
"""Return a denied call on PERMISSION_DENIED, else pass the real call through.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
continuation: Downstream call continuation.
|
|
90
|
+
client_call_details: Original call details.
|
|
91
|
+
request: Request message.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
The downstream call, or a terminal call raising PermissionDeniedError on await.
|
|
95
|
+
"""
|
|
96
|
+
call = await continuation(client_call_details, request)
|
|
97
|
+
if await call.code() == grpc.StatusCode.PERMISSION_DENIED:
|
|
98
|
+
method = client_call_details.method
|
|
99
|
+
method_name = method.decode() if isinstance(method, bytes) else method
|
|
100
|
+
details = await call.details()
|
|
101
|
+
logger.warning("permission denied on %s: %s", method_name, details or "")
|
|
102
|
+
return _DeniedUnaryUnaryCall(method_name, details)
|
|
103
|
+
return call
|
|
@@ -16,6 +16,7 @@ import grpc.aio
|
|
|
16
16
|
|
|
17
17
|
from digitalkin.core.resilience.bulkhead import Bulkhead
|
|
18
18
|
from digitalkin.grpc_servers.exceptions import CircuitOpenError, ServerError
|
|
19
|
+
from digitalkin.grpc_servers.interceptors.permission import PermissionClientInterceptor
|
|
19
20
|
from digitalkin.grpc_servers.interceptors.request_ids import RequestIdClientInterceptor
|
|
20
21
|
from digitalkin.grpc_servers.utils.circuit_breaker import CircuitBreaker
|
|
21
22
|
from digitalkin.logger import logger
|
|
@@ -103,7 +104,7 @@ class GrpcClientWrapper:
|
|
|
103
104
|
|
|
104
105
|
credentials = self._build_channel_credentials(config)
|
|
105
106
|
grpc_compression = config.compression.to_grpc()
|
|
106
|
-
interceptors = [RequestIdClientInterceptor()]
|
|
107
|
+
interceptors = [RequestIdClientInterceptor(), PermissionClientInterceptor()]
|
|
107
108
|
if credentials is not None:
|
|
108
109
|
channel = grpc.aio.secure_channel(
|
|
109
110
|
config.address,
|
|
@@ -4,7 +4,7 @@ from collections.abc import AsyncGenerator
|
|
|
4
4
|
from contextlib import asynccontextmanager
|
|
5
5
|
from typing import Any
|
|
6
6
|
|
|
7
|
-
from digitalkin.grpc_servers.exceptions import ServerError
|
|
7
|
+
from digitalkin.grpc_servers.exceptions import PermissionDeniedError, ServerError
|
|
8
8
|
from digitalkin.logger import logger
|
|
9
9
|
|
|
10
10
|
|
|
@@ -28,6 +28,7 @@ class GrpcErrorHandlerMixin:
|
|
|
28
28
|
Context for the operation.
|
|
29
29
|
|
|
30
30
|
Raises:
|
|
31
|
+
PermissionDeniedError: Re-raised as-is so the authz status is never masked.
|
|
31
32
|
ServerError: For gRPC-related errors.
|
|
32
33
|
service_error_class: For service-specific errors if provided.
|
|
33
34
|
"""
|
|
@@ -36,6 +37,8 @@ class GrpcErrorHandlerMixin:
|
|
|
36
37
|
|
|
37
38
|
try:
|
|
38
39
|
yield
|
|
40
|
+
except PermissionDeniedError:
|
|
41
|
+
raise
|
|
39
42
|
except service_error_class as e:
|
|
40
43
|
# Re-raise service-specific errors as-is
|
|
41
44
|
msg = f"{service_error_class.__name__} in {operation}: {e}"
|
|
@@ -7,6 +7,7 @@ from abc import ABC, abstractmethod
|
|
|
7
7
|
from collections.abc import Callable, Coroutine
|
|
8
8
|
from typing import Any, ClassVar, Generic
|
|
9
9
|
|
|
10
|
+
from digitalkin.grpc_servers.exceptions import PermissionDeniedError
|
|
10
11
|
from digitalkin.grpc_servers.utils.utility_schema_extender import UtilitySchemaExtender
|
|
11
12
|
from digitalkin.logger import logger
|
|
12
13
|
from digitalkin.models.module.module import ModuleCodeModel, ModuleStatus
|
|
@@ -548,6 +549,10 @@ class BaseModule( # Module SDK base class requires many public methods # noqa:
|
|
|
548
549
|
self._status = ModuleStatus.CANCELLED
|
|
549
550
|
logger.info("Module %s cancelled", self.name, extra=self.context.session.current_ids())
|
|
550
551
|
raise
|
|
552
|
+
except PermissionDeniedError as e:
|
|
553
|
+
self._status = ModuleStatus.FAILED
|
|
554
|
+
logger.warning("Permission denied in module %s: %s", self.name, e, extra=self.context.session.current_ids())
|
|
555
|
+
await self._notify_permission_denied(self.context.callbacks.send_message, e)
|
|
551
556
|
except Exception as e:
|
|
552
557
|
self._status = ModuleStatus.FAILED
|
|
553
558
|
logger.exception("Error inside module %s", self.name, extra=self.context.session.current_ids())
|
|
@@ -564,6 +569,28 @@ class BaseModule( # Module SDK base class requires many public methods # noqa:
|
|
|
564
569
|
else:
|
|
565
570
|
self._status = ModuleStatus.STOPPING
|
|
566
571
|
|
|
572
|
+
async def _notify_permission_denied(
|
|
573
|
+
self,
|
|
574
|
+
callback: Callable[..., Coroutine[Any, Any, None]],
|
|
575
|
+
e: PermissionDeniedError,
|
|
576
|
+
) -> None:
|
|
577
|
+
"""Send a PermissionDenied notification to the user via the callback.
|
|
578
|
+
|
|
579
|
+
Args:
|
|
580
|
+
callback: The output callback installed on the module context.
|
|
581
|
+
e: The permission-denied error raised by a service call.
|
|
582
|
+
"""
|
|
583
|
+
try:
|
|
584
|
+
await callback(
|
|
585
|
+
ModuleCodeModel(
|
|
586
|
+
code="PermissionDenied",
|
|
587
|
+
short_description="Permission denied",
|
|
588
|
+
message=str(e),
|
|
589
|
+
)
|
|
590
|
+
)
|
|
591
|
+
except Exception:
|
|
592
|
+
logger.exception("Failed to send permission-denied callback", extra=self.context.session.current_ids())
|
|
593
|
+
|
|
567
594
|
async def prepare(
|
|
568
595
|
self,
|
|
569
596
|
setup_data: SetupModelT,
|
|
@@ -623,6 +650,14 @@ class BaseModule( # Module SDK base class requires many public methods # noqa:
|
|
|
623
650
|
try:
|
|
624
651
|
await self.prepare(setup_data, callback)
|
|
625
652
|
timer.mark("prepare")
|
|
653
|
+
except PermissionDeniedError as e:
|
|
654
|
+
self._status = ModuleStatus.FAILED
|
|
655
|
+
logger.warning("Permission denied initializing module: %s", e, extra=self.context.session.current_ids())
|
|
656
|
+
await self._notify_permission_denied(callback, e)
|
|
657
|
+
if done_callback is not None:
|
|
658
|
+
await done_callback(None)
|
|
659
|
+
await self.stop()
|
|
660
|
+
return
|
|
626
661
|
except Exception as e:
|
|
627
662
|
self._status = ModuleStatus.FAILED
|
|
628
663
|
short_description = "Error initializing module"
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/setup/grpc_setup.py
RENAMED
|
@@ -12,7 +12,7 @@ from agentic_mesh_protocol.setup.v1 import (
|
|
|
12
12
|
from google.protobuf.struct_pb2 import Struct
|
|
13
13
|
from pydantic import ValidationError
|
|
14
14
|
|
|
15
|
-
from digitalkin.grpc_servers.exceptions import ServerError
|
|
15
|
+
from digitalkin.grpc_servers.exceptions import PermissionDeniedError, ServerError
|
|
16
16
|
from digitalkin.grpc_servers.utils.grpc_client_wrapper import GrpcClientWrapper
|
|
17
17
|
from digitalkin.logger import logger
|
|
18
18
|
from digitalkin.models.grpc_servers.models import ClientConfig
|
|
@@ -59,12 +59,15 @@ class GrpcSetup(SetupStrategy, GrpcClientWrapper):
|
|
|
59
59
|
Allow error handling in context.
|
|
60
60
|
|
|
61
61
|
Raises:
|
|
62
|
+
PermissionDeniedError: Service rejected the call with PERMISSION_DENIED.
|
|
62
63
|
ValueError: Pydantic model validation failed - input data is malformed.
|
|
63
64
|
ServerError: gRPC communication failed - remote service returned error or is unreachable.
|
|
64
65
|
SetupServiceError: Unexpected error during setup operation - includes connection/timeout issues.
|
|
65
66
|
"""
|
|
66
67
|
try:
|
|
67
68
|
yield
|
|
69
|
+
except PermissionDeniedError:
|
|
70
|
+
raise
|
|
68
71
|
except ValidationError as e:
|
|
69
72
|
msg = f"Validation failed for {operation}: {e}"
|
|
70
73
|
logger.error(
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/services/storage/grpc_storage.py
RENAMED
|
@@ -4,7 +4,7 @@ from agentic_mesh_protocol.storage.v1 import data_pb2, storage_service_pb2_grpc
|
|
|
4
4
|
from google.protobuf.struct_pb2 import Struct
|
|
5
5
|
from pydantic import BaseModel
|
|
6
6
|
|
|
7
|
-
from digitalkin.grpc_servers.exceptions import CircuitOpenError
|
|
7
|
+
from digitalkin.grpc_servers.exceptions import CircuitOpenError, PermissionDeniedError
|
|
8
8
|
from digitalkin.grpc_servers.utils.grpc_client_wrapper import GrpcClientWrapper
|
|
9
9
|
from digitalkin.logger import logger
|
|
10
10
|
from digitalkin.models.grpc_servers.models import ClientConfig
|
|
@@ -84,6 +84,7 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
84
84
|
StorageRecord: The corresponding record
|
|
85
85
|
|
|
86
86
|
Raises:
|
|
87
|
+
PermissionDeniedError: If the service rejects the call with PERMISSION_DENIED.
|
|
87
88
|
StorageServiceError: If there is an error while storing the record
|
|
88
89
|
"""
|
|
89
90
|
logger.debug("debug:_store collection=%s id=%s", record.collection, record.record_id)
|
|
@@ -99,6 +100,10 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
99
100
|
)
|
|
100
101
|
resp = await self.exec_grpc_query("StoreRecord", req)
|
|
101
102
|
return self._build_record_from_proto(resp.stored_data)
|
|
103
|
+
except PermissionDeniedError:
|
|
104
|
+
# TODO(validate): remove after prod validation
|
|
105
|
+
logger.warning("[VALIDATE PD1] storage StoreRecord permission denied")
|
|
106
|
+
raise
|
|
102
107
|
except Exception as e:
|
|
103
108
|
if self._is_circuit_open(e):
|
|
104
109
|
logger.debug("gRPC StoreRecord skipped (circuit open) for %s:%s", record.collection, record.record_id)
|
|
@@ -111,6 +116,9 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
111
116
|
|
|
112
117
|
Returns:
|
|
113
118
|
StorageData: The record
|
|
119
|
+
|
|
120
|
+
Raises:
|
|
121
|
+
PermissionDeniedError: If the service rejects the call with PERMISSION_DENIED.
|
|
114
122
|
"""
|
|
115
123
|
logger.debug("debug:_read context=%s collection=%s id=%s", context, collection, record_id)
|
|
116
124
|
try:
|
|
@@ -121,6 +129,10 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
121
129
|
)
|
|
122
130
|
resp = await self.exec_grpc_query("ReadRecord", req)
|
|
123
131
|
return self._build_record_from_proto(resp.stored_data)
|
|
132
|
+
except PermissionDeniedError:
|
|
133
|
+
# TODO(validate): remove after prod validation
|
|
134
|
+
logger.warning("[VALIDATE PD1] storage ReadRecord permission denied")
|
|
135
|
+
raise
|
|
124
136
|
except Exception as e:
|
|
125
137
|
if self._is_circuit_open(e):
|
|
126
138
|
logger.debug("gRPC ReadRecord skipped (circuit open) for %s:%s", collection, record_id)
|
|
@@ -139,6 +151,9 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
139
151
|
|
|
140
152
|
Returns:
|
|
141
153
|
StorageRecord: The updated record, or None on failure.
|
|
154
|
+
|
|
155
|
+
Raises:
|
|
156
|
+
PermissionDeniedError: If the service rejects the call with PERMISSION_DENIED.
|
|
142
157
|
"""
|
|
143
158
|
logger.debug("debug:_update context=%s collection=%s id=%s", context, collection, record_id)
|
|
144
159
|
try:
|
|
@@ -152,6 +167,10 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
152
167
|
)
|
|
153
168
|
resp = await self.exec_grpc_query("UpdateRecord", req)
|
|
154
169
|
return self._build_record_from_proto(resp.stored_data)
|
|
170
|
+
except PermissionDeniedError:
|
|
171
|
+
# TODO(validate): remove after prod validation
|
|
172
|
+
logger.warning("[VALIDATE PD1] storage UpdateRecord permission denied")
|
|
173
|
+
raise
|
|
155
174
|
except Exception as e:
|
|
156
175
|
if self._is_circuit_open(e):
|
|
157
176
|
logger.debug("gRPC UpdateRecord skipped (circuit open) for %s:%s", collection, record_id)
|
|
@@ -164,6 +183,9 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
164
183
|
|
|
165
184
|
Returns:
|
|
166
185
|
bool: True if the record was deleted, False otherwise.
|
|
186
|
+
|
|
187
|
+
Raises:
|
|
188
|
+
PermissionDeniedError: If the service rejects the call with PERMISSION_DENIED.
|
|
167
189
|
"""
|
|
168
190
|
logger.debug("debug:_remove context=%s collection=%s id=%s", context, collection, record_id)
|
|
169
191
|
try:
|
|
@@ -173,6 +195,10 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
173
195
|
record_id=record_id,
|
|
174
196
|
)
|
|
175
197
|
await self.exec_grpc_query("RemoveRecord", req)
|
|
198
|
+
except PermissionDeniedError:
|
|
199
|
+
# TODO(validate): remove after prod validation
|
|
200
|
+
logger.warning("[VALIDATE PD1] storage RemoveRecord permission denied")
|
|
201
|
+
raise
|
|
176
202
|
except Exception as e:
|
|
177
203
|
if self._is_circuit_open(e):
|
|
178
204
|
logger.debug("gRPC RemoveRecord skipped (circuit open) for %s:%s", collection, record_id)
|
|
@@ -186,6 +212,9 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
186
212
|
|
|
187
213
|
Returns:
|
|
188
214
|
list[StorageRecord]: The records found, or an empty list on failure.
|
|
215
|
+
|
|
216
|
+
Raises:
|
|
217
|
+
PermissionDeniedError: If the service rejects the call with PERMISSION_DENIED.
|
|
189
218
|
"""
|
|
190
219
|
logger.debug("debug:_list context=%s collection=%s", context, collection)
|
|
191
220
|
try:
|
|
@@ -195,6 +224,10 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
195
224
|
)
|
|
196
225
|
resp = await self.exec_grpc_query("ListRecords", req)
|
|
197
226
|
return [self._build_record_from_proto(r) for r in resp.records]
|
|
227
|
+
except PermissionDeniedError:
|
|
228
|
+
# TODO(validate): remove after prod validation
|
|
229
|
+
logger.warning("[VALIDATE PD1] storage ListRecords permission denied")
|
|
230
|
+
raise
|
|
198
231
|
except Exception as e:
|
|
199
232
|
if self._is_circuit_open(e):
|
|
200
233
|
logger.debug("gRPC ListRecords skipped (circuit open) for %s", collection)
|
|
@@ -207,6 +240,9 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
207
240
|
|
|
208
241
|
Returns:
|
|
209
242
|
bool: True if the collection was removed, False otherwise.
|
|
243
|
+
|
|
244
|
+
Raises:
|
|
245
|
+
PermissionDeniedError: If the service rejects the call with PERMISSION_DENIED.
|
|
210
246
|
"""
|
|
211
247
|
try:
|
|
212
248
|
req = data_pb2.RemoveCollectionRequest(
|
|
@@ -214,6 +250,10 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
214
250
|
collection=collection,
|
|
215
251
|
)
|
|
216
252
|
await self.exec_grpc_query("RemoveCollection", req)
|
|
253
|
+
except PermissionDeniedError:
|
|
254
|
+
# TODO(validate): remove after prod validation
|
|
255
|
+
logger.warning("[VALIDATE PD1] storage RemoveCollection permission denied")
|
|
256
|
+
raise
|
|
217
257
|
except Exception as e:
|
|
218
258
|
if self._is_circuit_open(e):
|
|
219
259
|
logger.debug("gRPC RemoveCollection skipped (circuit open) for %s", collection)
|
|
@@ -95,6 +95,7 @@ src/digitalkin/grpc_servers/module_servicer.py
|
|
|
95
95
|
src/digitalkin/grpc_servers/stream_registry.py
|
|
96
96
|
src/digitalkin/grpc_servers/stream_session.py
|
|
97
97
|
src/digitalkin/grpc_servers/interceptors/__init__.py
|
|
98
|
+
src/digitalkin/grpc_servers/interceptors/permission.py
|
|
98
99
|
src/digitalkin/grpc_servers/interceptors/request_ids.py
|
|
99
100
|
src/digitalkin/grpc_servers/utils/__init__.py
|
|
100
101
|
src/digitalkin/grpc_servers/utils/circuit_breaker.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/mock/mock_pb2_grpc.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/server_async_insecure.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/server_async_secure.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/server_sync_insecure.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/base_server/server_sync_secure.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/bench_module/triggers/__init__.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/bench_module/triggers/message_trigger.py
RENAMED
|
File without changes
|
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/modules/archetype_with_tools_module.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/examples/redis_demo/triggers/message_trigger.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/community/agno/agno_adapter.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/community/agno/agui_tools.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/job_manager/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/profiling/step_timer.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/profiling/task_profiler.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/resilience/__init__.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/resilience/bulkhead.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/resilience/task_supervisor.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/module_runner.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/redis/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/task_executor.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev20 → digitalkin-1.0.0.dev21}/src/digitalkin/core/task_manager/task_session.py
RENAMED
|
File without changes
|
|
File without changes
|