modal 1.1.2.dev17__tar.gz → 1.1.2.dev19__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.
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/PKG-INFO +1 -1
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_functions.py +2 -1
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_object.py +13 -2
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/client.pyi +2 -2
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cls.py +2 -1
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/dict.py +19 -3
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/experimental/__init__.py +28 -2
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/functions.pyi +6 -6
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/network_file_system.py +7 -1
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/object.pyi +3 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/proxy.py +2 -1
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/queue.py +12 -2
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/secret.py +12 -2
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/volume.py +19 -3
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_version/__init__.py +1 -1
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/LICENSE +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/README.md +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/__init__.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/__main__.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_clustered_functions.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_clustered_functions.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_container_entrypoint.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_ipython.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_location.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_output.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_partial_function.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_pty.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_resolver.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_resources.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_runtime/__init__.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_runtime/asgi.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_runtime/execution_context.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_runtime/telemetry.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_serialization.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_traceback.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_tunnel.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_tunnel.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_type_manager.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/__init__.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/app_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/async_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/blob_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/deprecation.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/docker_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/function_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/git_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/hash_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/http_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/logger.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/mount_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/name_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/package_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/shell_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_utils/time_utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_vendor/__init__.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_vendor/tblib.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/_watcher.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/app.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/app.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/builder/2023.12.txt +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/builder/2024.04.txt +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/builder/2024.10.txt +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/builder/2025.06.txt +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/builder/README.md +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/builder/base-images.json +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/call_graph.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/__init__.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/_download.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/_traceback.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/app.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/cluster.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/config.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/container.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/dict.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/entry_point.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/environment.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/import_refs.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/launch.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/network_file_system.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/profile.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/programs/__init__.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/programs/launch_instance_ssh.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/programs/run_marimo.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/programs/vscode.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/queues.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/run.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/secret.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/token.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/utils.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cli/volume.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/client.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/cls.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/config.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/container_process.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/container_process.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/dict.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/environments.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/environments.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/exception.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/experimental/flash.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/experimental/flash.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/experimental/ipython.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/file_io.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/file_io.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/file_pattern_matcher.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/functions.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/gpu.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/image.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/image.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/io_streams.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/io_streams.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/mount.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/mount.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/network_file_system.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/object.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/output.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/parallel_map.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/parallel_map.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/partial_function.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/partial_function.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/proxy.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/py.typed +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/queue.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/retries.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/runner.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/runner.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/running_app.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/sandbox.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/sandbox.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/schedule.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/scheduler_placement.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/secret.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/serving.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/serving.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/snapshot.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/snapshot.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/stream_type.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/token_flow.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/token_flow.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal/volume.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal.egg-info/requires.txt +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal.egg-info/top_level.txt +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_docs/__init__.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/__init__.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/api.proto +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/api_grpc.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/api_pb2.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/api_pb2.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/modal_options_grpc.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/options.proto +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/options_grpc.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/options_pb2.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/options_pb2.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/options_pb2_grpc.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/options_pb2_grpc.pyi +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_proto/py.typed +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/modal_version/__main__.py +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/pyproject.toml +0 -0
- {modal-1.1.2.dev17 → modal-1.1.2.dev19}/setup.cfg +0 -0
@@ -1276,7 +1276,8 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
1276
1276
|
|
1277
1277
|
self._hydrate(response.function_id, resolver.client, response.handle_metadata)
|
1278
1278
|
|
1279
|
-
|
1279
|
+
environment_rep = f", environment_name={environment_name!r}" if environment_name else ""
|
1280
|
+
rep = f"modal.Function.from_name('{app_name}', '{name}'{environment_rep})"
|
1280
1281
|
return cls._from_loader(_load_remote, rep, is_another_app=True, hydrate_lazily=True)
|
1281
1282
|
|
1282
1283
|
@classmethod
|
@@ -191,9 +191,20 @@ class _Object:
|
|
191
191
|
def _is_id_type(cls, object_id) -> bool:
|
192
192
|
return cls._get_type_from_id(object_id) == cls
|
193
193
|
|
194
|
+
@classmethod
|
195
|
+
def _repr(cls, name: str, environment_name: Optional[str] = None) -> str:
|
196
|
+
public_cls = cls.__name__.strip("_")
|
197
|
+
environment_repr = f", environment_name={environment_name!r}" if environment_name else ""
|
198
|
+
return f"modal.{public_cls}.from_name({name!r}{environment_repr})"
|
199
|
+
|
194
200
|
@classmethod
|
195
201
|
def _new_hydrated(
|
196
|
-
cls,
|
202
|
+
cls,
|
203
|
+
object_id: str,
|
204
|
+
client: _Client,
|
205
|
+
handle_metadata: Optional[Message],
|
206
|
+
is_another_app: bool = False,
|
207
|
+
rep: Optional[str] = None,
|
197
208
|
) -> Self:
|
198
209
|
obj_cls: type[Self]
|
199
210
|
if cls._type_prefix is not None:
|
@@ -210,7 +221,7 @@ class _Object:
|
|
210
221
|
|
211
222
|
# Instantiate provider
|
212
223
|
obj = _Object.__new__(obj_cls)
|
213
|
-
rep = f"
|
224
|
+
rep = rep or f"modal.{obj_cls.__name__.strip('_')}.from_id({object_id!r})"
|
214
225
|
obj._init(rep, is_another_app=is_another_app)
|
215
226
|
obj._hydrate(object_id, client, handle_metadata)
|
216
227
|
|
@@ -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.2.
|
36
|
+
version: str = "1.1.2.dev19",
|
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.2.
|
167
|
+
version: str = "1.1.2.dev19",
|
168
168
|
):
|
169
169
|
"""mdmd:hidden
|
170
170
|
The Modal client object is not intended to be instantiated directly by users.
|
@@ -657,7 +657,8 @@ More information on class parameterization can be found here: https://modal.com/
|
|
657
657
|
await resolver.load(self._class_service_function)
|
658
658
|
self._hydrate(response.class_id, resolver.client, response.handle_metadata)
|
659
659
|
|
660
|
-
|
660
|
+
environment_rep = f", environment_name={environment_name!r}" if environment_name else ""
|
661
|
+
rep = f"Cls.from_name({app_name!r}, {name!r}{environment_rep})"
|
661
662
|
cls = cls._from_loader(_load_remote, rep, is_another_app=True, hydrate_lazily=True)
|
662
663
|
|
663
664
|
class_service_name = f"{name}.*" # special name of the base service function for the class
|
@@ -101,7 +101,16 @@ class _DictManager:
|
|
101
101
|
break
|
102
102
|
finished = await retrieve_page(items[-1].metadata.creation_info.created_at)
|
103
103
|
|
104
|
-
dicts = [
|
104
|
+
dicts = [
|
105
|
+
_Dict._new_hydrated(
|
106
|
+
item.dict_id,
|
107
|
+
client,
|
108
|
+
item.metadata,
|
109
|
+
is_another_app=True,
|
110
|
+
rep=_Dict._repr(item.name, environment_name),
|
111
|
+
)
|
112
|
+
for item in items
|
113
|
+
]
|
105
114
|
return dicts[:max_objects] if max_objects is not None else dicts
|
106
115
|
|
107
116
|
@staticmethod
|
@@ -252,7 +261,13 @@ class _Dict(_Object, type_prefix="di"):
|
|
252
261
|
async with TaskContext() as tc:
|
253
262
|
request = api_pb2.DictHeartbeatRequest(dict_id=response.dict_id)
|
254
263
|
tc.infinite_loop(lambda: client.stub.DictHeartbeat(request), sleep=_heartbeat_sleep)
|
255
|
-
yield cls._new_hydrated(
|
264
|
+
yield cls._new_hydrated(
|
265
|
+
response.dict_id,
|
266
|
+
client,
|
267
|
+
response.metadata,
|
268
|
+
is_another_app=True,
|
269
|
+
rep="modal.Dict.ephemeral()",
|
270
|
+
)
|
256
271
|
|
257
272
|
@staticmethod
|
258
273
|
def from_name(
|
@@ -295,7 +310,8 @@ class _Dict(_Object, type_prefix="di"):
|
|
295
310
|
logger.debug(f"Created dict with id {response.dict_id}")
|
296
311
|
self._hydrate(response.dict_id, resolver.client, response.metadata)
|
297
312
|
|
298
|
-
|
313
|
+
rep = _Dict._repr(name, environment_name)
|
314
|
+
return _Dict._from_loader(_load, rep, is_another_app=True, hydrate_lazily=True, name=name)
|
299
315
|
|
300
316
|
@staticmethod
|
301
317
|
async def lookup(
|
@@ -213,6 +213,24 @@ async def raw_registry_image(
|
|
213
213
|
)
|
214
214
|
|
215
215
|
|
216
|
+
def _install_cuda_command() -> str:
|
217
|
+
"""Command to install CUDA Toolkit (nvcc) inside a container."""
|
218
|
+
arch = "x86_64" # instruction set architecture for the CPU, all Modal machines are x86_64
|
219
|
+
distro = "debian12" # the distribution and version number of our OS (GNU/Linux)
|
220
|
+
filename = "cuda-keyring_1.1-1_all.deb" # NVIDIA signing key file
|
221
|
+
cuda_keyring_url = f"https://developer.download.nvidia.com/compute/cuda/repos/{distro}/{arch}/{filename}"
|
222
|
+
|
223
|
+
major, minor = 12, 8
|
224
|
+
max_cuda_version = f"{major}-{minor}"
|
225
|
+
|
226
|
+
return (
|
227
|
+
f"wget {cuda_keyring_url} && "
|
228
|
+
+ f"dpkg -i {filename} && "
|
229
|
+
+ f"rm -f {filename} && "
|
230
|
+
+ f"apt-get update && apt-get install -y cuda-nvcc-{max_cuda_version}"
|
231
|
+
)
|
232
|
+
|
233
|
+
|
216
234
|
@synchronizer.create_blocking
|
217
235
|
async def notebook_base_image(*, python_version: Optional[str] = None, force_build: bool = False) -> _Image:
|
218
236
|
"""Default image used for Modal notebook kernels, with common libraries.
|
@@ -293,7 +311,8 @@ async def notebook_base_image(*, python_version: Optional[str] = None, force_bui
|
|
293
311
|
|
294
312
|
commands: list[str] = [
|
295
313
|
"apt-get update",
|
296
|
-
"apt-get install -y libpq-dev pkg-config cmake git curl wget unzip zip libsqlite3-dev openssh-server",
|
314
|
+
"apt-get install -y libpq-dev pkg-config cmake git curl wget unzip zip libsqlite3-dev openssh-server vim",
|
315
|
+
_install_cuda_command(),
|
297
316
|
# Install uv since it's faster than pip for installing packages.
|
298
317
|
"pip install uv",
|
299
318
|
# https://github.com/astral-sh/uv/issues/11480
|
@@ -306,7 +325,14 @@ async def notebook_base_image(*, python_version: Optional[str] = None, force_bui
|
|
306
325
|
# https://github.com/charlesfrye/cuda-modal/blob/7fef8db12402986cf42d9c8cca8c63d1da6d7700/cuda/use_cuda.py#L158-L188
|
307
326
|
|
308
327
|
def build_dockerfile(version: ImageBuilderVersion) -> DockerfileSpec:
|
309
|
-
return DockerfileSpec(
|
328
|
+
return DockerfileSpec(
|
329
|
+
commands=[
|
330
|
+
"FROM base",
|
331
|
+
*(f"RUN {cmd}" for cmd in commands),
|
332
|
+
"ENV PATH=/usr/local/cuda/bin:$PATH",
|
333
|
+
],
|
334
|
+
context_files={},
|
335
|
+
)
|
310
336
|
|
311
337
|
return _Image._from_args(
|
312
338
|
base_images={"base": base_image},
|
@@ -433,7 +433,7 @@ class Function(
|
|
433
433
|
|
434
434
|
_call_generator: ___call_generator_spec[typing_extensions.Self]
|
435
435
|
|
436
|
-
class __remote_spec(typing_extensions.Protocol[
|
436
|
+
class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
|
437
437
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
|
438
438
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result."""
|
439
439
|
...
|
@@ -442,7 +442,7 @@ class Function(
|
|
442
442
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result."""
|
443
443
|
...
|
444
444
|
|
445
|
-
remote: __remote_spec[modal._functions.
|
445
|
+
remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
|
446
446
|
|
447
447
|
class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
|
448
448
|
def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
|
@@ -469,7 +469,7 @@ class Function(
|
|
469
469
|
"""
|
470
470
|
...
|
471
471
|
|
472
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
472
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
|
473
473
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
474
474
|
"""[Experimental] Calls the function with the given arguments, without waiting for the results.
|
475
475
|
|
@@ -493,7 +493,7 @@ class Function(
|
|
493
493
|
...
|
494
494
|
|
495
495
|
_experimental_spawn: ___experimental_spawn_spec[
|
496
|
-
modal._functions.
|
496
|
+
modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
|
497
497
|
]
|
498
498
|
|
499
499
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER, SUPERSELF]):
|
@@ -502,7 +502,7 @@ class Function(
|
|
502
502
|
|
503
503
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P, typing_extensions.Self]
|
504
504
|
|
505
|
-
class __spawn_spec(typing_extensions.Protocol[
|
505
|
+
class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
|
506
506
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
507
507
|
"""Calls the function with the given arguments, without waiting for the results.
|
508
508
|
|
@@ -523,7 +523,7 @@ class Function(
|
|
523
523
|
"""
|
524
524
|
...
|
525
525
|
|
526
|
-
spawn: __spawn_spec[modal._functions.
|
526
|
+
spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
|
527
527
|
|
528
528
|
def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
|
529
529
|
"""Return the inner Python object wrapped by this Modal Function."""
|
@@ -161,7 +161,13 @@ class _NetworkFileSystem(_Object, type_prefix="sv"):
|
|
161
161
|
async with TaskContext() as tc:
|
162
162
|
request = api_pb2.SharedVolumeHeartbeatRequest(shared_volume_id=response.shared_volume_id)
|
163
163
|
tc.infinite_loop(lambda: client.stub.SharedVolumeHeartbeat(request), sleep=_heartbeat_sleep)
|
164
|
-
yield cls._new_hydrated(
|
164
|
+
yield cls._new_hydrated(
|
165
|
+
response.shared_volume_id,
|
166
|
+
client,
|
167
|
+
None,
|
168
|
+
is_another_app=True,
|
169
|
+
rep="modal.NetworkFileSystem.ephemeral()",
|
170
|
+
)
|
165
171
|
|
166
172
|
@staticmethod
|
167
173
|
async def lookup(
|
@@ -117,12 +117,15 @@ class Object:
|
|
117
117
|
@classmethod
|
118
118
|
def _is_id_type(cls, object_id) -> bool: ...
|
119
119
|
@classmethod
|
120
|
+
def _repr(cls, name: str, environment_name: typing.Optional[str] = None) -> str: ...
|
121
|
+
@classmethod
|
120
122
|
def _new_hydrated(
|
121
123
|
cls,
|
122
124
|
object_id: str,
|
123
125
|
client: modal.client.Client,
|
124
126
|
handle_metadata: typing.Optional[google.protobuf.message.Message],
|
125
127
|
is_another_app: bool = False,
|
128
|
+
rep: typing.Optional[str] = None,
|
126
129
|
) -> typing_extensions.Self: ...
|
127
130
|
def _hydrate_from_other(self, other: typing_extensions.Self): ...
|
128
131
|
def __repr__(self): ...
|
@@ -36,7 +36,8 @@ class _Proxy(_Object, type_prefix="pr"):
|
|
36
36
|
response: api_pb2.ProxyGetResponse = await resolver.client.stub.ProxyGet(req)
|
37
37
|
self._hydrate(response.proxy.proxy_id, resolver.client, None)
|
38
38
|
|
39
|
-
|
39
|
+
rep = _Proxy._repr(name, environment_name)
|
40
|
+
return _Proxy._from_loader(_load, rep, is_another_app=True)
|
40
41
|
|
41
42
|
|
42
43
|
Proxy = synchronize_api(_Proxy, target_module=__name__)
|
@@ -99,7 +99,16 @@ class _QueueManager:
|
|
99
99
|
break
|
100
100
|
finished = await retrieve_page(items[-1].metadata.creation_info.created_at)
|
101
101
|
|
102
|
-
queues = [
|
102
|
+
queues = [
|
103
|
+
_Queue._new_hydrated(
|
104
|
+
item.queue_id,
|
105
|
+
client,
|
106
|
+
item.metadata,
|
107
|
+
is_another_app=True,
|
108
|
+
rep=_Queue._repr(item.name, environment_name),
|
109
|
+
)
|
110
|
+
for item in items
|
111
|
+
]
|
103
112
|
return queues[:max_objects] if max_objects is not None else queues
|
104
113
|
|
105
114
|
@staticmethod
|
@@ -314,7 +323,8 @@ class _Queue(_Object, type_prefix="qu"):
|
|
314
323
|
response = await resolver.client.stub.QueueGetOrCreate(req)
|
315
324
|
self._hydrate(response.queue_id, resolver.client, response.metadata)
|
316
325
|
|
317
|
-
|
326
|
+
rep = _Queue._repr(name, environment_name)
|
327
|
+
return _Queue._from_loader(_load, rep, is_another_app=True, hydrate_lazily=True, name=name)
|
318
328
|
|
319
329
|
@staticmethod
|
320
330
|
async def lookup(
|
@@ -91,7 +91,16 @@ class _SecretManager:
|
|
91
91
|
break
|
92
92
|
finished = await retrieve_page(items[-1].metadata.creation_info.created_at)
|
93
93
|
|
94
|
-
secrets = [
|
94
|
+
secrets = [
|
95
|
+
_Secret._new_hydrated(
|
96
|
+
item.secret_id,
|
97
|
+
client,
|
98
|
+
item.metadata,
|
99
|
+
is_another_app=True,
|
100
|
+
rep=_Secret._repr(item.label, environment_name),
|
101
|
+
)
|
102
|
+
for item in items
|
103
|
+
]
|
95
104
|
return secrets[:max_objects] if max_objects is not None else secrets
|
96
105
|
|
97
106
|
@staticmethod
|
@@ -334,7 +343,8 @@ class _Secret(_Object, type_prefix="st"):
|
|
334
343
|
raise
|
335
344
|
self._hydrate(response.secret_id, resolver.client, response.metadata)
|
336
345
|
|
337
|
-
|
346
|
+
rep = _Secret._repr(name, environment_name)
|
347
|
+
return _Secret._from_loader(_load, rep, hydrate_lazily=True, name=name)
|
338
348
|
|
339
349
|
@staticmethod
|
340
350
|
async def lookup(
|
@@ -168,7 +168,16 @@ class _VolumeManager:
|
|
168
168
|
break
|
169
169
|
finished = await retrieve_page(items[-1].metadata.creation_info.created_at)
|
170
170
|
|
171
|
-
volumes = [
|
171
|
+
volumes = [
|
172
|
+
_Volume._new_hydrated(
|
173
|
+
item.volume_id,
|
174
|
+
client,
|
175
|
+
item.metadata,
|
176
|
+
is_another_app=True,
|
177
|
+
rep=_Volume._repr(item.label, environment_name),
|
178
|
+
)
|
179
|
+
for item in items
|
180
|
+
]
|
172
181
|
return volumes[:max_objects] if max_objects is not None else volumes
|
173
182
|
|
174
183
|
@staticmethod
|
@@ -362,7 +371,8 @@ class _Volume(_Object, type_prefix="vo"):
|
|
362
371
|
response = await resolver.client.stub.VolumeGetOrCreate(req)
|
363
372
|
self._hydrate(response.volume_id, resolver.client, response.metadata)
|
364
373
|
|
365
|
-
|
374
|
+
rep = _Volume._repr(name, environment_name)
|
375
|
+
return _Volume._from_loader(_load, rep, hydrate_lazily=True, name=name)
|
366
376
|
|
367
377
|
@classmethod
|
368
378
|
@asynccontextmanager
|
@@ -398,7 +408,13 @@ class _Volume(_Object, type_prefix="vo"):
|
|
398
408
|
async with TaskContext() as tc:
|
399
409
|
request = api_pb2.VolumeHeartbeatRequest(volume_id=response.volume_id)
|
400
410
|
tc.infinite_loop(lambda: client.stub.VolumeHeartbeat(request), sleep=_heartbeat_sleep)
|
401
|
-
yield cls._new_hydrated(
|
411
|
+
yield cls._new_hydrated(
|
412
|
+
response.volume_id,
|
413
|
+
client,
|
414
|
+
response.metadata,
|
415
|
+
is_another_app=True,
|
416
|
+
rep="modal.Volume.ephemeral()",
|
417
|
+
)
|
402
418
|
|
403
419
|
@staticmethod
|
404
420
|
async def lookup(
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|