modal 1.1.1.dev27__tar.gz → 1.1.1.dev29__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.
Potentially problematic release.
This version of modal might be problematic. Click here for more details.
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/PKG-INFO +1 -1
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_object.py +9 -1
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/client.pyi +2 -2
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/dict.py +45 -2
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/dict.pyi +55 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/functions.pyi +6 -6
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/object.pyi +4 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/queue.py +44 -2
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/queue.pyi +53 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/secret.py +44 -2
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/secret.pyi +55 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/volume.py +48 -18
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/volume.pyi +50 -8
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/api.proto +22 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/api_grpc.py +32 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/api_pb2.py +315 -275
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/api_pb2.pyi +71 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/api_pb2_grpc.py +66 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/api_pb2_grpc.pyi +20 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/modal_api_grpc.py +2 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_version/__init__.py +1 -1
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/LICENSE +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/README.md +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/__init__.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/__main__.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_clustered_functions.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_clustered_functions.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_container_entrypoint.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_functions.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_ipython.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_location.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_output.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_partial_function.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_pty.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_resolver.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_resources.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_runtime/__init__.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_runtime/asgi.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_runtime/execution_context.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_runtime/telemetry.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_serialization.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_traceback.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_tunnel.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_tunnel.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_type_manager.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/__init__.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/app_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/async_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/blob_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/deprecation.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/docker_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/function_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/git_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/hash_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/http_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/logger.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/mount_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/name_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/package_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/shell_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_utils/time_utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_vendor/__init__.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_vendor/tblib.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/_watcher.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/app.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/app.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/builder/2023.12.txt +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/builder/2024.04.txt +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/builder/2024.10.txt +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/builder/2025.06.txt +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/builder/README.md +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/builder/base-images.json +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/call_graph.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/__init__.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/_download.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/_traceback.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/app.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/cluster.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/config.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/container.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/dict.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/entry_point.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/environment.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/import_refs.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/launch.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/network_file_system.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/profile.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/programs/__init__.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/programs/vscode.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/queues.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/run.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/secret.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/token.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/utils.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cli/volume.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/client.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cls.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/cls.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/config.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/container_process.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/container_process.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/environments.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/environments.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/exception.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/experimental/__init__.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/experimental/flash.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/experimental/flash.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/experimental/ipython.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/file_io.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/file_io.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/file_pattern_matcher.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/functions.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/gpu.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/image.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/image.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/io_streams.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/io_streams.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/mount.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/mount.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/network_file_system.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/network_file_system.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/object.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/output.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/parallel_map.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/parallel_map.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/partial_function.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/partial_function.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/proxy.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/proxy.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/py.typed +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/retries.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/runner.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/runner.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/running_app.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/sandbox.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/sandbox.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/schedule.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/scheduler_placement.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/serving.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/serving.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/snapshot.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/snapshot.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/stream_type.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/token_flow.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal/token_flow.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal.egg-info/requires.txt +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal.egg-info/top_level.txt +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_docs/__init__.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/__init__.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/modal_options_grpc.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/options.proto +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/options_grpc.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/options_pb2.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/options_pb2.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/options_pb2_grpc.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/options_pb2_grpc.pyi +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_proto/py.typed +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/modal_version/__main__.py +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/pyproject.toml +0 -0
- {modal-1.1.1.dev27 → modal-1.1.1.dev29}/setup.cfg +0 -0
|
@@ -48,6 +48,10 @@ class _Object:
|
|
|
48
48
|
_is_hydrated: bool
|
|
49
49
|
_is_rehydrated: bool
|
|
50
50
|
|
|
51
|
+
# Not all object subclasses have a meaningful "name" concept
|
|
52
|
+
# So whether they expose this is a matter of having a name property
|
|
53
|
+
_name: Optional[str]
|
|
54
|
+
|
|
51
55
|
@classmethod
|
|
52
56
|
def __init_subclass__(cls, type_prefix: Optional[str] = None):
|
|
53
57
|
super().__init_subclass__()
|
|
@@ -68,6 +72,7 @@ class _Object:
|
|
|
68
72
|
hydrate_lazily: bool = False,
|
|
69
73
|
deps: Optional[Callable[..., Sequence["_Object"]]] = None,
|
|
70
74
|
deduplication_key: Optional[Callable[[], Awaitable[Hashable]]] = None,
|
|
75
|
+
name: Optional[str] = None,
|
|
71
76
|
):
|
|
72
77
|
self._local_uuid = str(uuid.uuid4())
|
|
73
78
|
self._load = load
|
|
@@ -83,6 +88,8 @@ class _Object:
|
|
|
83
88
|
self._is_hydrated = False
|
|
84
89
|
self._is_rehydrated = False
|
|
85
90
|
|
|
91
|
+
self._name = name
|
|
92
|
+
|
|
86
93
|
self._initialize_from_empty()
|
|
87
94
|
|
|
88
95
|
def _unhydrate(self):
|
|
@@ -163,10 +170,11 @@ class _Object:
|
|
|
163
170
|
hydrate_lazily: bool = False,
|
|
164
171
|
deps: Optional[Callable[..., Sequence["_Object"]]] = None,
|
|
165
172
|
deduplication_key: Optional[Callable[[], Awaitable[Hashable]]] = None,
|
|
173
|
+
name: Optional[str] = None,
|
|
166
174
|
):
|
|
167
175
|
# TODO(erikbern): flip the order of the two first arguments
|
|
168
176
|
obj = _Object.__new__(cls)
|
|
169
|
-
obj._init(rep, load, is_another_app, preload, hydrate_lazily, deps, deduplication_key)
|
|
177
|
+
obj._init(rep, load, is_another_app, preload, hydrate_lazily, deps, deduplication_key, name)
|
|
170
178
|
return obj
|
|
171
179
|
|
|
172
180
|
@staticmethod
|
|
@@ -33,7 +33,7 @@ class _Client:
|
|
|
33
33
|
server_url: str,
|
|
34
34
|
client_type: int,
|
|
35
35
|
credentials: typing.Optional[tuple[str, str]],
|
|
36
|
-
version: str = "1.1.1.
|
|
36
|
+
version: str = "1.1.1.dev29",
|
|
37
37
|
):
|
|
38
38
|
"""mdmd:hidden
|
|
39
39
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -164,7 +164,7 @@ class Client:
|
|
|
164
164
|
server_url: str,
|
|
165
165
|
client_type: int,
|
|
166
166
|
credentials: typing.Optional[tuple[str, str]],
|
|
167
|
-
version: str = "1.1.1.
|
|
167
|
+
version: str = "1.1.1.dev29",
|
|
168
168
|
):
|
|
169
169
|
"""mdmd:hidden
|
|
170
170
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# Copyright Modal Labs 2022
|
|
2
2
|
from collections.abc import AsyncIterator, Mapping
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
3
5
|
from typing import Any, Optional
|
|
4
6
|
|
|
7
|
+
from google.protobuf.message import Message
|
|
5
8
|
from grpclib import GRPCError
|
|
6
9
|
from synchronicity.async_wrap import asynccontextmanager
|
|
7
10
|
|
|
@@ -23,6 +26,18 @@ def _serialize_dict(data):
|
|
|
23
26
|
return [api_pb2.DictEntry(key=serialize(k), value=serialize(v)) for k, v in data.items()]
|
|
24
27
|
|
|
25
28
|
|
|
29
|
+
@dataclass
|
|
30
|
+
class DictInfo:
|
|
31
|
+
"""Information about the Dict object."""
|
|
32
|
+
|
|
33
|
+
# This dataclass should be limited to information that is unchanging over the lifetime of the Dict,
|
|
34
|
+
# since it is transmitted from the server when the object is hydrated and could be stale when accessed.
|
|
35
|
+
|
|
36
|
+
name: Optional[str]
|
|
37
|
+
created_at: datetime
|
|
38
|
+
created_by: Optional[str]
|
|
39
|
+
|
|
40
|
+
|
|
26
41
|
class _Dict(_Object, type_prefix="di"):
|
|
27
42
|
"""Distributed dictionary for storage in Modal apps.
|
|
28
43
|
|
|
@@ -65,12 +80,29 @@ class _Dict(_Object, type_prefix="di"):
|
|
|
65
80
|
For more examples, see the [guide](https://modal.com/docs/guide/dicts-and-queues#modal-dicts).
|
|
66
81
|
"""
|
|
67
82
|
|
|
83
|
+
_name: Optional[str] = None
|
|
84
|
+
_metadata: Optional[api_pb2.DictMetadata] = None
|
|
85
|
+
|
|
68
86
|
def __init__(self, data={}):
|
|
69
87
|
"""mdmd:hidden"""
|
|
70
88
|
raise RuntimeError(
|
|
71
89
|
"`Dict(...)` constructor is not allowed. Please use `Dict.from_name` or `Dict.ephemeral` instead"
|
|
72
90
|
)
|
|
73
91
|
|
|
92
|
+
@property
|
|
93
|
+
def name(self) -> Optional[str]:
|
|
94
|
+
return self._name
|
|
95
|
+
|
|
96
|
+
def _hydrate_metadata(self, metadata: Optional[Message]):
|
|
97
|
+
if metadata:
|
|
98
|
+
assert isinstance(metadata, api_pb2.DictMetadata)
|
|
99
|
+
self._metadata = metadata
|
|
100
|
+
self._name = metadata.name
|
|
101
|
+
|
|
102
|
+
def _get_metadata(self) -> api_pb2.DictMetadata:
|
|
103
|
+
assert self._metadata
|
|
104
|
+
return self._metadata
|
|
105
|
+
|
|
74
106
|
@classmethod
|
|
75
107
|
@asynccontextmanager
|
|
76
108
|
async def ephemeral(
|
|
@@ -112,7 +144,7 @@ class _Dict(_Object, type_prefix="di"):
|
|
|
112
144
|
async with TaskContext() as tc:
|
|
113
145
|
request = api_pb2.DictHeartbeatRequest(dict_id=response.dict_id)
|
|
114
146
|
tc.infinite_loop(lambda: client.stub.DictHeartbeat(request), sleep=_heartbeat_sleep)
|
|
115
|
-
yield cls._new_hydrated(response.dict_id, client,
|
|
147
|
+
yield cls._new_hydrated(response.dict_id, client, response.metadata, is_another_app=True)
|
|
116
148
|
|
|
117
149
|
@staticmethod
|
|
118
150
|
def from_name(
|
|
@@ -155,7 +187,7 @@ class _Dict(_Object, type_prefix="di"):
|
|
|
155
187
|
logger.debug(f"Created dict with id {response.dict_id}")
|
|
156
188
|
self._hydrate(response.dict_id, resolver.client, response.metadata)
|
|
157
189
|
|
|
158
|
-
return _Dict._from_loader(_load, "Dict()", is_another_app=True, hydrate_lazily=True)
|
|
190
|
+
return _Dict._from_loader(_load, "Dict()", is_another_app=True, hydrate_lazily=True, name=name)
|
|
159
191
|
|
|
160
192
|
@staticmethod
|
|
161
193
|
async def lookup(
|
|
@@ -209,6 +241,17 @@ class _Dict(_Object, type_prefix="di"):
|
|
|
209
241
|
req = api_pb2.DictDeleteRequest(dict_id=obj.object_id)
|
|
210
242
|
await retry_transient_errors(obj._client.stub.DictDelete, req)
|
|
211
243
|
|
|
244
|
+
@live_method
|
|
245
|
+
async def info(self) -> DictInfo:
|
|
246
|
+
"""Return information about the Dict object."""
|
|
247
|
+
metadata = self._get_metadata()
|
|
248
|
+
creation_info = metadata.creation_info
|
|
249
|
+
return DictInfo(
|
|
250
|
+
name=metadata.name or None,
|
|
251
|
+
created_at=datetime.fromtimestamp(creation_info.created_at),
|
|
252
|
+
created_by=creation_info.created_by or None,
|
|
253
|
+
)
|
|
254
|
+
|
|
212
255
|
@live_method
|
|
213
256
|
async def clear(self) -> None:
|
|
214
257
|
"""Remove all items from the Dict."""
|
|
@@ -1,13 +1,37 @@
|
|
|
1
1
|
import collections.abc
|
|
2
|
+
import datetime
|
|
3
|
+
import google.protobuf.message
|
|
2
4
|
import modal._object
|
|
3
5
|
import modal.client
|
|
4
6
|
import modal.object
|
|
7
|
+
import modal_proto.api_pb2
|
|
5
8
|
import synchronicity.combined_types
|
|
6
9
|
import typing
|
|
7
10
|
import typing_extensions
|
|
8
11
|
|
|
9
12
|
def _serialize_dict(data): ...
|
|
10
13
|
|
|
14
|
+
class DictInfo:
|
|
15
|
+
"""Information about the Dict object."""
|
|
16
|
+
|
|
17
|
+
name: typing.Optional[str]
|
|
18
|
+
created_at: datetime.datetime
|
|
19
|
+
created_by: typing.Optional[str]
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self, name: typing.Optional[str], created_at: datetime.datetime, created_by: typing.Optional[str]
|
|
23
|
+
) -> None:
|
|
24
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
25
|
+
...
|
|
26
|
+
|
|
27
|
+
def __repr__(self):
|
|
28
|
+
"""Return repr(self)."""
|
|
29
|
+
...
|
|
30
|
+
|
|
31
|
+
def __eq__(self, other):
|
|
32
|
+
"""Return self==value."""
|
|
33
|
+
...
|
|
34
|
+
|
|
11
35
|
class _Dict(modal._object._Object):
|
|
12
36
|
"""Distributed dictionary for storage in Modal apps.
|
|
13
37
|
|
|
@@ -49,10 +73,18 @@ class _Dict(modal._object._Object):
|
|
|
49
73
|
|
|
50
74
|
For more examples, see the [guide](https://modal.com/docs/guide/dicts-and-queues#modal-dicts).
|
|
51
75
|
"""
|
|
76
|
+
|
|
77
|
+
_name: typing.Optional[str]
|
|
78
|
+
_metadata: typing.Optional[modal_proto.api_pb2.DictMetadata]
|
|
79
|
+
|
|
52
80
|
def __init__(self, data={}):
|
|
53
81
|
"""mdmd:hidden"""
|
|
54
82
|
...
|
|
55
83
|
|
|
84
|
+
@property
|
|
85
|
+
def name(self) -> typing.Optional[str]: ...
|
|
86
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
87
|
+
def _get_metadata(self) -> modal_proto.api_pb2.DictMetadata: ...
|
|
56
88
|
@classmethod
|
|
57
89
|
def ephemeral(
|
|
58
90
|
cls: type[_Dict],
|
|
@@ -131,6 +163,10 @@ class _Dict(modal._object._Object):
|
|
|
131
163
|
client: typing.Optional[modal.client._Client] = None,
|
|
132
164
|
environment_name: typing.Optional[str] = None,
|
|
133
165
|
): ...
|
|
166
|
+
async def info(self) -> DictInfo:
|
|
167
|
+
"""Return information about the Dict object."""
|
|
168
|
+
...
|
|
169
|
+
|
|
134
170
|
async def clear(self) -> None:
|
|
135
171
|
"""Remove all items from the Dict."""
|
|
136
172
|
...
|
|
@@ -264,10 +300,18 @@ class Dict(modal.object.Object):
|
|
|
264
300
|
|
|
265
301
|
For more examples, see the [guide](https://modal.com/docs/guide/dicts-and-queues#modal-dicts).
|
|
266
302
|
"""
|
|
303
|
+
|
|
304
|
+
_name: typing.Optional[str]
|
|
305
|
+
_metadata: typing.Optional[modal_proto.api_pb2.DictMetadata]
|
|
306
|
+
|
|
267
307
|
def __init__(self, data={}):
|
|
268
308
|
"""mdmd:hidden"""
|
|
269
309
|
...
|
|
270
310
|
|
|
311
|
+
@property
|
|
312
|
+
def name(self) -> typing.Optional[str]: ...
|
|
313
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
314
|
+
def _get_metadata(self) -> modal_proto.api_pb2.DictMetadata: ...
|
|
271
315
|
@classmethod
|
|
272
316
|
def ephemeral(
|
|
273
317
|
cls: type[Dict],
|
|
@@ -388,6 +432,17 @@ class Dict(modal.object.Object):
|
|
|
388
432
|
|
|
389
433
|
delete: __delete_spec
|
|
390
434
|
|
|
435
|
+
class __info_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
436
|
+
def __call__(self, /) -> DictInfo:
|
|
437
|
+
"""Return information about the Dict object."""
|
|
438
|
+
...
|
|
439
|
+
|
|
440
|
+
async def aio(self, /) -> DictInfo:
|
|
441
|
+
"""Return information about the Dict object."""
|
|
442
|
+
...
|
|
443
|
+
|
|
444
|
+
info: __info_spec[typing_extensions.Self]
|
|
445
|
+
|
|
391
446
|
class __clear_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
392
447
|
def __call__(self, /) -> None:
|
|
393
448
|
"""Remove all items from the Dict."""
|
|
@@ -428,7 +428,7 @@ class Function(
|
|
|
428
428
|
|
|
429
429
|
_call_generator: ___call_generator_spec[typing_extensions.Self]
|
|
430
430
|
|
|
431
|
-
class __remote_spec(typing_extensions.Protocol[
|
|
431
|
+
class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
|
|
432
432
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
|
|
433
433
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result."""
|
|
434
434
|
...
|
|
@@ -437,7 +437,7 @@ class Function(
|
|
|
437
437
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result."""
|
|
438
438
|
...
|
|
439
439
|
|
|
440
|
-
remote: __remote_spec[modal._functions.
|
|
440
|
+
remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
|
|
441
441
|
|
|
442
442
|
class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
443
443
|
def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
|
|
@@ -464,7 +464,7 @@ class Function(
|
|
|
464
464
|
"""
|
|
465
465
|
...
|
|
466
466
|
|
|
467
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
|
467
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
|
|
468
468
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
469
469
|
"""[Experimental] Calls the function with the given arguments, without waiting for the results.
|
|
470
470
|
|
|
@@ -488,7 +488,7 @@ class Function(
|
|
|
488
488
|
...
|
|
489
489
|
|
|
490
490
|
_experimental_spawn: ___experimental_spawn_spec[
|
|
491
|
-
modal._functions.
|
|
491
|
+
modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
|
|
492
492
|
]
|
|
493
493
|
|
|
494
494
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER, SUPERSELF]):
|
|
@@ -497,7 +497,7 @@ class Function(
|
|
|
497
497
|
|
|
498
498
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P, typing_extensions.Self]
|
|
499
499
|
|
|
500
|
-
class __spawn_spec(typing_extensions.Protocol[
|
|
500
|
+
class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
|
|
501
501
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
502
502
|
"""Calls the function with the given arguments, without waiting for the results.
|
|
503
503
|
|
|
@@ -518,7 +518,7 @@ class Function(
|
|
|
518
518
|
"""
|
|
519
519
|
...
|
|
520
520
|
|
|
521
|
-
spawn: __spawn_spec[modal._functions.
|
|
521
|
+
spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
|
|
522
522
|
|
|
523
523
|
def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
|
|
524
524
|
"""Return the inner Python object wrapped by this Modal Function."""
|
|
@@ -31,6 +31,7 @@ class Object:
|
|
|
31
31
|
_client: typing.Optional[modal.client.Client]
|
|
32
32
|
_is_hydrated: bool
|
|
33
33
|
_is_rehydrated: bool
|
|
34
|
+
_name: typing.Optional[str]
|
|
34
35
|
|
|
35
36
|
def __init__(self, *args, **kwargs):
|
|
36
37
|
"""mdmd:hidden"""
|
|
@@ -54,6 +55,7 @@ class Object:
|
|
|
54
55
|
hydrate_lazily: bool = False,
|
|
55
56
|
deps: typing.Optional[collections.abc.Callable[..., collections.abc.Sequence[Object]]] = None,
|
|
56
57
|
deduplication_key: typing.Optional[collections.abc.Callable[[], collections.abc.Hashable]] = None,
|
|
58
|
+
name: typing.Optional[str] = None,
|
|
57
59
|
): ...
|
|
58
60
|
def aio(
|
|
59
61
|
self,
|
|
@@ -75,6 +77,7 @@ class Object:
|
|
|
75
77
|
deduplication_key: typing.Optional[
|
|
76
78
|
collections.abc.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
|
|
77
79
|
] = None,
|
|
80
|
+
name: typing.Optional[str] = None,
|
|
78
81
|
): ...
|
|
79
82
|
|
|
80
83
|
_init: ___init_spec[typing_extensions.Self]
|
|
@@ -107,6 +110,7 @@ class Object:
|
|
|
107
110
|
hydrate_lazily: bool = False,
|
|
108
111
|
deps: typing.Optional[collections.abc.Callable[..., collections.abc.Sequence[Object]]] = None,
|
|
109
112
|
deduplication_key: typing.Optional[collections.abc.Callable[[], collections.abc.Hashable]] = None,
|
|
113
|
+
name: typing.Optional[str] = None,
|
|
110
114
|
): ...
|
|
111
115
|
@staticmethod
|
|
112
116
|
def _get_type_from_id(object_id: str) -> type[Object]: ...
|
|
@@ -3,8 +3,11 @@ import queue # The system library
|
|
|
3
3
|
import time
|
|
4
4
|
import warnings
|
|
5
5
|
from collections.abc import AsyncGenerator, AsyncIterator
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from datetime import datetime
|
|
6
8
|
from typing import Any, Optional
|
|
7
9
|
|
|
10
|
+
from google.protobuf.message import Message
|
|
8
11
|
from grpclib import GRPCError, Status
|
|
9
12
|
from synchronicity.async_wrap import asynccontextmanager
|
|
10
13
|
|
|
@@ -21,6 +24,18 @@ from .client import _Client
|
|
|
21
24
|
from .exception import InvalidError, RequestSizeError
|
|
22
25
|
|
|
23
26
|
|
|
27
|
+
@dataclass
|
|
28
|
+
class QueueInfo:
|
|
29
|
+
"""Information about the Queue object."""
|
|
30
|
+
|
|
31
|
+
# This dataclass should be limited to information that is unchanging over the lifetime of the Queue,
|
|
32
|
+
# since it is transmitted from the server when the object is hydrated and could be stale when accessed.
|
|
33
|
+
|
|
34
|
+
name: Optional[str]
|
|
35
|
+
created_at: datetime
|
|
36
|
+
created_by: Optional[str]
|
|
37
|
+
|
|
38
|
+
|
|
24
39
|
class _Queue(_Object, type_prefix="qu"):
|
|
25
40
|
"""Distributed, FIFO queue for data flow in Modal apps.
|
|
26
41
|
|
|
@@ -94,10 +109,26 @@ class _Queue(_Object, type_prefix="qu"):
|
|
|
94
109
|
Partition keys must be non-empty and must not exceed 64 bytes.
|
|
95
110
|
"""
|
|
96
111
|
|
|
112
|
+
_metadata: Optional[api_pb2.QueueMetadata] = None
|
|
113
|
+
|
|
97
114
|
def __init__(self):
|
|
98
115
|
"""mdmd:hidden"""
|
|
99
116
|
raise RuntimeError("Queue() is not allowed. Please use `Queue.from_name(...)` or `Queue.ephemeral()` instead.")
|
|
100
117
|
|
|
118
|
+
@property
|
|
119
|
+
def name(self) -> Optional[str]:
|
|
120
|
+
return self._name
|
|
121
|
+
|
|
122
|
+
def _hydrate_metadata(self, metadata: Optional[Message]):
|
|
123
|
+
if metadata:
|
|
124
|
+
assert isinstance(metadata, api_pb2.QueueMetadata)
|
|
125
|
+
self._metadata = metadata
|
|
126
|
+
self._name = metadata.name
|
|
127
|
+
|
|
128
|
+
def _get_metadata(self) -> api_pb2.QueueMetadata:
|
|
129
|
+
assert self._metadata
|
|
130
|
+
return self._metadata
|
|
131
|
+
|
|
101
132
|
@staticmethod
|
|
102
133
|
def validate_partition_key(partition: Optional[str]) -> bytes:
|
|
103
134
|
if partition is not None:
|
|
@@ -142,7 +173,7 @@ class _Queue(_Object, type_prefix="qu"):
|
|
|
142
173
|
async with TaskContext() as tc:
|
|
143
174
|
request = api_pb2.QueueHeartbeatRequest(queue_id=response.queue_id)
|
|
144
175
|
tc.infinite_loop(lambda: client.stub.QueueHeartbeat(request), sleep=_heartbeat_sleep)
|
|
145
|
-
yield cls._new_hydrated(response.queue_id, client,
|
|
176
|
+
yield cls._new_hydrated(response.queue_id, client, response.metadata, is_another_app=True)
|
|
146
177
|
|
|
147
178
|
@staticmethod
|
|
148
179
|
def from_name(
|
|
@@ -175,7 +206,7 @@ class _Queue(_Object, type_prefix="qu"):
|
|
|
175
206
|
response = await resolver.client.stub.QueueGetOrCreate(req)
|
|
176
207
|
self._hydrate(response.queue_id, resolver.client, response.metadata)
|
|
177
208
|
|
|
178
|
-
return _Queue._from_loader(_load, "Queue()", is_another_app=True, hydrate_lazily=True)
|
|
209
|
+
return _Queue._from_loader(_load, "Queue()", is_another_app=True, hydrate_lazily=True, name=name)
|
|
179
210
|
|
|
180
211
|
@staticmethod
|
|
181
212
|
async def lookup(
|
|
@@ -222,6 +253,17 @@ class _Queue(_Object, type_prefix="qu"):
|
|
|
222
253
|
req = api_pb2.QueueDeleteRequest(queue_id=obj.object_id)
|
|
223
254
|
await retry_transient_errors(obj._client.stub.QueueDelete, req)
|
|
224
255
|
|
|
256
|
+
@live_method
|
|
257
|
+
async def info(self) -> QueueInfo:
|
|
258
|
+
"""Return information about the Queue object."""
|
|
259
|
+
metadata = self._get_metadata()
|
|
260
|
+
creation_info = metadata.creation_info
|
|
261
|
+
return QueueInfo(
|
|
262
|
+
name=metadata.name or None,
|
|
263
|
+
created_at=datetime.fromtimestamp(creation_info.created_at),
|
|
264
|
+
created_by=creation_info.created_by or None,
|
|
265
|
+
)
|
|
266
|
+
|
|
225
267
|
async def _get_nonblocking(self, partition: Optional[str], n_values: int) -> list[Any]:
|
|
226
268
|
request = api_pb2.QueueGetRequest(
|
|
227
269
|
queue_id=self.object_id,
|
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
import collections.abc
|
|
2
|
+
import datetime
|
|
3
|
+
import google.protobuf.message
|
|
2
4
|
import modal._object
|
|
3
5
|
import modal.client
|
|
4
6
|
import modal.object
|
|
7
|
+
import modal_proto.api_pb2
|
|
5
8
|
import synchronicity.combined_types
|
|
6
9
|
import typing
|
|
7
10
|
import typing_extensions
|
|
8
11
|
|
|
12
|
+
class QueueInfo:
|
|
13
|
+
"""Information about the Queue object."""
|
|
14
|
+
|
|
15
|
+
name: typing.Optional[str]
|
|
16
|
+
created_at: datetime.datetime
|
|
17
|
+
created_by: typing.Optional[str]
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self, name: typing.Optional[str], created_at: datetime.datetime, created_by: typing.Optional[str]
|
|
21
|
+
) -> None:
|
|
22
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
23
|
+
...
|
|
24
|
+
|
|
25
|
+
def __repr__(self):
|
|
26
|
+
"""Return repr(self)."""
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
def __eq__(self, other):
|
|
30
|
+
"""Return self==value."""
|
|
31
|
+
...
|
|
32
|
+
|
|
9
33
|
class _Queue(modal._object._Object):
|
|
10
34
|
"""Distributed, FIFO queue for data flow in Modal apps.
|
|
11
35
|
|
|
@@ -78,10 +102,17 @@ class _Queue(modal._object._Object):
|
|
|
78
102
|
|
|
79
103
|
Partition keys must be non-empty and must not exceed 64 bytes.
|
|
80
104
|
"""
|
|
105
|
+
|
|
106
|
+
_metadata: typing.Optional[modal_proto.api_pb2.QueueMetadata]
|
|
107
|
+
|
|
81
108
|
def __init__(self):
|
|
82
109
|
"""mdmd:hidden"""
|
|
83
110
|
...
|
|
84
111
|
|
|
112
|
+
@property
|
|
113
|
+
def name(self) -> typing.Optional[str]: ...
|
|
114
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
115
|
+
def _get_metadata(self) -> modal_proto.api_pb2.QueueMetadata: ...
|
|
85
116
|
@staticmethod
|
|
86
117
|
def validate_partition_key(partition: typing.Optional[str]) -> bytes: ...
|
|
87
118
|
@classmethod
|
|
@@ -155,6 +186,10 @@ class _Queue(modal._object._Object):
|
|
|
155
186
|
client: typing.Optional[modal.client._Client] = None,
|
|
156
187
|
environment_name: typing.Optional[str] = None,
|
|
157
188
|
): ...
|
|
189
|
+
async def info(self) -> QueueInfo:
|
|
190
|
+
"""Return information about the Queue object."""
|
|
191
|
+
...
|
|
192
|
+
|
|
158
193
|
async def _get_nonblocking(self, partition: typing.Optional[str], n_values: int) -> list[typing.Any]: ...
|
|
159
194
|
async def _get_blocking(
|
|
160
195
|
self, partition: typing.Optional[str], timeout: typing.Optional[float], n_values: int
|
|
@@ -335,10 +370,17 @@ class Queue(modal.object.Object):
|
|
|
335
370
|
|
|
336
371
|
Partition keys must be non-empty and must not exceed 64 bytes.
|
|
337
372
|
"""
|
|
373
|
+
|
|
374
|
+
_metadata: typing.Optional[modal_proto.api_pb2.QueueMetadata]
|
|
375
|
+
|
|
338
376
|
def __init__(self):
|
|
339
377
|
"""mdmd:hidden"""
|
|
340
378
|
...
|
|
341
379
|
|
|
380
|
+
@property
|
|
381
|
+
def name(self) -> typing.Optional[str]: ...
|
|
382
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
383
|
+
def _get_metadata(self) -> modal_proto.api_pb2.QueueMetadata: ...
|
|
342
384
|
@staticmethod
|
|
343
385
|
def validate_partition_key(partition: typing.Optional[str]) -> bytes: ...
|
|
344
386
|
@classmethod
|
|
@@ -453,6 +495,17 @@ class Queue(modal.object.Object):
|
|
|
453
495
|
|
|
454
496
|
delete: __delete_spec
|
|
455
497
|
|
|
498
|
+
class __info_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
499
|
+
def __call__(self, /) -> QueueInfo:
|
|
500
|
+
"""Return information about the Queue object."""
|
|
501
|
+
...
|
|
502
|
+
|
|
503
|
+
async def aio(self, /) -> QueueInfo:
|
|
504
|
+
"""Return information about the Queue object."""
|
|
505
|
+
...
|
|
506
|
+
|
|
507
|
+
info: __info_spec[typing_extensions.Self]
|
|
508
|
+
|
|
456
509
|
class ___get_nonblocking_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
457
510
|
def __call__(self, /, partition: typing.Optional[str], n_values: int) -> list[typing.Any]: ...
|
|
458
511
|
async def aio(self, /, partition: typing.Optional[str], n_values: int) -> list[typing.Any]: ...
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
# Copyright Modal Labs 2022
|
|
2
2
|
import os
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
3
5
|
from typing import Optional, Union
|
|
4
6
|
|
|
7
|
+
from google.protobuf.message import Message
|
|
5
8
|
from grpclib import GRPCError, Status
|
|
6
9
|
|
|
7
10
|
from modal_proto import api_pb2
|
|
8
11
|
|
|
9
|
-
from ._object import _get_environment_name, _Object
|
|
12
|
+
from ._object import _get_environment_name, _Object, live_method
|
|
10
13
|
from ._resolver import Resolver
|
|
11
14
|
from ._runtime.execution_context import is_local
|
|
12
15
|
from ._utils.async_utils import synchronize_api
|
|
@@ -19,6 +22,18 @@ from .exception import InvalidError, NotFoundError
|
|
|
19
22
|
ENV_DICT_WRONG_TYPE_ERR = "the env_dict argument to Secret has to be a dict[str, Union[str, None]]"
|
|
20
23
|
|
|
21
24
|
|
|
25
|
+
@dataclass
|
|
26
|
+
class SecretInfo:
|
|
27
|
+
"""Information about the Secret object."""
|
|
28
|
+
|
|
29
|
+
# This dataclass should be limited to information that is unchanging over the lifetime of the Secret,
|
|
30
|
+
# since it is transmitted from the server when the object is hydrated and could be stale when accessed.
|
|
31
|
+
|
|
32
|
+
name: Optional[str]
|
|
33
|
+
created_at: datetime
|
|
34
|
+
created_by: Optional[str]
|
|
35
|
+
|
|
36
|
+
|
|
22
37
|
class _Secret(_Object, type_prefix="st"):
|
|
23
38
|
"""Secrets provide a dictionary of environment variables for images.
|
|
24
39
|
|
|
@@ -29,6 +44,22 @@ class _Secret(_Object, type_prefix="st"):
|
|
|
29
44
|
See [the secrets guide page](https://modal.com/docs/guide/secrets) for more information.
|
|
30
45
|
"""
|
|
31
46
|
|
|
47
|
+
_metadata: Optional[api_pb2.SecretMetadata] = None
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def name(self) -> Optional[str]:
|
|
51
|
+
return self._name
|
|
52
|
+
|
|
53
|
+
def _hydrate_metadata(self, metadata: Optional[Message]):
|
|
54
|
+
if metadata:
|
|
55
|
+
assert isinstance(metadata, api_pb2.SecretMetadata)
|
|
56
|
+
self._metadata = metadata
|
|
57
|
+
self._name = metadata.name
|
|
58
|
+
|
|
59
|
+
def _get_metadata(self) -> api_pb2.SecretMetadata:
|
|
60
|
+
assert self._metadata
|
|
61
|
+
return self._metadata
|
|
62
|
+
|
|
32
63
|
@staticmethod
|
|
33
64
|
def from_dict(
|
|
34
65
|
env_dict: dict[
|
|
@@ -202,7 +233,7 @@ class _Secret(_Object, type_prefix="st"):
|
|
|
202
233
|
raise
|
|
203
234
|
self._hydrate(response.secret_id, resolver.client, response.metadata)
|
|
204
235
|
|
|
205
|
-
return _Secret._from_loader(_load, "Secret()", hydrate_lazily=True)
|
|
236
|
+
return _Secret._from_loader(_load, "Secret()", hydrate_lazily=True, name=name)
|
|
206
237
|
|
|
207
238
|
@staticmethod
|
|
208
239
|
async def lookup(
|
|
@@ -261,5 +292,16 @@ class _Secret(_Object, type_prefix="st"):
|
|
|
261
292
|
resp = await retry_transient_errors(client.stub.SecretGetOrCreate, request)
|
|
262
293
|
return resp.secret_id
|
|
263
294
|
|
|
295
|
+
@live_method
|
|
296
|
+
async def info(self) -> SecretInfo:
|
|
297
|
+
"""Return information about the Secret object."""
|
|
298
|
+
metadata = self._get_metadata()
|
|
299
|
+
creation_info = metadata.creation_info
|
|
300
|
+
return SecretInfo(
|
|
301
|
+
name=metadata.name or None,
|
|
302
|
+
created_at=datetime.fromtimestamp(creation_info.created_at),
|
|
303
|
+
created_by=creation_info.created_by or None,
|
|
304
|
+
)
|
|
305
|
+
|
|
264
306
|
|
|
265
307
|
Secret = synchronize_api(_Secret)
|