modal 1.0.6.dev8__py3-none-any.whl → 1.0.6.dev15__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.

Potentially problematic release.


This version of modal might be problematic. Click here for more details.

modal/image.py CHANGED
@@ -1222,6 +1222,114 @@ class _Image(_Object, type_prefix="im"):
1222
1222
  gpu_config=parse_gpu_config(gpu),
1223
1223
  )
1224
1224
 
1225
+ def uv_pip_install(
1226
+ self,
1227
+ *packages: Union[str, list[str]], # A list of Python packages, eg. ["numpy", "matplotlib>=3.5.0"]
1228
+ requirements: Optional[list[str]] = None, # Passes -r (--requirements) to uv pip install
1229
+ find_links: Optional[str] = None, # Passes -f (--find-links) to uv pip install
1230
+ index_url: Optional[str] = None, # Passes -i (--index-url) to uv pip install
1231
+ extra_index_url: Optional[str] = None, # Passes --extra-index-url to uv pip install
1232
+ pre: bool = False, # Allow pre-releases using uv pip install --prerelease allow
1233
+ extra_options: str = "", # Additional options to pass to pip install, e.g. "--no-build-isolation"
1234
+ force_build: bool = False, # Ignore cached builds, similar to 'docker build --no-cache'
1235
+ uv_version: Optional[str] = None, # uv version to use
1236
+ secrets: Sequence[_Secret] = [],
1237
+ gpu: GPU_T = None,
1238
+ ) -> "_Image":
1239
+ """Install a list of Python packages using uv pip install.
1240
+
1241
+ **Examples**
1242
+
1243
+ Simple installation:
1244
+ ```python
1245
+ image = modal.Image.debian_slim().uv_pip_install("torch==2.7.1", "numpy")
1246
+ ```
1247
+
1248
+ This method assumes that:
1249
+ - Python is on the `$PATH` and dependencies are installed with the first Python on the `$PATH`.
1250
+ - Shell supports backticks for substitution
1251
+ - `which` command is on the `$PATH`
1252
+ """
1253
+ pkgs = _flatten_str_args("uv_pip_install", "packages", packages)
1254
+
1255
+ if requirements is None or isinstance(requirements, list):
1256
+ requirements = requirements or []
1257
+ else:
1258
+ raise InvalidError("requirements must be None or a list of strings")
1259
+
1260
+ if not pkgs and not requirements:
1261
+ return self
1262
+ elif not _validate_packages(pkgs):
1263
+ raise InvalidError(
1264
+ "Package list for `Image.uv_pip_install` cannot contain other arguments;"
1265
+ " try the `extra_options` parameter instead."
1266
+ )
1267
+
1268
+ def build_dockerfile(version: ImageBuilderVersion) -> DockerfileSpec:
1269
+ commands = ["FROM base"]
1270
+ UV_ROOT = "/.uv"
1271
+ if uv_version is None:
1272
+ commands.append(f"COPY --from=ghcr.io/astral-sh/uv:latest /uv {UV_ROOT}/uv")
1273
+ else:
1274
+ commands.append(f"COPY --from=ghcr.io/astral-sh/uv:{uv_version} /uv {UV_ROOT}/uv")
1275
+
1276
+ # NOTE: Using `which python` assumes:
1277
+ # - python is on the PATH and uv is installing into the first python in the PATH
1278
+ # - the shell supports backticks for substitution
1279
+ # - `which` command is on the PATH
1280
+ uv_pip_args = ["--python `which python`", "--compile-bytecode"]
1281
+ context_files = {}
1282
+
1283
+ if find_links:
1284
+ uv_pip_args.append(f"--find-links {shlex.quote(find_links)}")
1285
+ if index_url:
1286
+ uv_pip_args.append(f"--index-url {shlex.quote(index_url)}")
1287
+ if extra_index_url:
1288
+ uv_pip_args.append(f"--extra-index-url {shlex.quote(extra_index_url)}")
1289
+ if pre:
1290
+ uv_pip_args.append("--prerelease allow")
1291
+ if extra_options:
1292
+ uv_pip_args.append(extra_options)
1293
+
1294
+ if requirements:
1295
+
1296
+ def _generate_paths(idx: int, req: str) -> dict:
1297
+ local_path = os.path.expanduser(req)
1298
+ basename = os.path.basename(req)
1299
+
1300
+ # The requirement files can have the same name but in different directories:
1301
+ # requirements=["test/requirements.txt", "a/b/c/requirements.txt"]
1302
+ # To uniquely identify these files, we add a `idx` prefix to every file's basename
1303
+ # - `test/requirements.txt` -> `/.0_requirements.txt` in context -> `/.uv/0/requirements.txt` to uv
1304
+ # - `a/b/c/requirements.txt` -> `/.1_requirements.txt` in context -> `/.uv/1/requirements.txt` to uv
1305
+ return {
1306
+ "local_path": local_path,
1307
+ "context_path": f"/.{idx}_{basename}",
1308
+ "dest_path": f"{UV_ROOT}/{idx}/{basename}",
1309
+ }
1310
+
1311
+ requirement_paths = [_generate_paths(idx, req) for idx, req in enumerate(requirements)]
1312
+ requirements_cli = " ".join(f"--requirements {req['dest_path']}" for req in requirement_paths)
1313
+ uv_pip_args.append(requirements_cli)
1314
+
1315
+ commands.extend([f"COPY {req['context_path']} {req['dest_path']}" for req in requirement_paths])
1316
+ context_files.update({req["context_path"]: req["local_path"] for req in requirement_paths})
1317
+
1318
+ uv_pip_args.extend(shlex.quote(p) for p in sorted(pkgs))
1319
+ uv_pip_args_joined = " ".join(uv_pip_args)
1320
+
1321
+ commands.append(f"RUN {UV_ROOT}/uv pip install {uv_pip_args_joined}")
1322
+
1323
+ return DockerfileSpec(commands=commands, context_files=context_files)
1324
+
1325
+ return _Image._from_args(
1326
+ base_images={"base": self},
1327
+ dockerfile_function=build_dockerfile,
1328
+ force_build=self.force_build or force_build,
1329
+ gpu_config=parse_gpu_config(gpu),
1330
+ secrets=secrets,
1331
+ )
1332
+
1225
1333
  def poetry_install_from_file(
1226
1334
  self,
1227
1335
  poetry_pyproject_toml: str,
@@ -1312,6 +1420,149 @@ class _Image(_Object, type_prefix="im"):
1312
1420
  gpu_config=parse_gpu_config(gpu),
1313
1421
  )
1314
1422
 
1423
+ def uv_sync(
1424
+ self,
1425
+ uv_project_dir: str = "./", # Path to local uv managed project
1426
+ *,
1427
+ force_build: bool = False, # Ignore cached builds, similar to 'docker build --no-cache'
1428
+ groups: Optional[list[str]] = None, # Dependency group to install using `uv sync --group`
1429
+ extras: Optional[list[str]] = None, # Optional dependencies to install using `uv sync --extra`
1430
+ frozen: bool = True, # If True, then we run `uv sync --frozen` when a uv.lock file is present
1431
+ extra_options: str = "", # Extra options to pass to `uv sync`
1432
+ uv_version: Optional[str] = None, # uv version to use
1433
+ secrets: Sequence[_Secret] = [],
1434
+ gpu: GPU_T = None,
1435
+ ) -> "_Image":
1436
+ """Creates a virtual environment with the dependencies in a uv managed project with `uv sync`.
1437
+
1438
+ **Examples**
1439
+ ```python
1440
+ image = modal.Image.debian_slim().uv_sync()
1441
+ ```
1442
+ """
1443
+
1444
+ def _normalize_items(items, name) -> list[str]:
1445
+ if items is None:
1446
+ return []
1447
+ elif isinstance(items, list):
1448
+ return items
1449
+ else:
1450
+ raise InvalidError(f"{name} must be None or a list of strings")
1451
+
1452
+ groups = _normalize_items(groups, "groups")
1453
+ extras = _normalize_items(extras, "extras")
1454
+
1455
+ def _check_pyproject_toml(pyproject_toml: str, version: ImageBuilderVersion):
1456
+ if not os.path.exists(pyproject_toml):
1457
+ raise InvalidError(f"Expected {pyproject_toml} to exist")
1458
+
1459
+ import toml
1460
+
1461
+ with open(pyproject_toml) as f:
1462
+ pyproject_toml_content = toml.load(f)
1463
+
1464
+ if (
1465
+ "tool" in pyproject_toml_content
1466
+ and "uv" in pyproject_toml_content["tool"]
1467
+ and "workspace" in pyproject_toml_content["tool"]["uv"]
1468
+ ):
1469
+ raise InvalidError("uv workspaces are not supported")
1470
+
1471
+ if version > "2024.10":
1472
+ # For builder version > 2024.10, modal is mounted at runtime and is not
1473
+ # a requirement in `uv.lock`
1474
+ return
1475
+
1476
+ dependencies = pyproject_toml_content["project"]["dependencies"]
1477
+
1478
+ for group in groups:
1479
+ if (
1480
+ "dependency-groups" in pyproject_toml_content
1481
+ and group in pyproject_toml_content["dependency-groups"]
1482
+ ):
1483
+ dependencies += pyproject_toml_content["dependency-groups"][group]
1484
+
1485
+ for extra in extras:
1486
+ if (
1487
+ "project" in pyproject_toml_content
1488
+ and "optional-dependencies" in pyproject_toml_content["project"]
1489
+ and extra in pyproject_toml_content["project"]["optional-dependencies"]
1490
+ ):
1491
+ dependencies += pyproject_toml_content["project"]["optional-dependencies"][extra]
1492
+
1493
+ PACKAGE_REGEX = re.compile(r"^[\w-]+")
1494
+
1495
+ def _extract_package(package) -> str:
1496
+ m = PACKAGE_REGEX.match(package)
1497
+ return m.group(0) if m else ""
1498
+
1499
+ if not any(_extract_package(dependency) == "modal" for dependency in dependencies):
1500
+ raise InvalidError(
1501
+ "Image builder version <= 2024.10 requires modal to be specified in your pyproject.toml file"
1502
+ )
1503
+
1504
+ def build_dockerfile(version: ImageBuilderVersion) -> DockerfileSpec:
1505
+ uv_project_dir_ = os.path.expanduser(uv_project_dir)
1506
+ pyproject_toml = os.path.join(uv_project_dir_, "pyproject.toml")
1507
+
1508
+ UV_ROOT = "/.uv"
1509
+ uv_sync_args = [
1510
+ f"--project={UV_ROOT}",
1511
+ "--no-install-workspace", # Do not install the root project or any "uv workspace"
1512
+ "--compile-bytecode",
1513
+ ]
1514
+
1515
+ for group in groups:
1516
+ uv_sync_args.append(f"--group={group}")
1517
+ for extra in extras:
1518
+ uv_sync_args.append(f"--extra={extra}")
1519
+ if extra_options:
1520
+ uv_sync_args.append(extra_options)
1521
+
1522
+ commands = ["FROM base"]
1523
+
1524
+ if uv_version is None:
1525
+ commands.append(f"COPY --from=ghcr.io/astral-sh/uv:latest /uv {UV_ROOT}/uv")
1526
+ else:
1527
+ commands.append(f"COPY --from=ghcr.io/astral-sh/uv:{uv_version} /uv {UV_ROOT}/uv")
1528
+
1529
+ context_files = {}
1530
+
1531
+ _check_pyproject_toml(pyproject_toml, version)
1532
+
1533
+ context_files["/.pyproject.toml"] = pyproject_toml
1534
+ commands.append(f"COPY /.pyproject.toml {UV_ROOT}/pyproject.toml")
1535
+
1536
+ uv_lock = os.path.join(uv_project_dir_, "uv.lock")
1537
+ if os.path.exists(uv_lock):
1538
+ context_files["/.uv.lock"] = uv_lock
1539
+ commands.append(f"COPY /.uv.lock {UV_ROOT}/uv.lock")
1540
+
1541
+ if frozen:
1542
+ # Do not update `uv.lock` when we have one when `frozen=True`. This it ehd efault because this
1543
+ # ensures that the runtime environment matches the local `uv.lock`.
1544
+ #
1545
+ # If `frozen=False`, then `uv sync` will update the the dependencies in the `uv.lock` file
1546
+ # during build time.
1547
+ uv_sync_args.append("--frozen")
1548
+
1549
+ uv_sync_args_joined = " ".join(uv_sync_args).strip()
1550
+
1551
+ commands += [
1552
+ f"RUN {UV_ROOT}/uv sync {uv_sync_args_joined}",
1553
+ f"ENV PATH={UV_ROOT}/.venv/bin:$PATH",
1554
+ ]
1555
+
1556
+ return DockerfileSpec(commands=commands, context_files=context_files)
1557
+
1558
+ return _Image._from_args(
1559
+ base_images={"base": self},
1560
+ dockerfile_function=build_dockerfile,
1561
+ force_build=self.force_build or force_build,
1562
+ secrets=secrets,
1563
+ gpu_config=parse_gpu_config(gpu),
1564
+ )
1565
+
1315
1566
  def dockerfile_commands(
1316
1567
  self,
1317
1568
  *dockerfile_commands: Union[str, list[str]],
modal/image.pyi CHANGED
@@ -505,6 +505,36 @@ class _Image(modal._object._Object):
505
505
  """
506
506
  ...
507
507
 
508
+ def uv_pip_install(
509
+ self,
510
+ *packages: typing.Union[str, list[str]],
511
+ requirements: typing.Optional[list[str]] = None,
512
+ find_links: typing.Optional[str] = None,
513
+ index_url: typing.Optional[str] = None,
514
+ extra_index_url: typing.Optional[str] = None,
515
+ pre: bool = False,
516
+ extra_options: str = "",
517
+ force_build: bool = False,
518
+ uv_version: typing.Optional[str] = None,
519
+ secrets: collections.abc.Sequence[modal.secret._Secret] = [],
520
+ gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
521
+ ) -> _Image:
522
+ """Install a list of Python packages using uv pip install.
523
+
524
+ **Examples**
525
+
526
+ Simple installation:
527
+ ```python
528
+ image = modal.Image.debian_slim().uv_pip_install("torch==2.7.1", "numpy")
529
+ ```
530
+
531
+ This method assumes that:
532
+ - Python is on the `$PATH` and dependencies are installed with the first Python on the `$PATH`.
533
+ - Shell supports backticks for substitution
534
+ - `which` command is on the `$PATH`
535
+ """
536
+ ...
537
+
508
538
  def poetry_install_from_file(
509
539
  self,
510
540
  poetry_pyproject_toml: str,
@@ -534,6 +564,28 @@ class _Image(modal._object._Object):
534
564
  """
535
565
  ...
536
566
 
567
+ def uv_sync(
568
+ self,
569
+ uv_project_dir: str = "./",
570
+ *,
571
+ force_build: bool = False,
572
+ groups: typing.Optional[list[str]] = None,
573
+ extras: typing.Optional[list[str]] = None,
574
+ frozen: bool = True,
575
+ extra_options: str = "",
576
+ uv_version: typing.Optional[str] = None,
577
+ secrets: collections.abc.Sequence[modal.secret._Secret] = [],
578
+ gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
579
+ ) -> _Image:
580
+ """Creates a virtual environment with the dependencies in a uv managed project with `uv sync`.
581
+
582
+ **Examples**
583
+ ```python
584
+ image = modal.Image.debian_slim().uv_sync()
585
+ ```
586
+ """
587
+ ...
588
+
537
589
  def dockerfile_commands(
538
590
  self,
539
591
  *dockerfile_commands: typing.Union[str, list[str]],
@@ -1348,6 +1400,36 @@ class Image(modal.object.Object):
1348
1400
  """
1349
1401
  ...
1350
1402
 
1403
+ def uv_pip_install(
1404
+ self,
1405
+ *packages: typing.Union[str, list[str]],
1406
+ requirements: typing.Optional[list[str]] = None,
1407
+ find_links: typing.Optional[str] = None,
1408
+ index_url: typing.Optional[str] = None,
1409
+ extra_index_url: typing.Optional[str] = None,
1410
+ pre: bool = False,
1411
+ extra_options: str = "",
1412
+ force_build: bool = False,
1413
+ uv_version: typing.Optional[str] = None,
1414
+ secrets: collections.abc.Sequence[modal.secret.Secret] = [],
1415
+ gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
1416
+ ) -> Image:
1417
+ """Install a list of Python packages using uv pip install.
1418
+
1419
+ **Examples**
1420
+
1421
+ Simple installation:
1422
+ ```python
1423
+ image = modal.Image.debian_slim().uv_pip_install("torch==2.7.1", "numpy")
1424
+ ```
1425
+
1426
+ This method assumes that:
1427
+ - Python is on the `$PATH` and dependencies are installed with the first Python on the `$PATH`.
1428
+ - Shell supports backticks for substitution
1429
+ - `which` command is on the `$PATH`
1430
+ """
1431
+ ...
1432
+
1351
1433
  def poetry_install_from_file(
1352
1434
  self,
1353
1435
  poetry_pyproject_toml: str,
@@ -1377,6 +1459,28 @@ class Image(modal.object.Object):
1377
1459
  """
1378
1460
  ...
1379
1461
 
1462
+ def uv_sync(
1463
+ self,
1464
+ uv_project_dir: str = "./",
1465
+ *,
1466
+ force_build: bool = False,
1467
+ groups: typing.Optional[list[str]] = None,
1468
+ extras: typing.Optional[list[str]] = None,
1469
+ frozen: bool = True,
1470
+ extra_options: str = "",
1471
+ uv_version: typing.Optional[str] = None,
1472
+ secrets: collections.abc.Sequence[modal.secret.Secret] = [],
1473
+ gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
1474
+ ) -> Image:
1475
+ """Creates a virtual environment with the dependencies in a uv managed project with `uv sync`.
1476
+
1477
+ **Examples**
1478
+ ```python
1479
+ image = modal.Image.debian_slim().uv_sync()
1480
+ ```
1481
+ """
1482
+ ...
1483
+
1380
1484
  def dockerfile_commands(
1381
1485
  self,
1382
1486
  *dockerfile_commands: typing.Union[str, list[str]],
modal/parallel_map.py CHANGED
@@ -139,7 +139,14 @@ async def _map_invocation(
139
139
  idx = inputs_created
140
140
  update_state(set_inputs_created=inputs_created + 1)
141
141
  (args, kwargs) = argskwargs
142
- return await _create_input(args, kwargs, client.stub, idx=idx, method_name=function._use_method_name)
142
+ return await _create_input(
143
+ args,
144
+ kwargs,
145
+ client.stub,
146
+ max_object_size_bytes=function._max_object_size_bytes,
147
+ idx=idx,
148
+ method_name=function._use_method_name,
149
+ )
143
150
 
144
151
  async def input_iter():
145
152
  while 1:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.6.dev8
3
+ Version: 1.0.6.dev15
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -2,8 +2,8 @@ modal/__init__.py,sha256=1131svUxi876UMFC6Z68qe5Z031ZfZ9NrduvGwHphj8,2710
2
2
  modal/__main__.py,sha256=sTJcc9EbDuCKSwg3tL6ZckFw9WWdlkXW8mId1IvJCNc,2846
3
3
  modal/_clustered_functions.py,sha256=kTf-9YBXY88NutC1akI-gCbvf01RhMPCw-zoOI_YIUE,2700
4
4
  modal/_clustered_functions.pyi,sha256=_QKM87tdYwcALSGth8a0-9qXl02fZK6zMfEGEoYz7eA,1007
5
- modal/_container_entrypoint.py,sha256=2Zx9O_EMJg0H77EdnC2vGKs6uFMWwbP1NLFf-qYmWmU,28962
6
- modal/_functions.py,sha256=Qt1QYZ84kqilJ4PYYOLfUy4b6jKv6YyWdJoFxU0xBHw,81072
5
+ modal/_container_entrypoint.py,sha256=1qBMNY_E9ICC_sRCtillMxmKPsmxJl1J0_qOAG8rH-0,28288
6
+ modal/_functions.py,sha256=kZf0EdIgEYnHuXasjOX3fsJktjZMA1n3rPXEscKMuJU,82303
7
7
  modal/_ipython.py,sha256=TW1fkVOmZL3YYqdS2YlM1hqpf654Yf8ZyybHdBnlhSw,301
8
8
  modal/_location.py,sha256=joiX-0ZeutEUDTrrqLF1GHXCdVLF-rHzstocbMcd_-k,366
9
9
  modal/_object.py,sha256=QWyUGjrGLupITkyvJru2cekizsaVdteAhwMQlw_tE4k,11172
@@ -22,7 +22,7 @@ modal/app.py,sha256=fCKq3TJ2Y5LB2WKNs6pp_5XECNH5avUL01jQljuoYRU,46603
22
22
  modal/app.pyi,sha256=Z6wi_dkXywiaM2rvAvguj2Wgu9ZgPjMSLl1nH1a7EYI,42243
23
23
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
24
24
  modal/client.py,sha256=OwISJvkgMb-rHm9Gc4i-7YcDgGiZgwJ7F_PzwZH7a6Q,16847
25
- modal/client.pyi,sha256=F0JvLqFF2KdeFO-kDVo--6m5sW_J97l0agyaUV4T54U,15079
25
+ modal/client.pyi,sha256=VHfIgRYvvssOL4KatMYRcm9n3IqRdktL3OHfz7LnFuM,15081
26
26
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
27
27
  modal/cloud_bucket_mount.pyi,sha256=-qSfYAQvIoO_l2wsCCGTG5ZUwQieNKXdAO00yP1-LYU,7394
28
28
  modal/cls.py,sha256=EFrM949jNXJpmwB2G_1d28b8IpHShfKIEIaiPkZqeOU,39881
@@ -41,8 +41,8 @@ modal/file_pattern_matcher.py,sha256=urAue8es8jxqX94k9EYoZxxhtfgOlsEES8lbFHOorzc
41
41
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
42
42
  modal/functions.pyi,sha256=FJe_91dSrMCRNVT-YV1UhtxFKzIvL_C5q8xdk08-wT8,34840
43
43
  modal/gpu.py,sha256=Fe5ORvVPDIstSq1xjmM6OoNgLYFWvogP9r5BgmD3hYg,6769
44
- modal/image.py,sha256=W0Xg-nhsuLDO6weC1lk07MWVZFgZAxRdFqaA-Lt6_AI,94068
45
- modal/image.pyi,sha256=ha8QhMPDRmfTSoRlQ8CgV4-AZ7kYKK_-R2UXLyGPgQU,68172
44
+ modal/image.py,sha256=lfbLICSDz4DPEiSipvGasL8EEu8ydHeyn3qBwgFPgBo,105262
45
+ modal/image.pyi,sha256=RGxpmYZUJXtZrH9H3xPHdfHFd_KpmDp3ZHrDS8vUKlI,71760
46
46
  modal/io_streams.py,sha256=FUDpBsVK8isqwyC7DtAcQZhaHlMFSaNZGhYJOg-SFW0,15590
47
47
  modal/io_streams.pyi,sha256=5b3b93ztZeR8IpJtNIGffX24QLPgocE4-gAps8y7CKU,13824
48
48
  modal/mount.py,sha256=VrExPZApUnuh9shJx-tzdmQJ9ASTSK-SEaYHDBkQl-k,36632
@@ -52,7 +52,7 @@ modal/network_file_system.pyi,sha256=Td_IobHr84iLo_9LZKQ4tNdUB60yjX8QWBaFiUvhfi8
52
52
  modal/object.py,sha256=bTeskuY8JFrESjU4_UL_nTwYlBQdOLmVaOX3X6EMxsg,164
53
53
  modal/object.pyi,sha256=751TV6BntarPsErf0HDQPsvePjWFf0JZK8ZAiRpM1yg,6627
54
54
  modal/output.py,sha256=q4T9uHduunj4NwY-YSwkHGgjZlCXMuJbfQ5UFaAGRAc,1968
55
- modal/parallel_map.py,sha256=uRCIId1C1lHHprG3A5WdWkOBcl2DmlPTAxZAkXUrrow,40765
55
+ modal/parallel_map.py,sha256=hoyGd6DPz87f3WiwsncB2jls3qA1aIYK7G8e1SyO-wQ,40903
56
56
  modal/parallel_map.pyi,sha256=-t3nZ-SvKEK8_xC4A_AmAq6UVpt4ZFtq7rPnWzHGhfg,10290
57
57
  modal/partial_function.py,sha256=SwuAAj2wj4SO6F6nkSnwNZrczEmm9w9YdlQTHh6hr04,1195
58
58
  modal/partial_function.pyi,sha256=-rhLIgXtLpP5weJw7U4aMcDxtFMwXJ1wf-nncPowUMg,14991
@@ -82,8 +82,8 @@ modal/volume.py,sha256=7-nLtHhIY18qPJo0W23rBc2p4chf-t4Se3uJPzTSzoA,44333
82
82
  modal/volume.pyi,sha256=sjr67f0npiRzl2j3blrcMA_QSoogJAS0xLqWI06xWXQ,40727
83
83
  modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
84
84
  modal/_runtime/asgi.py,sha256=_2xSTsDD27Cit7xnMs4lzkJA2wzer2_N4Oa3BkXFzVA,22521
85
- modal/_runtime/container_io_manager.py,sha256=qKYtd52I0JAmiw1Wfy_EQXHuHsbmt-XwLqKDLBhWrZc,44289
86
- modal/_runtime/container_io_manager.pyi,sha256=coh_qkm5LFKLOACYBaWAKKzzmbMTEY4E5K0wfcTDlGQ,22874
85
+ modal/_runtime/container_io_manager.py,sha256=ANV-Tp1zJbVII0aXdj1HByUrePQPWvlfss19z2Jeogg,44752
86
+ modal/_runtime/container_io_manager.pyi,sha256=yGgA-fcVwv5M8cOzLlj-44qOI1vTw9Fa3GQP7_2aXqA,22967
87
87
  modal/_runtime/execution_context.py,sha256=73Y5zH_o-MhVCrkJXakYVlFkKqCa2CWvqoHjOfJrJGg,3034
88
88
  modal/_runtime/execution_context.pyi,sha256=IFcW1jphqTchX4fy-45rqfz91RhkZPWtIhIvLvGsNGM,2294
89
89
  modal/_runtime/gpu_memory_snapshot.py,sha256=HXgqPHQj0LARhmie_h62V95L-M2R1Kg21INUm_IStn8,7574
@@ -92,11 +92,11 @@ modal/_runtime/user_code_imports.py,sha256=78wJyleqY2RVibqcpbDQyfWVBVT9BjyHPeoV9
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=MhSCsCL8GqIVFWoHubU_899IH-JBZAiiqadG9Wri2l4,29361
95
- modal/_utils/blob_utils.py,sha256=NViIia3A5rdCpN712UDwiIiWtCZFoK_9DGq-xNX1z6A,19906
95
+ modal/_utils/blob_utils.py,sha256=4R-X3VNUJkc8EDSyGNfgcR5fAAkdpQ9W0O5Fy3PyOlU,20628
96
96
  modal/_utils/bytes_io_segment_payload.py,sha256=vaXPq8b52-x6G2hwE7SrjS58pg_aRm7gV3bn3yjmTzQ,4261
97
97
  modal/_utils/deprecation.py,sha256=-Bgg7jZdcJU8lROy18YyVnQYbM8hue-hVmwJqlWAGH0,5504
98
98
  modal/_utils/docker_utils.py,sha256=h1uETghR40mp_y3fSWuZAfbIASH1HMzuphJHghAL6DU,3722
99
- modal/_utils/function_utils.py,sha256=7rFHglocBOUEmbZDEwgVAA2pnhq-7JHcpppQmgAZLoQ,27907
99
+ modal/_utils/function_utils.py,sha256=wFJcfmGC8RuYeQUORGKg6soLj31Mzw9qfay6CyPSAZE,28130
100
100
  modal/_utils/git_utils.py,sha256=qtUU6JAttF55ZxYq51y55OR58B0tDPZsZWK5dJe6W5g,3182
101
101
  modal/_utils/grpc_testing.py,sha256=H1zHqthv19eGPJz2HKXDyWXWGSqO4BRsxah3L5Xaa8A,8619
102
102
  modal/_utils/grpc_utils.py,sha256=aFDJIK3Idn9r0iqLRmQqCKsPhRCueyeaA64mZUvDNKA,11118
@@ -147,7 +147,7 @@ modal/requirements/2024.10.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddR
147
147
  modal/requirements/PREVIEW.txt,sha256=KxDaVTOwatHvboDo4lorlgJ7-n-MfAwbPwxJ0zcJqrs,312
148
148
  modal/requirements/README.md,sha256=9tK76KP0Uph7O0M5oUgsSwEZDj5y-dcUPsnpR0Sc-Ik,854
149
149
  modal/requirements/base-images.json,sha256=3oKVHov9vE88hMQGnn1OqDQK-ohxNF_TEL2DNPKg09s,1051
150
- modal-1.0.6.dev8.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
150
+ modal-1.0.6.dev15.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
151
151
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
152
152
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
153
153
  modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
@@ -155,13 +155,13 @@ modal_docs/mdmd/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,2
155
155
  modal_docs/mdmd/mdmd.py,sha256=eW5MzrEl7mSclDo4Uv64sQ1-4IyLggldbgUJdBVLDdI,6449
156
156
  modal_docs/mdmd/signatures.py,sha256=XJaZrK7Mdepk5fdX51A8uENiLFNil85Ud0d4MH8H5f0,3218
157
157
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
158
- modal_proto/api.proto,sha256=1MXS-aHrFzxalwWfZGz-9BeaKWXjh6I2Y5lj5gMjHKs,97877
159
- modal_proto/api_grpc.py,sha256=GYwNovPwj07sOoE8dC-cYZNYDPBOMT3dIkUb62aLrVY,119952
160
- modal_proto/api_pb2.py,sha256=2XBowKXGHytALBHPrX0aPY2UDKrjyq8VDZfb4mmpnPQ,344980
161
- modal_proto/api_pb2.pyi,sha256=E0CL0q0-ycQYn3fvFCdieDapMdYSSVtzMcNN5WR5g9g,470454
162
- modal_proto/api_pb2_grpc.py,sha256=YBLQpJSxBVK846jPPRSbbA4acUEqRMBeAUXsgwh_xI8,259277
163
- modal_proto/api_pb2_grpc.pyi,sha256=4W_ahZAhumFE-ugs8agFWSQoobs6BdjUkiO3BcBX7ew,60735
164
- modal_proto/modal_api_grpc.py,sha256=D8nUUUId-x98-IzPGWh76ERt5COhdeAd4NtoGL5dBpI,18137
158
+ modal_proto/api.proto,sha256=OUvsHwZhB-WMAhzAdHF4g0huOQtVDpSI93s1wngEX94,98254
159
+ modal_proto/api_grpc.py,sha256=Y2-UcWleygG_-WPkC1u4hYejehB6WEwQtaTfTNYxLPU,120808
160
+ modal_proto/api_pb2.py,sha256=gaZc4r_7wfH-sDbKoZNWUNqEkypGc1o8o2XKI4gyADo,346573
161
+ modal_proto/api_pb2.pyi,sha256=LXiJ27WnWQb9SpcDTPPnjpAF_Ua_-0cB0nsK4KDSt0U,472099
162
+ modal_proto/api_pb2_grpc.py,sha256=Owh9lQBI_fIf7imQhUY0htttwxMNwVUlArU0-mjItpc,261040
163
+ modal_proto/api_pb2_grpc.pyi,sha256=Oshss4U3PFWkZe9DckYiuw4jv_4_Ri3sRJ_YxIuXfic,61160
164
+ modal_proto/modal_api_grpc.py,sha256=VuqkS-sNufg1VHjN0um5pVeXDz-MlbKbufbbEqv_ElQ,18263
165
165
  modal_proto/modal_options_grpc.py,sha256=qJ1cuwA54oRqrdTyPTbvfhFZYd9HhJKK5UCwt523r3Y,120
166
166
  modal_proto/options.proto,sha256=zp9h5r61ivsp0XwEWwNBsVqNTbRA1VSY_UtN7sEcHtE,549
167
167
  modal_proto/options_grpc.py,sha256=M18X3d-8F_cNYSVM3I25dUTO5rZ0rd-vCCfynfh13Nc,125
@@ -170,10 +170,10 @@ modal_proto/options_pb2.pyi,sha256=l7DBrbLO7q3Ir-XDkWsajm0d0TQqqrfuX54i4BMpdQg,1
170
170
  modal_proto/options_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
171
171
  modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0yJSI,247
172
172
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
- modal_version/__init__.py,sha256=paHgvAiEToJxaQReFX1MRZqzvG9f7EZRuVDrZufTweg,120
173
+ modal_version/__init__.py,sha256=wcE59hmlXzee0VnOL5fAq-TlX000CLaNokiaH0xTei0,121
174
174
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
175
- modal-1.0.6.dev8.dist-info/METADATA,sha256=DbJAb6s9SLb-ldcQXECfBSbOkUauxxbciiHmGsGqpPk,2461
176
- modal-1.0.6.dev8.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
177
- modal-1.0.6.dev8.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
- modal-1.0.6.dev8.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
179
- modal-1.0.6.dev8.dist-info/RECORD,,
175
+ modal-1.0.6.dev15.dist-info/METADATA,sha256=cHX7BcS7qLqCntGveGhPKInFzFgH4lNpTGB2L-vSBFg,2462
176
+ modal-1.0.6.dev15.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
177
+ modal-1.0.6.dev15.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
+ modal-1.0.6.dev15.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
179
+ modal-1.0.6.dev15.dist-info/RECORD,,
modal_proto/api.proto CHANGED
@@ -1013,6 +1013,12 @@ message ContainerLogRequest {
1013
1013
  repeated TaskLogs logs = 3;
1014
1014
  }
1015
1015
 
1016
+ message ContainerReloadVolumesRequest {
1017
+ string task_id = 1;
1018
+ }
1019
+
1020
+ message ContainerReloadVolumesResponse { }
1021
+
1016
1022
  message ContainerStopRequest {
1017
1023
  string task_id = 1 [ (modal.options.audit_target_attr) = true ];
1018
1024
  }
@@ -1718,6 +1724,8 @@ message FunctionHandleMetadata {
1718
1724
  FunctionSchema function_schema = 45;
1719
1725
  optional string input_plane_url = 46;
1720
1726
  optional string input_plane_region = 47;
1727
+ // Use optional to ensure unset values default to None instead of 0
1728
+ optional uint64 max_object_size_bytes = 48;
1721
1729
  }
1722
1730
 
1723
1731
  message FunctionInput {
@@ -1790,6 +1798,8 @@ message FunctionPrecreateResponse {
1790
1798
  message FunctionPutInputsItem {
1791
1799
  int32 idx = 1;
1792
1800
  FunctionInput input = 2;
1801
+ bool r2_failed = 3;
1802
+ uint64 r2_latency_ms = 4;
1793
1803
  }
1794
1804
 
1795
1805
  message FunctionPutInputsRequest {
@@ -3279,6 +3289,7 @@ service ModalClient {
3279
3289
  rpc ContainerHeartbeat(ContainerHeartbeatRequest) returns (ContainerHeartbeatResponse);
3280
3290
  rpc ContainerHello(google.protobuf.Empty) returns (google.protobuf.Empty);
3281
3291
  rpc ContainerLog(ContainerLogRequest) returns (google.protobuf.Empty);
3292
+ rpc ContainerReloadVolumes(ContainerReloadVolumesRequest) returns (ContainerReloadVolumesResponse);
3282
3293
  rpc ContainerStop(ContainerStopRequest) returns (ContainerStopResponse);
3283
3294
 
3284
3295
  // Dicts
modal_proto/api_grpc.py CHANGED
@@ -162,6 +162,10 @@ class ModalClientBase(abc.ABC):
162
162
  async def ContainerLog(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.ContainerLogRequest, google.protobuf.empty_pb2.Empty]') -> None:
163
163
  pass
164
164
 
165
+ @abc.abstractmethod
166
+ async def ContainerReloadVolumes(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.ContainerReloadVolumesRequest, modal_proto.api_pb2.ContainerReloadVolumesResponse]') -> None:
167
+ pass
168
+
165
169
  @abc.abstractmethod
166
170
  async def ContainerStop(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.ContainerStopRequest, modal_proto.api_pb2.ContainerStopResponse]') -> None:
167
171
  pass
@@ -860,6 +864,12 @@ class ModalClientBase(abc.ABC):
860
864
  modal_proto.api_pb2.ContainerLogRequest,
861
865
  google.protobuf.empty_pb2.Empty,
862
866
  ),
867
+ '/modal.client.ModalClient/ContainerReloadVolumes': grpclib.const.Handler(
868
+ self.ContainerReloadVolumes,
869
+ grpclib.const.Cardinality.UNARY_UNARY,
870
+ modal_proto.api_pb2.ContainerReloadVolumesRequest,
871
+ modal_proto.api_pb2.ContainerReloadVolumesResponse,
872
+ ),
863
873
  '/modal.client.ModalClient/ContainerStop': grpclib.const.Handler(
864
874
  self.ContainerStop,
865
875
  grpclib.const.Cardinality.UNARY_UNARY,
@@ -1802,6 +1812,12 @@ class ModalClientStub:
1802
1812
  modal_proto.api_pb2.ContainerLogRequest,
1803
1813
  google.protobuf.empty_pb2.Empty,
1804
1814
  )
1815
+ self.ContainerReloadVolumes = grpclib.client.UnaryUnaryMethod(
1816
+ channel,
1817
+ '/modal.client.ModalClient/ContainerReloadVolumes',
1818
+ modal_proto.api_pb2.ContainerReloadVolumesRequest,
1819
+ modal_proto.api_pb2.ContainerReloadVolumesResponse,
1820
+ )
1805
1821
  self.ContainerStop = grpclib.client.UnaryUnaryMethod(
1806
1822
  channel,
1807
1823
  '/modal.client.ModalClient/ContainerStop',