modal 0.74.6__py3-none-any.whl → 0.74.8__py3-none-any.whl
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/_resolver.py +12 -0
- modal/_utils/blob_utils.py +2 -0
- modal/client.pyi +2 -2
- modal/config.py +20 -3
- modal/experimental/__init__.py +42 -0
- modal/mount.py +12 -0
- {modal-0.74.6.dist-info → modal-0.74.8.dist-info}/METADATA +1 -1
- {modal-0.74.6.dist-info → modal-0.74.8.dist-info}/RECORD +13 -13
- modal_version/_version_generated.py +1 -1
- {modal-0.74.6.dist-info → modal-0.74.8.dist-info}/WHEEL +0 -0
- {modal-0.74.6.dist-info → modal-0.74.8.dist-info}/entry_points.txt +0 -0
- {modal-0.74.6.dist-info → modal-0.74.8.dist-info}/licenses/LICENSE +0 -0
- {modal-0.74.6.dist-info → modal-0.74.8.dist-info}/top_level.txt +0 -0
    
        modal/_resolver.py
    CHANGED
    
    | @@ -1,6 +1,8 @@ | |
| 1 1 | 
             
            # Copyright Modal Labs 2023
         | 
| 2 2 | 
             
            import asyncio
         | 
| 3 3 | 
             
            import contextlib
         | 
| 4 | 
            +
            import os
         | 
| 5 | 
            +
            import tempfile
         | 
| 4 6 | 
             
            import typing
         | 
| 5 7 | 
             
            from asyncio import Future
         | 
| 6 8 | 
             
            from collections.abc import Hashable
         | 
| @@ -46,6 +48,7 @@ class Resolver: | |
| 46 48 | 
             
                _app_id: Optional[str]
         | 
| 47 49 | 
             
                _deduplication_cache: dict[Hashable, Future]
         | 
| 48 50 | 
             
                _client: _Client
         | 
| 51 | 
            +
                _build_start: float
         | 
| 49 52 |  | 
| 50 53 | 
             
                def __init__(
         | 
| 51 54 | 
             
                    self,
         | 
| @@ -73,6 +76,11 @@ class Resolver: | |
| 73 76 | 
             
                    self._environment_name = environment_name
         | 
| 74 77 | 
             
                    self._deduplication_cache = {}
         | 
| 75 78 |  | 
| 79 | 
            +
                    with tempfile.TemporaryFile() as temp_file:
         | 
| 80 | 
            +
                        # Use file mtime to track build start time because we will later compare this baseline
         | 
| 81 | 
            +
                        # to the mtime on mounted files, and want those measurements to have the same resolution.
         | 
| 82 | 
            +
                        self._build_start = os.fstat(temp_file.fileno()).st_mtime
         | 
| 83 | 
            +
             | 
| 76 84 | 
             
                @property
         | 
| 77 85 | 
             
                def app_id(self) -> Optional[str]:
         | 
| 78 86 | 
             
                    return self._app_id
         | 
| @@ -85,6 +93,10 @@ class Resolver: | |
| 85 93 | 
             
                def environment_name(self):
         | 
| 86 94 | 
             
                    return self._environment_name
         | 
| 87 95 |  | 
| 96 | 
            +
                @property
         | 
| 97 | 
            +
                def build_start(self) -> float:
         | 
| 98 | 
            +
                    return self._build_start
         | 
| 99 | 
            +
             | 
| 88 100 | 
             
                async def preload(self, obj, existing_object_id: Optional[str]):
         | 
| 89 101 | 
             
                    if obj._preload is not None:
         | 
| 90 102 | 
             
                        await obj._preload(obj, self, existing_object_id)
         | 
    
        modal/_utils/blob_utils.py
    CHANGED
    
    | @@ -292,6 +292,7 @@ async def blob_iter(blob_id: str, stub: ModalClientModal) -> AsyncIterator[bytes | |
| 292 292 | 
             
            class FileUploadSpec:
         | 
| 293 293 | 
             
                source: Callable[[], Union[AbstractContextManager, BinaryIO]]
         | 
| 294 294 | 
             
                source_description: Any
         | 
| 295 | 
            +
                source_is_path: bool
         | 
| 295 296 | 
             
                mount_filename: str
         | 
| 296 297 |  | 
| 297 298 | 
             
                use_blob: bool
         | 
| @@ -328,6 +329,7 @@ def _get_file_upload_spec( | |
| 328 329 | 
             
                return FileUploadSpec(
         | 
| 329 330 | 
             
                    source=source,
         | 
| 330 331 | 
             
                    source_description=source_description,
         | 
| 332 | 
            +
                    source_is_path=isinstance(source_description, Path),
         | 
| 331 333 | 
             
                    mount_filename=mount_filename.as_posix(),
         | 
| 332 334 | 
             
                    use_blob=use_blob,
         | 
| 333 335 | 
             
                    content=content,
         | 
    
        modal/client.pyi
    CHANGED
    
    | @@ -27,7 +27,7 @@ class _Client: | |
| 27 27 | 
             
                _snapshotted: bool
         | 
| 28 28 |  | 
| 29 29 | 
             
                def __init__(
         | 
| 30 | 
            -
                    self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.74. | 
| 30 | 
            +
                    self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.74.8"
         | 
| 31 31 | 
             
                ): ...
         | 
| 32 32 | 
             
                def is_closed(self) -> bool: ...
         | 
| 33 33 | 
             
                @property
         | 
| @@ -85,7 +85,7 @@ class Client: | |
| 85 85 | 
             
                _snapshotted: bool
         | 
| 86 86 |  | 
| 87 87 | 
             
                def __init__(
         | 
| 88 | 
            -
                    self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.74. | 
| 88 | 
            +
                    self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.74.8"
         | 
| 89 89 | 
             
                ): ...
         | 
| 90 90 | 
             
                def is_closed(self) -> bool: ...
         | 
| 91 91 | 
             
                @property
         | 
    
        modal/config.py
    CHANGED
    
    | @@ -87,7 +87,7 @@ import os | |
| 87 87 | 
             
            import typing
         | 
| 88 88 | 
             
            import warnings
         | 
| 89 89 | 
             
            from textwrap import dedent
         | 
| 90 | 
            -
            from typing import Any, Optional
         | 
| 90 | 
            +
            from typing import Any, Callable, Optional
         | 
| 91 91 |  | 
| 92 92 | 
             
            from google.protobuf.empty_pb2 import Empty
         | 
| 93 93 |  | 
| @@ -199,6 +199,15 @@ def _to_boolean(x: object) -> bool: | |
| 199 199 | 
             
                return str(x).lower() not in {"", "0", "false"}
         | 
| 200 200 |  | 
| 201 201 |  | 
| 202 | 
            +
            def _check_value(options: list[str]) -> Callable[[str], str]:
         | 
| 203 | 
            +
                def checker(x: str) -> str:
         | 
| 204 | 
            +
                    if x not in options:
         | 
| 205 | 
            +
                        raise ValueError(f"Must be one of {options}.")
         | 
| 206 | 
            +
                    return x
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                return checker
         | 
| 209 | 
            +
             | 
| 210 | 
            +
             | 
| 202 211 | 
             
            class _Setting(typing.NamedTuple):
         | 
| 203 212 | 
             
                default: typing.Any = None
         | 
| 204 213 | 
             
                transform: typing.Callable[[str], typing.Any] = lambda x: x  # noqa: E731
         | 
| @@ -232,6 +241,7 @@ _SETTINGS = { | |
| 232 241 | 
             
                "snapshot_debug": _Setting(False, transform=_to_boolean),
         | 
| 233 242 | 
             
                "cuda_checkpoint_path": _Setting("/__modal/.bin/cuda-checkpoint"),  # Used for snapshotting GPU memory.
         | 
| 234 243 | 
             
                "function_schemas": _Setting(False, transform=_to_boolean),
         | 
| 244 | 
            +
                "build_validation": _Setting("error", transform=_check_value(["error", "warn", "ignore"])),
         | 
| 235 245 | 
             
            }
         | 
| 236 246 |  | 
| 237 247 |  | 
| @@ -253,10 +263,17 @@ class Config: | |
| 253 263 | 
             
                        profile = _profile
         | 
| 254 264 | 
             
                    s = _SETTINGS[key]
         | 
| 255 265 | 
             
                    env_var_key = "MODAL_" + key.upper()
         | 
| 266 | 
            +
             | 
| 267 | 
            +
                    def transform(val: str) -> Any:
         | 
| 268 | 
            +
                        try:
         | 
| 269 | 
            +
                            return s.transform(val)
         | 
| 270 | 
            +
                        except Exception as e:
         | 
| 271 | 
            +
                            raise InvalidError(f"Invalid value for {key} config ({val!r}): {e}")
         | 
| 272 | 
            +
             | 
| 256 273 | 
             
                    if use_env and env_var_key in os.environ:
         | 
| 257 | 
            -
                        return  | 
| 274 | 
            +
                        return transform(os.environ[env_var_key])
         | 
| 258 275 | 
             
                    elif profile in _user_config and key in _user_config[profile]:
         | 
| 259 | 
            -
                        return  | 
| 276 | 
            +
                        return transform(_user_config[profile][key])
         | 
| 260 277 | 
             
                    else:
         | 
| 261 278 | 
             
                        return s.default
         | 
| 262 279 |  | 
    
        modal/experimental/__init__.py
    CHANGED
    
    | @@ -7,11 +7,14 @@ from typing import Literal, Optional, Union | |
| 7 7 | 
             
            from modal_proto import api_pb2
         | 
| 8 8 |  | 
| 9 9 | 
             
            from .._clustered_functions import ClusterInfo, get_cluster_info as _get_cluster_info
         | 
| 10 | 
            +
            from .._functions import _Function
         | 
| 10 11 | 
             
            from .._object import _get_environment_name
         | 
| 11 12 | 
             
            from .._partial_function import _clustered
         | 
| 12 13 | 
             
            from .._runtime.container_io_manager import _ContainerIOManager
         | 
| 13 14 | 
             
            from .._utils.async_utils import synchronize_api, synchronizer
         | 
| 15 | 
            +
            from .._utils.grpc_utils import retry_transient_errors
         | 
| 14 16 | 
             
            from ..client import _Client
         | 
| 17 | 
            +
            from ..cls import _Obj
         | 
| 15 18 | 
             
            from ..exception import InvalidError
         | 
| 16 19 | 
             
            from ..image import DockerfileSpec, ImageBuilderVersion, _Image, _ImageRegistryConfig
         | 
| 17 20 | 
             
            from ..secret import _Secret
         | 
| @@ -157,3 +160,42 @@ async def raw_registry_image( | |
| 157 160 | 
             
                    image_registry_config=registry_config,
         | 
| 158 161 | 
             
                    force_build=force_build,
         | 
| 159 162 | 
             
                )
         | 
| 163 | 
            +
             | 
| 164 | 
            +
             | 
| 165 | 
            +
            @synchronizer.create_blocking
         | 
| 166 | 
            +
            async def update_autoscaler(
         | 
| 167 | 
            +
                obj: Union[_Function, _Obj],
         | 
| 168 | 
            +
                *,
         | 
| 169 | 
            +
                min_containers: Optional[int] = None,
         | 
| 170 | 
            +
                max_containers: Optional[int] = None,
         | 
| 171 | 
            +
                buffer_containers: Optional[int] = None,
         | 
| 172 | 
            +
                scaledown_window: Optional[int] = None,
         | 
| 173 | 
            +
                client: Optional[_Client] = None,
         | 
| 174 | 
            +
            ) -> None:
         | 
| 175 | 
            +
                """Update the autoscaler settings for a Function or Obj (instance of a Cls).
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                This is an experimental interface for a feature that we will be adding to
         | 
| 178 | 
            +
                replace the existing `.keep_warm()` method. The stable form of this interface
         | 
| 179 | 
            +
                may look different (i.e., it may be a standalone function or a method).
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                """
         | 
| 182 | 
            +
                settings = api_pb2.AutoscalerSettings(
         | 
| 183 | 
            +
                    min_containers=min_containers,
         | 
| 184 | 
            +
                    max_containers=max_containers,
         | 
| 185 | 
            +
                    buffer_containers=buffer_containers,
         | 
| 186 | 
            +
                    scaledown_window=scaledown_window,
         | 
| 187 | 
            +
                )
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                if client is None:
         | 
| 190 | 
            +
                    client = await _Client.from_env()
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                if isinstance(obj, _Function):
         | 
| 193 | 
            +
                    f = obj
         | 
| 194 | 
            +
                else:
         | 
| 195 | 
            +
                    assert obj._cls._class_service_function is not None
         | 
| 196 | 
            +
                    await obj._cls._class_service_function.hydrate(client=client)
         | 
| 197 | 
            +
                    f = obj._cached_service_function()
         | 
| 198 | 
            +
                await f.hydrate(client=client)
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                request = api_pb2.FunctionUpdateSchedulingParamsRequest(function_id=f.object_id, settings=settings)
         | 
| 201 | 
            +
                await retry_transient_errors(client.stub.FunctionUpdateSchedulingParams, request)
         | 
    
        modal/mount.py
    CHANGED
    
    | @@ -9,6 +9,7 @@ import sys | |
| 9 9 | 
             
            import sysconfig
         | 
| 10 10 | 
             
            import time
         | 
| 11 11 | 
             
            import typing
         | 
| 12 | 
            +
            import warnings
         | 
| 12 13 | 
             
            from collections.abc import AsyncGenerator
         | 
| 13 14 | 
             
            from pathlib import Path, PurePosixPath
         | 
| 14 15 | 
             
            from typing import Callable, Optional, Sequence, Union
         | 
| @@ -532,6 +533,17 @@ class _Mount(_Object, type_prefix="mo"): | |
| 532 533 | 
             
                            n_finished += 1
         | 
| 533 534 | 
             
                            return mount_file
         | 
| 534 535 |  | 
| 536 | 
            +
                        # Try to catch cases where user modified their local files (e.g. changed git branches)
         | 
| 537 | 
            +
                        # between triggering a build and Modal actually uploading the file
         | 
| 538 | 
            +
                        if config.get("build_validation") != "ignore" and file_spec.source_is_path:
         | 
| 539 | 
            +
                            mtime = os.stat(file_spec.source_description).st_mtime
         | 
| 540 | 
            +
                            if mtime > resolver.build_start:
         | 
| 541 | 
            +
                                msg = f"{file_spec.source_description} was modified during build process."
         | 
| 542 | 
            +
                                if config.get("build_validation") == "error":
         | 
| 543 | 
            +
                                    raise modal.exception.ExecutionError(msg)
         | 
| 544 | 
            +
                                elif config.get("build_validation") == "warn":
         | 
| 545 | 
            +
                                    warnings.warn(msg)
         | 
| 546 | 
            +
             | 
| 535 547 | 
             
                        request = api_pb2.MountPutFileRequest(sha256_hex=file_spec.sha256_hex)
         | 
| 536 548 | 
             
                        accounted_hashes.add(file_spec.sha256_hex)
         | 
| 537 549 | 
             
                        response = await retry_transient_errors(resolver.client.stub.MountPutFile, request, base_delay=1)
         | 
| @@ -10,7 +10,7 @@ modal/_object.py,sha256=JBIECWdfpRKCaCxVWZbC3Q1kF5Whk_EKvY9f4Y6AFyg,11446 | |
| 10 10 | 
             
            modal/_output.py,sha256=Z0nngPh2mKHMQc4MQ92YjVPc3ewOLa3I4dFBlL9nvQY,25656
         | 
| 11 11 | 
             
            modal/_partial_function.py,sha256=8mmd5lvjZaC7qi0KAnLR1H590MlxNslAE2_Kr9biJUA,39704
         | 
| 12 12 | 
             
            modal/_pty.py,sha256=JZfPDDpzqICZqtyPI_oMJf_9w-p_lLNuzHhwhodUXio,1329
         | 
| 13 | 
            -
            modal/_resolver.py,sha256= | 
| 13 | 
            +
            modal/_resolver.py,sha256=owmQ72ZuGvrTpHxguTMYJyodnfeYcSP0MPV8wvkGa74,7375
         | 
| 14 14 | 
             
            modal/_resources.py,sha256=5qmcirXUI8dSH926nwkUaeX9H25mqYu9mXD_KuT79-o,1733
         | 
| 15 15 | 
             
            modal/_serialization.py,sha256=wAgaALThfr-DBV9LMhM4qY_PCH7SRhA9xgoHL2bapBk,22963
         | 
| 16 16 | 
             
            modal/_traceback.py,sha256=IZQzB3fVlUfMHOSyKUgw0H6qv4yHnpyq-XVCNZKfUdA,5023
         | 
| @@ -22,12 +22,12 @@ modal/app.py,sha256=4EeD3MXXpaeSFatuWt80xGbMH9cSYS3b9m9z3PQDlwU,48144 | |
| 22 22 | 
             
            modal/app.pyi,sha256=SkqXNrdnGIZ4MmNNvpGtzNLoUdyuvi9IjQQR_DRiRHk,26968
         | 
| 23 23 | 
             
            modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
         | 
| 24 24 | 
             
            modal/client.py,sha256=U-YKSw0n7J1ZLREt9cbEJCtmHe5YoPKFxl0xlkan2yc,15565
         | 
| 25 | 
            -
            modal/client.pyi,sha256= | 
| 25 | 
            +
            modal/client.pyi,sha256=nR5ZYzOwOa9b-5B_PiZ4Ddtu_KKfN2KpAHO2UQEaan8,7591
         | 
| 26 26 | 
             
            modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
         | 
| 27 27 | 
             
            modal/cloud_bucket_mount.pyi,sha256=30T3K1a89l6wzmEJ_J9iWv9SknoGqaZDx59Xs-ZQcmk,1607
         | 
| 28 28 | 
             
            modal/cls.py,sha256=GvaNl8R5UsH7Vg88WEOyerdjvZEPK7xxi3nqHlyOW_c,33497
         | 
| 29 29 | 
             
            modal/cls.pyi,sha256=pTYO9JsRENmsa5pDgzfoRJGm_NpCvEjEx--vs-jJkj8,10902
         | 
| 30 | 
            -
            modal/config.py,sha256= | 
| 30 | 
            +
            modal/config.py,sha256=nKlX60bC1O-qAEsbGq-efRX1q25h13RyVnoM_0bnhSw,12229
         | 
| 31 31 | 
             
            modal/container_process.py,sha256=vvyK3DVPUMsuqvkKdUiQ49cDLF9JawGrxpglLk5vfgI,6208
         | 
| 32 32 | 
             
            modal/container_process.pyi,sha256=bXs2KHe7nxVuLAm6RRBqXCvDKelANGX9gFY8qIuZYDs,2898
         | 
| 33 33 | 
             
            modal/dict.py,sha256=3Pb45IkfqcDGXu3VVStJVbC_QYk6RTRXrMbZxtByAAk,13354
         | 
| @@ -45,7 +45,7 @@ modal/image.py,sha256=I-9_YZL0SSfnuGPywa3-4PlxDmJ-53p7ce3gP74SrOA,92877 | |
| 45 45 | 
             
            modal/image.pyi,sha256=89zv12C1sFrJs7Es9SnX23_m208ASAdeNGCVTrhjzHI,25632
         | 
| 46 46 | 
             
            modal/io_streams.py,sha256=YDZVQSDv05DeXg5TwcucC9Rj5hQBx2GXdluan9rIUpw,15467
         | 
| 47 47 | 
             
            modal/io_streams.pyi,sha256=RpXIWFm6fQkLJRc1uxd0KkQ2wTLCB65jRlyGplU6CQE,5100
         | 
| 48 | 
            -
            modal/mount.py,sha256= | 
| 48 | 
            +
            modal/mount.py,sha256=VruBgKrCXD_mmv7iXEfSYERQ3CwH7iqymA3v-5xLGMc,32685
         | 
| 49 49 | 
             
            modal/mount.pyi,sha256=CmHa7zKSxHA_7-vMQLnGfw_ZXvAvHlafvUEVJcQ1LQA,12535
         | 
| 50 50 | 
             
            modal/network_file_system.py,sha256=WXdyL7du_fvjvuG6hSAREyJ83sSEP2xSLAIAhBsisdI,14869
         | 
| 51 51 | 
             
            modal/network_file_system.pyi,sha256=4N3eqMbTSlqmS8VV_aJK-uvrgJC8xnf_YtW5FHfRfc8,8156
         | 
| @@ -92,7 +92,7 @@ modal/_runtime/user_code_imports.py,sha256=kAv37Pl1TmGKduv0Kozum0xNTD42bDLloSIsT | |
| 92 92 | 
             
            modal/_utils/__init__.py,sha256=waLjl5c6IPDhSsdWAm9Bji4e2PVxamYABKAze6CHVXY,28
         | 
| 93 93 | 
             
            modal/_utils/app_utils.py,sha256=88BT4TPLWfYAQwKTHcyzNQRHg8n9B-QE2UyJs96iV-0,108
         | 
| 94 94 | 
             
            modal/_utils/async_utils.py,sha256=b2TJyKY1Hq7df7M-fo3qlFM95mGdo3dCuqRPPcV5hsE,27445
         | 
| 95 | 
            -
            modal/_utils/blob_utils.py,sha256= | 
| 95 | 
            +
            modal/_utils/blob_utils.py,sha256=jWJovk4g-YNG3CvkvglOds4a6D1M0Tcal_59v7y9VsM,14591
         | 
| 96 96 | 
             
            modal/_utils/bytes_io_segment_payload.py,sha256=uunxVJS4PE1LojF_UpURMzVK9GuvmYWRqQo_bxEj5TU,3385
         | 
| 97 97 | 
             
            modal/_utils/deprecation.py,sha256=EXP1beU4pmEqEzWMLw6E3kUfNfpmNA_VOp6i0EHi93g,4856
         | 
| 98 98 | 
             
            modal/_utils/docker_utils.py,sha256=h1uETghR40mp_y3fSWuZAfbIASH1HMzuphJHghAL6DU,3722
         | 
| @@ -136,7 +136,7 @@ modal/cli/volume.py,sha256=c2IuVNO2yJVaXmZkRh3xwQmznlRTgFoJr_BIzzqtVv0,10251 | |
| 136 136 | 
             
            modal/cli/programs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
         | 
| 137 137 | 
             
            modal/cli/programs/run_jupyter.py,sha256=YVvJYu927A4ji72d6i27CKfyZ_uDWteeittARtJnf7E,2775
         | 
| 138 138 | 
             
            modal/cli/programs/vscode.py,sha256=kfvhZQ4bJwtVm3MgC1V7AlygZOlKT1a33alr_uwrewA,3473
         | 
| 139 | 
            -
            modal/experimental/__init__.py,sha256= | 
| 139 | 
            +
            modal/experimental/__init__.py,sha256=GCE8vAcVj2nQB0-v2j49mQBsHpAQkbmCTths9lJffNw,7962
         | 
| 140 140 | 
             
            modal/experimental/ipython.py,sha256=epLUZeDSdE226TH_tU3igRKCiVuQi99mUOrIJ4SemOE,2792
         | 
| 141 141 | 
             
            modal/requirements/2023.12.312.txt,sha256=zWWUVgVQ92GXBKNYYr2-5vn9rlnXcmkqlwlX5u1eTYw,400
         | 
| 142 142 | 
             
            modal/requirements/2023.12.txt,sha256=OjsbXFkCSdkzzryZP82Q73osr5wxQ6EUzmGcK7twfkA,502
         | 
| @@ -145,7 +145,7 @@ modal/requirements/2024.10.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddR | |
| 145 145 | 
             
            modal/requirements/PREVIEW.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddRo,296
         | 
| 146 146 | 
             
            modal/requirements/README.md,sha256=9tK76KP0Uph7O0M5oUgsSwEZDj5y-dcUPsnpR0Sc-Ik,854
         | 
| 147 147 | 
             
            modal/requirements/base-images.json,sha256=57vMSqzMbLBxw5tFWSaMiIkkVEps4JfX5PAtXGnkS4U,740
         | 
| 148 | 
            -
            modal-0.74. | 
| 148 | 
            +
            modal-0.74.8.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
         | 
| 149 149 | 
             
            modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
         | 
| 150 150 | 
             
            modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
         | 
| 151 151 | 
             
            modal_docs/gen_reference_docs.py,sha256=cvTgltucqYLLIX84QxAwf51Z5Vc2n6cLxS8VcrxNCAo,6401
         | 
| @@ -170,9 +170,9 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y | |
| 170 170 | 
             
            modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 171 171 | 
             
            modal_version/__init__.py,sha256=m94xZNWIjH8oUtJk4l9xfovzDJede2o7X-q0MHVECtM,470
         | 
| 172 172 | 
             
            modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
         | 
| 173 | 
            -
            modal_version/_version_generated.py,sha256= | 
| 174 | 
            -
            modal-0.74. | 
| 175 | 
            -
            modal-0.74. | 
| 176 | 
            -
            modal-0.74. | 
| 177 | 
            -
            modal-0.74. | 
| 178 | 
            -
            modal-0.74. | 
| 173 | 
            +
            modal_version/_version_generated.py,sha256=SKRywF4xkghsAUSPFoIkr9QXNxiWC-hTZXuIpgTd91M,148
         | 
| 174 | 
            +
            modal-0.74.8.dist-info/METADATA,sha256=HsM0NqrOdeyaB2HjUUJLwmm0xvXNNtxX1jxmhsw9ARk,2473
         | 
| 175 | 
            +
            modal-0.74.8.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
         | 
| 176 | 
            +
            modal-0.74.8.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
         | 
| 177 | 
            +
            modal-0.74.8.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
         | 
| 178 | 
            +
            modal-0.74.8.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |