chalkcompute 2.3.3__tar.gz → 2.3.4__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.
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/PKG-INFO +1 -1
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/__init__.py +9 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/__init__.pyi +16 -0
- chalkcompute-2.3.4/chalkcompute/_artifact.py +352 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_cls.py +17 -11
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_container.py +13 -17
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_function.py +9 -6
- chalkcompute-2.3.4/chalkcompute/_gen/chalk/artifactstore/v1/service_pb2.py +131 -0
- chalkcompute-2.3.4/chalkcompute/_gen/chalk/artifactstore/v1/service_pb2.pyi +374 -0
- chalkcompute-2.3.4/chalkcompute/_gen/chalk/artifactstore/v1/service_pb2_grpc.py +354 -0
- chalkcompute-2.3.4/chalkcompute/_gen/chalk/artifactstore/v1/service_pb2_grpc.pyi +120 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/agent_pb2.py +6 -6
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/agent_pb2.pyi +10 -1
- chalkcompute-2.3.4/chalkcompute/_gen/chalk/container/v1/service_pb2.py +288 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/container/v1/service_pb2.pyi +42 -4
- chalkcompute-2.3.4/chalkcompute/_gen/chalk/sandbox/v1/runtime_service_pb2.py +72 -0
- chalkcompute-2.3.4/chalkcompute/_gen/chalk/sandbox/v1/runtime_service_pb2.pyi +170 -0
- chalkcompute-2.3.4/chalkcompute/_gen/chalk/sandbox/v1/runtime_service_pb2_grpc.py +82 -0
- chalkcompute-2.3.4/chalkcompute/_gen/chalk/sandbox/v1/runtime_service_pb2_grpc.pyi +41 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/sandbox/v1/service_pb2.py +54 -54
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/sandbox/v1/service_pb2.pyi +42 -6
- chalkcompute-2.3.4/chalkcompute/_gen/chalk/volume/v1/__init__.py +0 -0
- chalkcompute-2.3.4/chalkcompute/_gen/chalk/volume/v2/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_sandbox.py +195 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_scaling_group.py +82 -7
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_secret.py +65 -24
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/pyproject.toml +1 -1
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/rust/chalkcompute_native/Cargo.lock +14 -12
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/rust/chalkcompute_native/Cargo.toml +1 -1
- chalkcompute-2.3.3/chalkcompute/_gen/chalk/container/v1/service_pb2.py +0 -282
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/README.md +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_arrow_schema.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_auth_config.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_concurrency.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_connect.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/buf/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/buf/validate/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/buf/validate/validate_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/buf/validate/validate_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/buf/validate/validate_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/buf/validate/validate_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/argo/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/argo/v1/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/argo/v1/workflow_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/argo/v1/workflow_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/argo/v1/workflow_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/argo/v1/workflow_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/arrow/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/arrow/v1/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/arrow/v1/arrow_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/arrow/v1/arrow_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/arrow/v1/arrow_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/arrow/v1/arrow_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/auth → chalkcompute-2.3.4/chalkcompute/_gen/chalk/artifactstore}/__init__.py +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/auth → chalkcompute-2.3.4/chalkcompute/_gen/chalk/artifactstore}/v1/__init__.py +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/common → chalkcompute-2.3.4/chalkcompute/_gen/chalk/auth}/__init__.py +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/common → chalkcompute-2.3.4/chalkcompute/_gen/chalk/auth}/v1/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/agent_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/agent_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/audit_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/audit_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/audit_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/audit_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/displayagent_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/displayagent_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/displayagent_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/displayagent_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/featurepermission_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/featurepermission_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/featurepermission_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/featurepermission_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/permissions_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/permissions_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/permissions_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/auth/v1/permissions_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/container → chalkcompute-2.3.4/chalkcompute/_gen/chalk/common}/__init__.py +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/container → chalkcompute-2.3.4/chalkcompute/_gen/chalk/common}/v1/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/common/v1/chalk_error_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/common/v1/chalk_error_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/common/v1/chalk_error_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/common/v1/chalk_error_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/common/v1/log_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/common/v1/log_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/common/v1/log_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/common/v1/log_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/externalfunctioncatalog → chalkcompute-2.3.4/chalkcompute/_gen/chalk/container}/__init__.py +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/externalfunctioncatalog → chalkcompute-2.3.4/chalkcompute/_gen/chalk/container}/v1/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/container/v1/service_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/container/v1/service_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/flags → chalkcompute-2.3.4/chalkcompute/_gen/chalk/externalfunctioncatalog}/__init__.py +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/flags → chalkcompute-2.3.4/chalkcompute/_gen/chalk/externalfunctioncatalog}/v1/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/externalfunctioncatalog/v1/service_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/externalfunctioncatalog/v1/service_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/externalfunctioncatalog/v1/service_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/externalfunctioncatalog/v1/service_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/runtime → chalkcompute-2.3.4/chalkcompute/_gen/chalk/flags}/__init__.py +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/runtime → chalkcompute-2.3.4/chalkcompute/_gen/chalk/flags}/v1/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/flags/v1/flags_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/flags/v1/flags_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/flags/v1/flags_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/flags/v1/flags_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/sandbox → chalkcompute-2.3.4/chalkcompute/_gen/chalk/runtime}/__init__.py +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/sandbox → chalkcompute-2.3.4/chalkcompute/_gen/chalk/runtime}/v1/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/runtime/v1/remote_python_call_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/runtime/v1/remote_python_call_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/runtime/v1/remote_python_call_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/runtime/v1/remote_python_call_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/scalinggroup → chalkcompute-2.3.4/chalkcompute/_gen/chalk/sandbox}/__init__.py +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/scalinggroup → chalkcompute-2.3.4/chalkcompute/_gen/chalk/sandbox}/v1/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/sandbox/v1/service_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/sandbox/v1/service_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/utils → chalkcompute-2.3.4/chalkcompute/_gen/chalk/scalinggroup}/__init__.py +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/utils → chalkcompute-2.3.4/chalkcompute/_gen/chalk/scalinggroup}/v1/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/scalinggroup/v1/service_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/scalinggroup/v1/service_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/scalinggroup/v1/service_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/scalinggroup/v1/service_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/volume → chalkcompute-2.3.4/chalkcompute/_gen/chalk/utils}/__init__.py +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/volume → chalkcompute-2.3.4/chalkcompute/_gen/chalk/utils}/v1/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/utils/v1/encoding_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/utils/v1/encoding_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/utils/v1/encoding_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/utils/v1/encoding_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/utils/v1/field_change_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/utils/v1/field_change_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/utils/v1/field_change_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/utils/v1/field_change_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/utils/v1/sensitive_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/utils/v1/sensitive_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/utils/v1/sensitive_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/utils/v1/sensitive_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3/chalkcompute/_gen/chalk/volume/v2 → chalkcompute-2.3.4/chalkcompute/_gen/chalk/volume}/__init__.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/volume/v1/volume_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/volume/v1/volume_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/volume/v1/volume_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/volume/v1/volume_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/volume/v2/volume_pb2.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/volume/v2/volume_pb2.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/volume/v2/volume_pb2_grpc.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_gen/chalk/volume/v2/volume_pb2_grpc.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_ignore.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_image.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_local_dev.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_logging.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_model.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_naming.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_native.pyi +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_progress.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_proto_pool.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_quota.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_rate_limit.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_remote_call_client.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_remote_function_tracing.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_retry.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_tracing.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_volume.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/_vvolume.py +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/chalkcompute/py.typed +0 -0
- {chalkcompute-2.3.3 → chalkcompute-2.3.4}/rust/chalkcompute_native/src/lib.rs +0 -0
|
@@ -9,6 +9,11 @@ _setup_logging()
|
|
|
9
9
|
# Keep top-level imports lazy so `import chalkcompute` does not eagerly import
|
|
10
10
|
# the grpc/protobuf/client modules. Update `__init__.pyi` when adding exports.
|
|
11
11
|
_LAZY_MAP: dict[str, tuple[str, str]] = {
|
|
12
|
+
# _artifact.py
|
|
13
|
+
"Artifact": ("chalkcompute._artifact", "Artifact"),
|
|
14
|
+
"ArtifactClient": ("chalkcompute._artifact", "ArtifactClient"),
|
|
15
|
+
"ArtifactError": ("chalkcompute._artifact", "ArtifactError"),
|
|
16
|
+
"ArtifactNotFoundError": ("chalkcompute._artifact", "ArtifactNotFoundError"),
|
|
12
17
|
# _container.py
|
|
13
18
|
"Container": ("chalkcompute._container", "Container"),
|
|
14
19
|
"ContainerError": ("chalkcompute._container", "ContainerError"),
|
|
@@ -71,12 +76,15 @@ _LAZY_MAP: dict[str, tuple[str, str]] = {
|
|
|
71
76
|
"LazyLocalFile": ("chalkcompute._image", "LazyLocalFile"),
|
|
72
77
|
# _secret.py
|
|
73
78
|
"Secret": ("chalkcompute._secret", "Secret"),
|
|
79
|
+
"SecretScope": ("chalkcompute._secret", "SecretScope"),
|
|
74
80
|
"resolve_lazy_secrets": ("chalkcompute._secret", "resolve_lazy_secrets"),
|
|
75
81
|
# _sandbox.py
|
|
76
82
|
"ExecError": ("chalkcompute._sandbox", "ExecError"),
|
|
77
83
|
"ExecEvent": ("chalkcompute._sandbox", "ExecEvent"),
|
|
78
84
|
"ExecProcess": ("chalkcompute._sandbox", "ExecProcess"),
|
|
79
85
|
"ExecResult": ("chalkcompute._sandbox", "ExecResult"),
|
|
86
|
+
"PythonExecution": ("chalkcompute._sandbox", "PythonExecution"),
|
|
87
|
+
"PythonSkippedArtifact": ("chalkcompute._sandbox", "PythonSkippedArtifact"),
|
|
80
88
|
"Sandbox": ("chalkcompute._sandbox", "Sandbox"),
|
|
81
89
|
"SandboxBuildError": ("chalkcompute._sandbox", "SandboxBuildError"),
|
|
82
90
|
"SandboxClient": ("chalkcompute._sandbox", "SandboxClient"),
|
|
@@ -89,6 +97,7 @@ _LAZY_MAP: dict[str, tuple[str, str]] = {
|
|
|
89
97
|
"ScalingGroupBuildError": ("chalkcompute._scaling_group", "ScalingGroupBuildError"),
|
|
90
98
|
"ScalingGroupError": ("chalkcompute._scaling_group", "ScalingGroupError"),
|
|
91
99
|
"ScalingGroupInfo": ("chalkcompute._scaling_group", "ScalingGroupInfo"),
|
|
100
|
+
"ReadinessProbe": ("chalkcompute._scaling_group", "ReadinessProbe"),
|
|
92
101
|
# _volume.py
|
|
93
102
|
"FileInfo": ("chalkcompute._volume", "FileInfo"),
|
|
94
103
|
"Volume": ("chalkcompute._volume", "make_volume"),
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
from chalkcompute._artifact import Artifact as Artifact
|
|
2
|
+
from chalkcompute._artifact import ArtifactClient as ArtifactClient
|
|
3
|
+
from chalkcompute._artifact import ArtifactError as ArtifactError
|
|
4
|
+
from chalkcompute._artifact import ArtifactNotFoundError as ArtifactNotFoundError
|
|
1
5
|
from chalkcompute._cls import ClassBuildError as ClassBuildError
|
|
2
6
|
from chalkcompute._cls import ClassError as ClassError
|
|
3
7
|
from chalkcompute._cls import RemoteClass as RemoteClass
|
|
@@ -47,6 +51,8 @@ from chalkcompute._sandbox import ExecError as ExecError
|
|
|
47
51
|
from chalkcompute._sandbox import ExecEvent as ExecEvent
|
|
48
52
|
from chalkcompute._sandbox import ExecProcess as ExecProcess
|
|
49
53
|
from chalkcompute._sandbox import ExecResult as ExecResult
|
|
54
|
+
from chalkcompute._sandbox import PythonExecution as PythonExecution
|
|
55
|
+
from chalkcompute._sandbox import PythonSkippedArtifact as PythonSkippedArtifact
|
|
50
56
|
from chalkcompute._sandbox import Sandbox as Sandbox
|
|
51
57
|
from chalkcompute._sandbox import SandboxBuildError as SandboxBuildError
|
|
52
58
|
from chalkcompute._sandbox import SandboxClient as SandboxClient
|
|
@@ -58,7 +64,9 @@ from chalkcompute._scaling_group import ScalingGroup as ScalingGroup
|
|
|
58
64
|
from chalkcompute._scaling_group import ScalingGroupBuildError as ScalingGroupBuildError
|
|
59
65
|
from chalkcompute._scaling_group import ScalingGroupError as ScalingGroupError
|
|
60
66
|
from chalkcompute._scaling_group import ScalingGroupInfo as ScalingGroupInfo
|
|
67
|
+
from chalkcompute._scaling_group import ReadinessProbe as ReadinessProbe
|
|
61
68
|
from chalkcompute._secret import Secret as Secret
|
|
69
|
+
from chalkcompute._secret import SecretScope as SecretScope
|
|
62
70
|
from chalkcompute._secret import resolve_lazy_secrets as resolve_lazy_secrets
|
|
63
71
|
from chalkcompute._tracing import span as span
|
|
64
72
|
from chalkcompute._tracing import traced as traced
|
|
@@ -79,6 +87,10 @@ from chalkcompute._vvolume import VersionedVolume as VersionedVolume
|
|
|
79
87
|
from chalkcompute._vvolume import VersionedVolumeClient as VersionedVolumeClient
|
|
80
88
|
|
|
81
89
|
__all__ = [
|
|
90
|
+
"Artifact",
|
|
91
|
+
"ArtifactClient",
|
|
92
|
+
"ArtifactError",
|
|
93
|
+
"ArtifactNotFoundError",
|
|
82
94
|
"Container",
|
|
83
95
|
"ContainerError",
|
|
84
96
|
"ContainerInfo",
|
|
@@ -123,11 +135,14 @@ __all__ = [
|
|
|
123
135
|
"Image",
|
|
124
136
|
"LazyLocalFile",
|
|
125
137
|
"Secret",
|
|
138
|
+
"SecretScope",
|
|
126
139
|
"resolve_lazy_secrets",
|
|
127
140
|
"ExecError",
|
|
128
141
|
"ExecEvent",
|
|
129
142
|
"ExecProcess",
|
|
130
143
|
"ExecResult",
|
|
144
|
+
"PythonExecution",
|
|
145
|
+
"PythonSkippedArtifact",
|
|
131
146
|
"Sandbox",
|
|
132
147
|
"SandboxBuildError",
|
|
133
148
|
"SandboxClient",
|
|
@@ -139,6 +154,7 @@ __all__ = [
|
|
|
139
154
|
"ScalingGroupBuildError",
|
|
140
155
|
"ScalingGroupError",
|
|
141
156
|
"ScalingGroupInfo",
|
|
157
|
+
"ReadinessProbe",
|
|
142
158
|
"FileInfo",
|
|
143
159
|
"Volume",
|
|
144
160
|
"SimpleVolume",
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Client for the Chalk artifact store (chalk.artifactstore.v1.ArtifactService).
|
|
3
|
+
|
|
4
|
+
Artifacts are durable, environment-scoped outputs: charts captured from
|
|
5
|
+
``Sandbox.execute_python``, files saved with the in-sandbox ``save_artifact``
|
|
6
|
+
helper, or content stored directly through :meth:`ArtifactClient.create`.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
from chalkcompute import ArtifactClient, Sandbox
|
|
10
|
+
|
|
11
|
+
sandbox = Sandbox(image="python:3.12-slim").run()
|
|
12
|
+
execution = sandbox.execute_python(
|
|
13
|
+
"import altair as alt..."
|
|
14
|
+
)
|
|
15
|
+
for chart in execution.charts:
|
|
16
|
+
print(chart.name, chart.chart_encoding)
|
|
17
|
+
|
|
18
|
+
client = ArtifactClient.from_env()
|
|
19
|
+
for artifact in client.list(kinds=["chart"]):
|
|
20
|
+
print(artifact.id, artifact.name)
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
from collections.abc import Iterator
|
|
26
|
+
from dataclasses import dataclass, field
|
|
27
|
+
from typing import Any
|
|
28
|
+
|
|
29
|
+
import grpc
|
|
30
|
+
|
|
31
|
+
from chalkcompute._connect import (
|
|
32
|
+
ConnectClient,
|
|
33
|
+
grpc_target_from_url,
|
|
34
|
+
raise_for_grpc_error,
|
|
35
|
+
)
|
|
36
|
+
from chalkcompute._gen.chalk.artifactstore.v1 import service_pb2 as pb
|
|
37
|
+
from chalkcompute._gen.chalk.artifactstore.v1 import service_pb2_grpc as pb_grpc
|
|
38
|
+
from chalkcompute._tracing import _instrumented
|
|
39
|
+
|
|
40
|
+
# Aliases defined before ArtifactClient, which has a ``.list()`` method that
|
|
41
|
+
# would otherwise shadow the builtin ``list`` in class-scope name resolution.
|
|
42
|
+
_GrpcMetadata = list[tuple[str, str]]
|
|
43
|
+
_StrList = list[str]
|
|
44
|
+
|
|
45
|
+
_KIND_TO_PROTO: dict[str, pb.ArtifactKind] = {
|
|
46
|
+
"file": pb.ARTIFACT_KIND_FILE,
|
|
47
|
+
"chart": pb.ARTIFACT_KIND_CHART,
|
|
48
|
+
"html": pb.ARTIFACT_KIND_HTML,
|
|
49
|
+
"image": pb.ARTIFACT_KIND_IMAGE,
|
|
50
|
+
}
|
|
51
|
+
_KIND_FROM_PROTO: dict[pb.ArtifactKind, str] = {v: k for k, v in _KIND_TO_PROTO.items()}
|
|
52
|
+
|
|
53
|
+
_PRODUCER_TO_PROTO: dict[str, pb.ArtifactProducer] = {
|
|
54
|
+
"user": pb.ARTIFACT_PRODUCER_USER,
|
|
55
|
+
"system": pb.ARTIFACT_PRODUCER_SYSTEM,
|
|
56
|
+
}
|
|
57
|
+
_PRODUCER_FROM_PROTO: dict[pb.ArtifactProducer, str] = {
|
|
58
|
+
v: k for k, v in _PRODUCER_TO_PROTO.items()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class ArtifactError(Exception):
|
|
63
|
+
"""Base exception for artifact store errors."""
|
|
64
|
+
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class ArtifactNotFoundError(ArtifactError):
|
|
69
|
+
"""Raised when an artifact is not found."""
|
|
70
|
+
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@dataclass
|
|
75
|
+
class Artifact:
|
|
76
|
+
"""A stored artifact.
|
|
77
|
+
|
|
78
|
+
Small artifacts carry their content inline in ``data``; larger ones are
|
|
79
|
+
blob-backed and fetched on :meth:`download`.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
id: str
|
|
83
|
+
"""Artifact identifier."""
|
|
84
|
+
|
|
85
|
+
name: str
|
|
86
|
+
"""User-facing label."""
|
|
87
|
+
|
|
88
|
+
kind: str
|
|
89
|
+
"""One of ``"file"``, ``"chart"``, ``"html"``, ``"image"``."""
|
|
90
|
+
|
|
91
|
+
producer: str
|
|
92
|
+
"""``"user"`` (saved explicitly) or ``"system"`` (discovered by Chalk)."""
|
|
93
|
+
|
|
94
|
+
content_type: str
|
|
95
|
+
"""MIME type of the content."""
|
|
96
|
+
|
|
97
|
+
byte_size: int
|
|
98
|
+
"""Content size in bytes."""
|
|
99
|
+
|
|
100
|
+
sandbox_id: str | None = None
|
|
101
|
+
"""The sandbox that produced this artifact, when it came from one."""
|
|
102
|
+
|
|
103
|
+
execution_id: str | None = None
|
|
104
|
+
"""The ExecutePython execution that produced this artifact, if any."""
|
|
105
|
+
|
|
106
|
+
chart_encoding: str | None = None
|
|
107
|
+
"""For charts: ``"vega_lite"``, ``"tabular"``, or ``"plotly"``."""
|
|
108
|
+
|
|
109
|
+
chart_variable_name: str | None = None
|
|
110
|
+
"""For captured charts: the variable the figure was bound to."""
|
|
111
|
+
|
|
112
|
+
data: bytes | None = None
|
|
113
|
+
"""Inline content, when the artifact is small enough to travel inline."""
|
|
114
|
+
|
|
115
|
+
_client: ArtifactClient | None = field(default=None, repr=False, compare=False)
|
|
116
|
+
|
|
117
|
+
def download(self) -> bytes:
|
|
118
|
+
"""Return the artifact's content bytes, fetching them if not inline."""
|
|
119
|
+
if self.data is not None:
|
|
120
|
+
return self.data
|
|
121
|
+
if self._client is None:
|
|
122
|
+
raise ArtifactError(
|
|
123
|
+
"Artifact has no attached client. Fetch it via ArtifactClient to download content."
|
|
124
|
+
)
|
|
125
|
+
self.data = self._client.download(self.id)
|
|
126
|
+
return self.data
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _artifact_from_proto(msg: pb.Artifact, client: ArtifactClient | None) -> Artifact:
|
|
130
|
+
chart_encoding: str | None = None
|
|
131
|
+
chart_variable_name: str | None = None
|
|
132
|
+
if msg.HasField("chart"):
|
|
133
|
+
chart_variable_name = msg.chart.variable_name or None
|
|
134
|
+
which = msg.chart.WhichOneof("chart")
|
|
135
|
+
if which == "vega_lite":
|
|
136
|
+
chart_encoding = "vega_lite"
|
|
137
|
+
elif which == "tabular":
|
|
138
|
+
chart_encoding = "tabular"
|
|
139
|
+
elif which == "plotly":
|
|
140
|
+
chart_encoding = "plotly"
|
|
141
|
+
|
|
142
|
+
sandbox_id: str | None = None
|
|
143
|
+
execution_id: str | None = None
|
|
144
|
+
if msg.origin.WhichOneof("origin") == "sandbox_exec":
|
|
145
|
+
sandbox_id = msg.origin.sandbox_exec.sandbox_id or None
|
|
146
|
+
execution_id = msg.origin.sandbox_exec.execution_id or None
|
|
147
|
+
|
|
148
|
+
data: bytes | None = None
|
|
149
|
+
byte_size = 0
|
|
150
|
+
if msg.WhichOneof("content") == "inline":
|
|
151
|
+
data = msg.inline.data
|
|
152
|
+
byte_size = len(data)
|
|
153
|
+
elif msg.WhichOneof("content") == "blob":
|
|
154
|
+
byte_size = msg.blob.byte_size
|
|
155
|
+
|
|
156
|
+
return Artifact(
|
|
157
|
+
id=msg.id,
|
|
158
|
+
name=msg.name,
|
|
159
|
+
kind=_KIND_FROM_PROTO.get(msg.kind, "file"),
|
|
160
|
+
producer=_PRODUCER_FROM_PROTO.get(msg.producer, "user"),
|
|
161
|
+
content_type=msg.content_type,
|
|
162
|
+
byte_size=byte_size,
|
|
163
|
+
sandbox_id=sandbox_id,
|
|
164
|
+
execution_id=execution_id,
|
|
165
|
+
chart_encoding=chart_encoding,
|
|
166
|
+
chart_variable_name=chart_variable_name,
|
|
167
|
+
data=data,
|
|
168
|
+
_client=client,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class ArtifactClient:
|
|
173
|
+
"""Client for the artifact store gRPC service."""
|
|
174
|
+
|
|
175
|
+
def __init__(
|
|
176
|
+
self,
|
|
177
|
+
target: str = "localhost:50051",
|
|
178
|
+
*,
|
|
179
|
+
credentials: grpc.ChannelCredentials | None = None,
|
|
180
|
+
metadata: _GrpcMetadata | None = None,
|
|
181
|
+
) -> None:
|
|
182
|
+
self._target = target
|
|
183
|
+
self._metadata = metadata
|
|
184
|
+
if credentials is not None:
|
|
185
|
+
self._channel = grpc.secure_channel(target, credentials)
|
|
186
|
+
else:
|
|
187
|
+
self._channel = grpc.insecure_channel(target)
|
|
188
|
+
self._stub = pb_grpc.ArtifactServiceStub(self._channel)
|
|
189
|
+
|
|
190
|
+
@classmethod
|
|
191
|
+
def _from_channel(
|
|
192
|
+
cls, channel: grpc.Channel, metadata: _GrpcMetadata | None
|
|
193
|
+
) -> ArtifactClient:
|
|
194
|
+
"""Internal: wrap an existing authenticated channel (no new connection)."""
|
|
195
|
+
client = cls.__new__(cls)
|
|
196
|
+
client._target = ""
|
|
197
|
+
client._metadata = metadata
|
|
198
|
+
client._channel = channel
|
|
199
|
+
client._stub = pb_grpc.ArtifactServiceStub(channel)
|
|
200
|
+
return client
|
|
201
|
+
|
|
202
|
+
@classmethod
|
|
203
|
+
def from_env(cls, *, chalk_client: Any | None = None) -> ArtifactClient:
|
|
204
|
+
"""Create an ``ArtifactClient`` from ambient Chalk credentials."""
|
|
205
|
+
connect = ConnectClient(chalk_client=chalk_client)
|
|
206
|
+
connect._ensure_auth()
|
|
207
|
+
host, use_tls = grpc_target_from_url(connect._api_server or "")
|
|
208
|
+
return cls(
|
|
209
|
+
host,
|
|
210
|
+
credentials=grpc.ssl_channel_credentials() if use_tls else None,
|
|
211
|
+
metadata=[
|
|
212
|
+
("authorization", f"Bearer {connect._access_token}"),
|
|
213
|
+
("x-chalk-env-id", connect._env_id or ""),
|
|
214
|
+
("x-chalk-server", "go-api"),
|
|
215
|
+
],
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
def __enter__(self) -> ArtifactClient:
|
|
219
|
+
return self
|
|
220
|
+
|
|
221
|
+
def __exit__(self, *_args: object) -> None:
|
|
222
|
+
self.close()
|
|
223
|
+
|
|
224
|
+
def close(self) -> None:
|
|
225
|
+
"""Close the gRPC channel."""
|
|
226
|
+
self._channel.close()
|
|
227
|
+
|
|
228
|
+
@_instrumented("chalkcompute.artifact.create")
|
|
229
|
+
def create(
|
|
230
|
+
self,
|
|
231
|
+
data: bytes | str,
|
|
232
|
+
*,
|
|
233
|
+
name: str,
|
|
234
|
+
kind: str = "file",
|
|
235
|
+
content_type: str = "application/octet-stream",
|
|
236
|
+
) -> Artifact:
|
|
237
|
+
"""Store an artifact with inline content (up to a few MiB)."""
|
|
238
|
+
if isinstance(data, str):
|
|
239
|
+
data = data.encode("utf-8")
|
|
240
|
+
if kind not in _KIND_TO_PROTO:
|
|
241
|
+
raise ArtifactError(
|
|
242
|
+
f"unknown artifact kind {kind!r}; expected one of {sorted(_KIND_TO_PROTO)}"
|
|
243
|
+
)
|
|
244
|
+
spec = pb.Artifact(
|
|
245
|
+
name=name,
|
|
246
|
+
kind=_KIND_TO_PROTO[kind],
|
|
247
|
+
producer=pb.ARTIFACT_PRODUCER_USER,
|
|
248
|
+
content_type=content_type,
|
|
249
|
+
inline=pb.ArtifactInlineContent(data=data),
|
|
250
|
+
)
|
|
251
|
+
try:
|
|
252
|
+
resp = self._stub.CreateArtifact(
|
|
253
|
+
pb.CreateArtifactRequest(artifact=spec), metadata=self._metadata
|
|
254
|
+
)
|
|
255
|
+
except grpc.RpcError as e:
|
|
256
|
+
_handle_artifact_rpc_error(e, name)
|
|
257
|
+
raise
|
|
258
|
+
return _artifact_from_proto(resp.artifact, self)
|
|
259
|
+
|
|
260
|
+
@_instrumented("chalkcompute.artifact.get")
|
|
261
|
+
def get(self, artifact_id: str) -> Artifact:
|
|
262
|
+
"""Fetch a single artifact by id."""
|
|
263
|
+
try:
|
|
264
|
+
resp = self._stub.GetArtifact(
|
|
265
|
+
pb.GetArtifactRequest(artifact_id=artifact_id), metadata=self._metadata
|
|
266
|
+
)
|
|
267
|
+
except grpc.RpcError as e:
|
|
268
|
+
_handle_artifact_rpc_error(e, artifact_id)
|
|
269
|
+
raise
|
|
270
|
+
return _artifact_from_proto(resp.artifact, self)
|
|
271
|
+
|
|
272
|
+
@_instrumented("chalkcompute.artifact.list")
|
|
273
|
+
def list(
|
|
274
|
+
self,
|
|
275
|
+
*,
|
|
276
|
+
kinds: _StrList | None = None,
|
|
277
|
+
producers: _StrList | None = None,
|
|
278
|
+
sandbox_id: str | None = None,
|
|
279
|
+
limit: int | None = None,
|
|
280
|
+
) -> Iterator[Artifact]:
|
|
281
|
+
"""Iterate artifacts, newest first, paging transparently."""
|
|
282
|
+
cursor: str | None = None
|
|
283
|
+
remaining = limit
|
|
284
|
+
while True:
|
|
285
|
+
req = pb.ListArtifactsRequest(
|
|
286
|
+
kinds=[_KIND_TO_PROTO[k] for k in kinds or []],
|
|
287
|
+
producers=[_PRODUCER_TO_PROTO[p] for p in producers or []],
|
|
288
|
+
)
|
|
289
|
+
if sandbox_id is not None:
|
|
290
|
+
req.sandbox_id = sandbox_id
|
|
291
|
+
if cursor is not None:
|
|
292
|
+
req.cursor = cursor
|
|
293
|
+
if remaining is not None:
|
|
294
|
+
req.limit = min(remaining, 100)
|
|
295
|
+
try:
|
|
296
|
+
resp = self._stub.ListArtifacts(req, metadata=self._metadata)
|
|
297
|
+
except grpc.RpcError as e:
|
|
298
|
+
_handle_artifact_rpc_error(e, "list")
|
|
299
|
+
raise
|
|
300
|
+
for msg in resp.artifacts:
|
|
301
|
+
yield _artifact_from_proto(msg, self)
|
|
302
|
+
if remaining is not None:
|
|
303
|
+
remaining -= 1
|
|
304
|
+
if remaining <= 0:
|
|
305
|
+
return
|
|
306
|
+
if not resp.HasField("next_cursor") or not resp.next_cursor:
|
|
307
|
+
return
|
|
308
|
+
cursor = resp.next_cursor
|
|
309
|
+
|
|
310
|
+
@_instrumented("chalkcompute.artifact.download")
|
|
311
|
+
def download(self, artifact_id: str) -> bytes:
|
|
312
|
+
"""Download an artifact's content bytes."""
|
|
313
|
+
chunks: list[bytes] = []
|
|
314
|
+
try:
|
|
315
|
+
for frame in self._stub.DownloadArtifact(
|
|
316
|
+
pb.DownloadArtifactRequest(artifact_id=artifact_id),
|
|
317
|
+
metadata=self._metadata,
|
|
318
|
+
):
|
|
319
|
+
chunks.append(frame.data)
|
|
320
|
+
except grpc.RpcError as e:
|
|
321
|
+
_handle_artifact_rpc_error(e, artifact_id)
|
|
322
|
+
raise
|
|
323
|
+
return b"".join(chunks)
|
|
324
|
+
|
|
325
|
+
@_instrumented("chalkcompute.artifact.delete")
|
|
326
|
+
def delete(self, artifact_id: str) -> None:
|
|
327
|
+
"""Delete an artifact and its stored content."""
|
|
328
|
+
try:
|
|
329
|
+
self._stub.DeleteArtifact(
|
|
330
|
+
pb.DeleteArtifactRequest(artifact_id=artifact_id),
|
|
331
|
+
metadata=self._metadata,
|
|
332
|
+
)
|
|
333
|
+
except grpc.RpcError as e:
|
|
334
|
+
_handle_artifact_rpc_error(e, artifact_id)
|
|
335
|
+
raise
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def _handle_artifact_rpc_error(e: grpc.RpcError, subject: str) -> None:
|
|
339
|
+
"""Translate mapped gRPC status codes to typed artifact errors.
|
|
340
|
+
|
|
341
|
+
Unmapped codes return so the caller re-raises the original gRPC error,
|
|
342
|
+
matching the sandbox/volume client convention.
|
|
343
|
+
"""
|
|
344
|
+
raise_for_grpc_error(
|
|
345
|
+
e,
|
|
346
|
+
{
|
|
347
|
+
grpc.StatusCode.NOT_FOUND: (
|
|
348
|
+
ArtifactNotFoundError,
|
|
349
|
+
f"Artifact not found: {subject}",
|
|
350
|
+
),
|
|
351
|
+
},
|
|
352
|
+
)
|
|
@@ -874,7 +874,7 @@ class RemoteClass:
|
|
|
874
874
|
@classmethod
|
|
875
875
|
def _make_empty(cls, name: str, *, chalk_client: Any | None = None) -> RemoteClass:
|
|
876
876
|
rc = cls.__new__(cls)
|
|
877
|
-
rc._user_cls = None #
|
|
877
|
+
rc._user_cls = None # ty: ignore[invalid-assignment]
|
|
878
878
|
rc._class_name = name
|
|
879
879
|
rc._explicit_name = name
|
|
880
880
|
rc._image = None
|
|
@@ -1059,6 +1059,20 @@ class RemoteClass:
|
|
|
1059
1059
|
self._volume_driver = driver
|
|
1060
1060
|
_cleanup_temp_files(temp_files)
|
|
1061
1061
|
|
|
1062
|
+
# Resolve lazy secrets once, into a local rather than
|
|
1063
|
+
# self._secrets: they're shared by every method (one FUNCTION
|
|
1064
|
+
# scope for the class), and keeping self._secrets as the user's
|
|
1065
|
+
# lazy originals means a later .deploy() on the same object
|
|
1066
|
+
# re-upserts instead of reusing a stale resolution.
|
|
1067
|
+
resolved_secrets = self._secrets
|
|
1068
|
+
if self._secrets and any(s.is_lazy for s in self._secrets):
|
|
1069
|
+
from chalkcompute._secret import SecretScope, resolve_lazy_secrets
|
|
1070
|
+
|
|
1071
|
+
scope = SecretScope.function(self._explicit_name or self._class_name)
|
|
1072
|
+
resolved_secrets, _upserted = resolve_lazy_secrets(
|
|
1073
|
+
self._secrets, self._client, scope=scope
|
|
1074
|
+
)
|
|
1075
|
+
|
|
1062
1076
|
# 3. Register each method as a function version
|
|
1063
1077
|
sg_names: list[str] = []
|
|
1064
1078
|
for method_info in self._methods.values():
|
|
@@ -1089,17 +1103,9 @@ class RemoteClass:
|
|
|
1089
1103
|
volumes=self._volumes,
|
|
1090
1104
|
)
|
|
1091
1105
|
|
|
1092
|
-
|
|
1093
|
-
if self._secrets:
|
|
1094
|
-
from chalkcompute._secret import resolve_lazy_secrets
|
|
1095
|
-
|
|
1096
|
-
if any(s.is_lazy for s in self._secrets):
|
|
1097
|
-
resolved, _upserted = resolve_lazy_secrets(
|
|
1098
|
-
self._secrets, self._client
|
|
1099
|
-
)
|
|
1100
|
-
self._secrets = resolved
|
|
1106
|
+
if resolved_secrets:
|
|
1101
1107
|
container_spec["secretRefs"] = [
|
|
1102
|
-
s._to_proto_dict() for s in
|
|
1108
|
+
s._to_proto_dict() for s in resolved_secrets
|
|
1103
1109
|
]
|
|
1104
1110
|
|
|
1105
1111
|
scaling_spec: dict[str, Any] = {
|
|
@@ -1011,7 +1011,6 @@ class Container:
|
|
|
1011
1011
|
self._built_image_uri: str | None = None
|
|
1012
1012
|
self._container_id: str | None = None
|
|
1013
1013
|
self._container_info: ContainerInfo | None = None
|
|
1014
|
-
self._upserted_secret_names: list[str] = []
|
|
1015
1014
|
|
|
1016
1015
|
self._client = ConnectClient(chalk_client=chalk_client)
|
|
1017
1016
|
self._session_client: ContainerSessionClient | None = None
|
|
@@ -1101,7 +1100,7 @@ class Container:
|
|
|
1101
1100
|
@classmethod
|
|
1102
1101
|
def _make_empty(cls, *, chalk_client: Any | None = None) -> Container:
|
|
1103
1102
|
c = cls.__new__(cls)
|
|
1104
|
-
c._image = None #
|
|
1103
|
+
c._image = None # ty: ignore[invalid-assignment]
|
|
1105
1104
|
c._name = None
|
|
1106
1105
|
c._cpu = None
|
|
1107
1106
|
c._memory = None
|
|
@@ -1121,7 +1120,6 @@ class Container:
|
|
|
1121
1120
|
c._built_image_uri = None
|
|
1122
1121
|
c._container_id = None
|
|
1123
1122
|
c._container_info = None
|
|
1124
|
-
c._upserted_secret_names = []
|
|
1125
1123
|
c._client = ConnectClient(chalk_client=chalk_client)
|
|
1126
1124
|
c._session_client = None
|
|
1127
1125
|
return c
|
|
@@ -1345,15 +1343,19 @@ class Container:
|
|
|
1345
1343
|
)
|
|
1346
1344
|
progress_done(vkey)
|
|
1347
1345
|
|
|
1348
|
-
# 3. Resolve lazy secrets (from_local_env / from_local_env_file)
|
|
1346
|
+
# 3. Resolve lazy secrets (from_local_env / from_local_env_file).
|
|
1347
|
+
# Resolved into a local, not self._secrets, so a later .run() on
|
|
1348
|
+
# the same object re-upserts instead of reusing a stale resolution.
|
|
1349
|
+
resolved_secrets = self._secrets
|
|
1349
1350
|
if any(s.is_lazy for s in self._secrets):
|
|
1350
1351
|
skey = f"secret:{container_name}"
|
|
1351
1352
|
progress_add(skey, "secret", "Resolving secrets", parent=ckey)
|
|
1352
|
-
from chalkcompute._secret import resolve_lazy_secrets
|
|
1353
|
+
from chalkcompute._secret import SecretScope, resolve_lazy_secrets
|
|
1353
1354
|
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1355
|
+
scope = SecretScope.sandbox(container_name)
|
|
1356
|
+
resolved_secrets, upserted = resolve_lazy_secrets(
|
|
1357
|
+
self._secrets, self._client, scope=scope
|
|
1358
|
+
)
|
|
1357
1359
|
logger.info(
|
|
1358
1360
|
"Upserted %d secret(s) from local environment.",
|
|
1359
1361
|
len(upserted),
|
|
@@ -1403,8 +1405,8 @@ class Container:
|
|
|
1403
1405
|
)
|
|
1404
1406
|
spec["volumes"] = [v.to_spec_dict() for v in self._volumes]
|
|
1405
1407
|
|
|
1406
|
-
if
|
|
1407
|
-
spec["secretRefs"] = [s._to_proto_dict() for s in
|
|
1408
|
+
if resolved_secrets:
|
|
1409
|
+
spec["secretRefs"] = [s._to_proto_dict() for s in resolved_secrets]
|
|
1408
1410
|
|
|
1409
1411
|
logger.info("Starting container '%s'...", container_name)
|
|
1410
1412
|
resp = self._client.rpc(
|
|
@@ -1687,7 +1689,7 @@ class Container:
|
|
|
1687
1689
|
|
|
1688
1690
|
@_instrumented("chalkcompute.container.stop")
|
|
1689
1691
|
def stop(self, grace_period_seconds: int | None = None) -> None:
|
|
1690
|
-
"""Stop the container and clean up temporary volumes
|
|
1692
|
+
"""Stop the container and clean up temporary volumes.
|
|
1691
1693
|
|
|
1692
1694
|
Parameters
|
|
1693
1695
|
----------
|
|
@@ -1718,12 +1720,6 @@ class Container:
|
|
|
1718
1720
|
self._volumes = []
|
|
1719
1721
|
self._volume_driver = None
|
|
1720
1722
|
|
|
1721
|
-
if self._upserted_secret_names:
|
|
1722
|
-
from chalkcompute._secret import delete_secrets
|
|
1723
|
-
|
|
1724
|
-
delete_secrets(self._client, self._upserted_secret_names)
|
|
1725
|
-
self._upserted_secret_names = []
|
|
1726
|
-
|
|
1727
1723
|
def refresh(self) -> ContainerInfo:
|
|
1728
1724
|
"""Fetch latest container status from the server.
|
|
1729
1725
|
|
|
@@ -1943,17 +1943,20 @@ class RemoteFunction:
|
|
|
1943
1943
|
"scalingSpec": scaling_spec,
|
|
1944
1944
|
}
|
|
1945
1945
|
|
|
1946
|
-
# 5b. Resolve lazy secrets and add to container spec
|
|
1946
|
+
# 5b. Resolve lazy secrets and add to container spec. Resolved
|
|
1947
|
+
# into a local, not self._secrets, so a later .deploy() on the
|
|
1948
|
+
# same object re-upserts instead of reusing a stale resolution.
|
|
1947
1949
|
if self._secrets:
|
|
1948
|
-
from chalkcompute._secret import resolve_lazy_secrets
|
|
1950
|
+
from chalkcompute._secret import SecretScope, resolve_lazy_secrets
|
|
1949
1951
|
|
|
1952
|
+
resolved_secrets = self._secrets
|
|
1950
1953
|
if any(s.is_lazy for s in self._secrets):
|
|
1951
|
-
|
|
1952
|
-
|
|
1954
|
+
scope = SecretScope.function(self._explicit_name or self._func_name)
|
|
1955
|
+
resolved_secrets, _upserted = resolve_lazy_secrets(
|
|
1956
|
+
self._secrets, self._client, scope=scope
|
|
1953
1957
|
)
|
|
1954
|
-
self._secrets = resolved
|
|
1955
1958
|
container_spec["secretRefs"] = [
|
|
1956
|
-
s._to_proto_dict() for s in
|
|
1959
|
+
s._to_proto_dict() for s in resolved_secrets
|
|
1957
1960
|
]
|
|
1958
1961
|
|
|
1959
1962
|
# 5c. Build function-level config
|