modal 0.74.11__tar.gz → 0.74.13__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.
Files changed (183) hide show
  1. {modal-0.74.11 → modal-0.74.13}/PKG-INFO +1 -1
  2. {modal-0.74.11 → modal-0.74.13}/modal/__main__.py +2 -2
  3. {modal-0.74.11 → modal-0.74.13}/modal/_functions.py +5 -0
  4. {modal-0.74.11 → modal-0.74.13}/modal/_resolver.py +6 -0
  5. {modal-0.74.11 → modal-0.74.13}/modal/_utils/function_utils.py +5 -0
  6. {modal-0.74.11 → modal-0.74.13}/modal/app.py +5 -1
  7. {modal-0.74.11 → modal-0.74.13}/modal/app.pyi +4 -0
  8. {modal-0.74.11 → modal-0.74.13}/modal/cli/_traceback.py +2 -2
  9. {modal-0.74.11 → modal-0.74.13}/modal/client.pyi +2 -2
  10. {modal-0.74.11 → modal-0.74.13}/modal/functions.pyi +1 -0
  11. {modal-0.74.11 → modal-0.74.13}/modal.egg-info/PKG-INFO +1 -1
  12. {modal-0.74.11 → modal-0.74.13}/modal_proto/api.proto +12 -3
  13. {modal-0.74.11 → modal-0.74.13}/modal_proto/api_pb2.py +592 -566
  14. {modal-0.74.11 → modal-0.74.13}/modal_proto/api_pb2.pyi +58 -10
  15. {modal-0.74.11 → modal-0.74.13}/modal_version/_version_generated.py +1 -1
  16. {modal-0.74.11 → modal-0.74.13}/LICENSE +0 -0
  17. {modal-0.74.11 → modal-0.74.13}/README.md +0 -0
  18. {modal-0.74.11 → modal-0.74.13}/modal/__init__.py +0 -0
  19. {modal-0.74.11 → modal-0.74.13}/modal/_clustered_functions.py +0 -0
  20. {modal-0.74.11 → modal-0.74.13}/modal/_clustered_functions.pyi +0 -0
  21. {modal-0.74.11 → modal-0.74.13}/modal/_container_entrypoint.py +0 -0
  22. {modal-0.74.11 → modal-0.74.13}/modal/_ipython.py +0 -0
  23. {modal-0.74.11 → modal-0.74.13}/modal/_location.py +0 -0
  24. {modal-0.74.11 → modal-0.74.13}/modal/_object.py +0 -0
  25. {modal-0.74.11 → modal-0.74.13}/modal/_output.py +0 -0
  26. {modal-0.74.11 → modal-0.74.13}/modal/_partial_function.py +0 -0
  27. {modal-0.74.11 → modal-0.74.13}/modal/_pty.py +0 -0
  28. {modal-0.74.11 → modal-0.74.13}/modal/_resources.py +0 -0
  29. {modal-0.74.11 → modal-0.74.13}/modal/_runtime/__init__.py +0 -0
  30. {modal-0.74.11 → modal-0.74.13}/modal/_runtime/asgi.py +0 -0
  31. {modal-0.74.11 → modal-0.74.13}/modal/_runtime/container_io_manager.py +0 -0
  32. {modal-0.74.11 → modal-0.74.13}/modal/_runtime/container_io_manager.pyi +0 -0
  33. {modal-0.74.11 → modal-0.74.13}/modal/_runtime/execution_context.py +0 -0
  34. {modal-0.74.11 → modal-0.74.13}/modal/_runtime/execution_context.pyi +0 -0
  35. {modal-0.74.11 → modal-0.74.13}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  36. {modal-0.74.11 → modal-0.74.13}/modal/_runtime/telemetry.py +0 -0
  37. {modal-0.74.11 → modal-0.74.13}/modal/_runtime/user_code_imports.py +0 -0
  38. {modal-0.74.11 → modal-0.74.13}/modal/_serialization.py +0 -0
  39. {modal-0.74.11 → modal-0.74.13}/modal/_traceback.py +0 -0
  40. {modal-0.74.11 → modal-0.74.13}/modal/_tunnel.py +0 -0
  41. {modal-0.74.11 → modal-0.74.13}/modal/_tunnel.pyi +0 -0
  42. {modal-0.74.11 → modal-0.74.13}/modal/_type_manager.py +0 -0
  43. {modal-0.74.11 → modal-0.74.13}/modal/_utils/__init__.py +0 -0
  44. {modal-0.74.11 → modal-0.74.13}/modal/_utils/app_utils.py +0 -0
  45. {modal-0.74.11 → modal-0.74.13}/modal/_utils/async_utils.py +0 -0
  46. {modal-0.74.11 → modal-0.74.13}/modal/_utils/blob_utils.py +0 -0
  47. {modal-0.74.11 → modal-0.74.13}/modal/_utils/bytes_io_segment_payload.py +0 -0
  48. {modal-0.74.11 → modal-0.74.13}/modal/_utils/deprecation.py +0 -0
  49. {modal-0.74.11 → modal-0.74.13}/modal/_utils/docker_utils.py +0 -0
  50. {modal-0.74.11 → modal-0.74.13}/modal/_utils/git_utils.py +0 -0
  51. {modal-0.74.11 → modal-0.74.13}/modal/_utils/grpc_testing.py +0 -0
  52. {modal-0.74.11 → modal-0.74.13}/modal/_utils/grpc_utils.py +0 -0
  53. {modal-0.74.11 → modal-0.74.13}/modal/_utils/hash_utils.py +0 -0
  54. {modal-0.74.11 → modal-0.74.13}/modal/_utils/http_utils.py +0 -0
  55. {modal-0.74.11 → modal-0.74.13}/modal/_utils/jwt_utils.py +0 -0
  56. {modal-0.74.11 → modal-0.74.13}/modal/_utils/logger.py +0 -0
  57. {modal-0.74.11 → modal-0.74.13}/modal/_utils/mount_utils.py +0 -0
  58. {modal-0.74.11 → modal-0.74.13}/modal/_utils/name_utils.py +0 -0
  59. {modal-0.74.11 → modal-0.74.13}/modal/_utils/package_utils.py +0 -0
  60. {modal-0.74.11 → modal-0.74.13}/modal/_utils/pattern_utils.py +0 -0
  61. {modal-0.74.11 → modal-0.74.13}/modal/_utils/rand_pb_testing.py +0 -0
  62. {modal-0.74.11 → modal-0.74.13}/modal/_utils/shell_utils.py +0 -0
  63. {modal-0.74.11 → modal-0.74.13}/modal/_vendor/__init__.py +0 -0
  64. {modal-0.74.11 → modal-0.74.13}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  65. {modal-0.74.11 → modal-0.74.13}/modal/_vendor/cloudpickle.py +0 -0
  66. {modal-0.74.11 → modal-0.74.13}/modal/_vendor/tblib.py +0 -0
  67. {modal-0.74.11 → modal-0.74.13}/modal/_watcher.py +0 -0
  68. {modal-0.74.11 → modal-0.74.13}/modal/call_graph.py +0 -0
  69. {modal-0.74.11 → modal-0.74.13}/modal/cli/__init__.py +0 -0
  70. {modal-0.74.11 → modal-0.74.13}/modal/cli/_download.py +0 -0
  71. {modal-0.74.11 → modal-0.74.13}/modal/cli/app.py +0 -0
  72. {modal-0.74.11 → modal-0.74.13}/modal/cli/config.py +0 -0
  73. {modal-0.74.11 → modal-0.74.13}/modal/cli/container.py +0 -0
  74. {modal-0.74.11 → modal-0.74.13}/modal/cli/dict.py +0 -0
  75. {modal-0.74.11 → modal-0.74.13}/modal/cli/entry_point.py +0 -0
  76. {modal-0.74.11 → modal-0.74.13}/modal/cli/environment.py +0 -0
  77. {modal-0.74.11 → modal-0.74.13}/modal/cli/import_refs.py +0 -0
  78. {modal-0.74.11 → modal-0.74.13}/modal/cli/launch.py +0 -0
  79. {modal-0.74.11 → modal-0.74.13}/modal/cli/network_file_system.py +0 -0
  80. {modal-0.74.11 → modal-0.74.13}/modal/cli/profile.py +0 -0
  81. {modal-0.74.11 → modal-0.74.13}/modal/cli/programs/__init__.py +0 -0
  82. {modal-0.74.11 → modal-0.74.13}/modal/cli/programs/run_jupyter.py +0 -0
  83. {modal-0.74.11 → modal-0.74.13}/modal/cli/programs/vscode.py +0 -0
  84. {modal-0.74.11 → modal-0.74.13}/modal/cli/queues.py +0 -0
  85. {modal-0.74.11 → modal-0.74.13}/modal/cli/run.py +0 -0
  86. {modal-0.74.11 → modal-0.74.13}/modal/cli/secret.py +0 -0
  87. {modal-0.74.11 → modal-0.74.13}/modal/cli/token.py +0 -0
  88. {modal-0.74.11 → modal-0.74.13}/modal/cli/utils.py +0 -0
  89. {modal-0.74.11 → modal-0.74.13}/modal/cli/volume.py +0 -0
  90. {modal-0.74.11 → modal-0.74.13}/modal/client.py +0 -0
  91. {modal-0.74.11 → modal-0.74.13}/modal/cloud_bucket_mount.py +0 -0
  92. {modal-0.74.11 → modal-0.74.13}/modal/cloud_bucket_mount.pyi +0 -0
  93. {modal-0.74.11 → modal-0.74.13}/modal/cls.py +0 -0
  94. {modal-0.74.11 → modal-0.74.13}/modal/cls.pyi +0 -0
  95. {modal-0.74.11 → modal-0.74.13}/modal/config.py +0 -0
  96. {modal-0.74.11 → modal-0.74.13}/modal/container_process.py +0 -0
  97. {modal-0.74.11 → modal-0.74.13}/modal/container_process.pyi +0 -0
  98. {modal-0.74.11 → modal-0.74.13}/modal/dict.py +0 -0
  99. {modal-0.74.11 → modal-0.74.13}/modal/dict.pyi +0 -0
  100. {modal-0.74.11 → modal-0.74.13}/modal/environments.py +0 -0
  101. {modal-0.74.11 → modal-0.74.13}/modal/environments.pyi +0 -0
  102. {modal-0.74.11 → modal-0.74.13}/modal/exception.py +0 -0
  103. {modal-0.74.11 → modal-0.74.13}/modal/experimental/__init__.py +0 -0
  104. {modal-0.74.11 → modal-0.74.13}/modal/experimental/ipython.py +0 -0
  105. {modal-0.74.11 → modal-0.74.13}/modal/file_io.py +0 -0
  106. {modal-0.74.11 → modal-0.74.13}/modal/file_io.pyi +0 -0
  107. {modal-0.74.11 → modal-0.74.13}/modal/file_pattern_matcher.py +0 -0
  108. {modal-0.74.11 → modal-0.74.13}/modal/functions.py +0 -0
  109. {modal-0.74.11 → modal-0.74.13}/modal/gpu.py +0 -0
  110. {modal-0.74.11 → modal-0.74.13}/modal/image.py +0 -0
  111. {modal-0.74.11 → modal-0.74.13}/modal/image.pyi +0 -0
  112. {modal-0.74.11 → modal-0.74.13}/modal/io_streams.py +0 -0
  113. {modal-0.74.11 → modal-0.74.13}/modal/io_streams.pyi +0 -0
  114. {modal-0.74.11 → modal-0.74.13}/modal/mount.py +0 -0
  115. {modal-0.74.11 → modal-0.74.13}/modal/mount.pyi +0 -0
  116. {modal-0.74.11 → modal-0.74.13}/modal/network_file_system.py +0 -0
  117. {modal-0.74.11 → modal-0.74.13}/modal/network_file_system.pyi +0 -0
  118. {modal-0.74.11 → modal-0.74.13}/modal/object.py +0 -0
  119. {modal-0.74.11 → modal-0.74.13}/modal/object.pyi +0 -0
  120. {modal-0.74.11 → modal-0.74.13}/modal/output.py +0 -0
  121. {modal-0.74.11 → modal-0.74.13}/modal/parallel_map.py +0 -0
  122. {modal-0.74.11 → modal-0.74.13}/modal/parallel_map.pyi +0 -0
  123. {modal-0.74.11 → modal-0.74.13}/modal/partial_function.py +0 -0
  124. {modal-0.74.11 → modal-0.74.13}/modal/partial_function.pyi +0 -0
  125. {modal-0.74.11 → modal-0.74.13}/modal/proxy.py +0 -0
  126. {modal-0.74.11 → modal-0.74.13}/modal/proxy.pyi +0 -0
  127. {modal-0.74.11 → modal-0.74.13}/modal/py.typed +0 -0
  128. {modal-0.74.11 → modal-0.74.13}/modal/queue.py +0 -0
  129. {modal-0.74.11 → modal-0.74.13}/modal/queue.pyi +0 -0
  130. {modal-0.74.11 → modal-0.74.13}/modal/requirements/2023.12.312.txt +0 -0
  131. {modal-0.74.11 → modal-0.74.13}/modal/requirements/2023.12.txt +0 -0
  132. {modal-0.74.11 → modal-0.74.13}/modal/requirements/2024.04.txt +0 -0
  133. {modal-0.74.11 → modal-0.74.13}/modal/requirements/2024.10.txt +0 -0
  134. {modal-0.74.11 → modal-0.74.13}/modal/requirements/PREVIEW.txt +0 -0
  135. {modal-0.74.11 → modal-0.74.13}/modal/requirements/README.md +0 -0
  136. {modal-0.74.11 → modal-0.74.13}/modal/requirements/base-images.json +0 -0
  137. {modal-0.74.11 → modal-0.74.13}/modal/retries.py +0 -0
  138. {modal-0.74.11 → modal-0.74.13}/modal/runner.py +0 -0
  139. {modal-0.74.11 → modal-0.74.13}/modal/runner.pyi +0 -0
  140. {modal-0.74.11 → modal-0.74.13}/modal/running_app.py +0 -0
  141. {modal-0.74.11 → modal-0.74.13}/modal/sandbox.py +0 -0
  142. {modal-0.74.11 → modal-0.74.13}/modal/sandbox.pyi +0 -0
  143. {modal-0.74.11 → modal-0.74.13}/modal/schedule.py +0 -0
  144. {modal-0.74.11 → modal-0.74.13}/modal/scheduler_placement.py +0 -0
  145. {modal-0.74.11 → modal-0.74.13}/modal/secret.py +0 -0
  146. {modal-0.74.11 → modal-0.74.13}/modal/secret.pyi +0 -0
  147. {modal-0.74.11 → modal-0.74.13}/modal/serving.py +0 -0
  148. {modal-0.74.11 → modal-0.74.13}/modal/serving.pyi +0 -0
  149. {modal-0.74.11 → modal-0.74.13}/modal/snapshot.py +0 -0
  150. {modal-0.74.11 → modal-0.74.13}/modal/snapshot.pyi +0 -0
  151. {modal-0.74.11 → modal-0.74.13}/modal/stream_type.py +0 -0
  152. {modal-0.74.11 → modal-0.74.13}/modal/token_flow.py +0 -0
  153. {modal-0.74.11 → modal-0.74.13}/modal/token_flow.pyi +0 -0
  154. {modal-0.74.11 → modal-0.74.13}/modal/volume.py +0 -0
  155. {modal-0.74.11 → modal-0.74.13}/modal/volume.pyi +0 -0
  156. {modal-0.74.11 → modal-0.74.13}/modal.egg-info/SOURCES.txt +0 -0
  157. {modal-0.74.11 → modal-0.74.13}/modal.egg-info/dependency_links.txt +0 -0
  158. {modal-0.74.11 → modal-0.74.13}/modal.egg-info/entry_points.txt +0 -0
  159. {modal-0.74.11 → modal-0.74.13}/modal.egg-info/requires.txt +0 -0
  160. {modal-0.74.11 → modal-0.74.13}/modal.egg-info/top_level.txt +0 -0
  161. {modal-0.74.11 → modal-0.74.13}/modal_docs/__init__.py +0 -0
  162. {modal-0.74.11 → modal-0.74.13}/modal_docs/gen_cli_docs.py +0 -0
  163. {modal-0.74.11 → modal-0.74.13}/modal_docs/gen_reference_docs.py +0 -0
  164. {modal-0.74.11 → modal-0.74.13}/modal_docs/mdmd/__init__.py +0 -0
  165. {modal-0.74.11 → modal-0.74.13}/modal_docs/mdmd/mdmd.py +0 -0
  166. {modal-0.74.11 → modal-0.74.13}/modal_docs/mdmd/signatures.py +0 -0
  167. {modal-0.74.11 → modal-0.74.13}/modal_proto/__init__.py +0 -0
  168. {modal-0.74.11 → modal-0.74.13}/modal_proto/api_grpc.py +0 -0
  169. {modal-0.74.11 → modal-0.74.13}/modal_proto/api_pb2_grpc.py +0 -0
  170. {modal-0.74.11 → modal-0.74.13}/modal_proto/api_pb2_grpc.pyi +0 -0
  171. {modal-0.74.11 → modal-0.74.13}/modal_proto/modal_api_grpc.py +0 -0
  172. {modal-0.74.11 → modal-0.74.13}/modal_proto/modal_options_grpc.py +0 -0
  173. {modal-0.74.11 → modal-0.74.13}/modal_proto/options.proto +0 -0
  174. {modal-0.74.11 → modal-0.74.13}/modal_proto/options_grpc.py +0 -0
  175. {modal-0.74.11 → modal-0.74.13}/modal_proto/options_pb2.py +0 -0
  176. {modal-0.74.11 → modal-0.74.13}/modal_proto/options_pb2.pyi +0 -0
  177. {modal-0.74.11 → modal-0.74.13}/modal_proto/options_pb2_grpc.py +0 -0
  178. {modal-0.74.11 → modal-0.74.13}/modal_proto/options_pb2_grpc.pyi +0 -0
  179. {modal-0.74.11 → modal-0.74.13}/modal_proto/py.typed +0 -0
  180. {modal-0.74.11 → modal-0.74.13}/modal_version/__init__.py +0 -0
  181. {modal-0.74.11 → modal-0.74.13}/modal_version/__main__.py +0 -0
  182. {modal-0.74.11 → modal-0.74.13}/pyproject.toml +0 -0
  183. {modal-0.74.11 → modal-0.74.13}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 0.74.11
3
+ Version: 0.74.13
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -2,7 +2,7 @@
2
2
  import sys
3
3
 
4
4
  from ._traceback import reduce_traceback_to_user_code
5
- from .cli._traceback import highlight_modal_deprecation_warnings, setup_rich_traceback
5
+ from .cli._traceback import highlight_modal_warnings, setup_rich_traceback
6
6
  from .cli.entry_point import entrypoint_cli
7
7
  from .cli.import_refs import _CliUserExecutionError
8
8
  from .config import config
@@ -11,7 +11,7 @@ from .config import config
11
11
  def main():
12
12
  # Setup rich tracebacks, but only on user's end, when using the Modal CLI.
13
13
  setup_rich_traceback()
14
- highlight_modal_deprecation_warnings()
14
+ highlight_modal_warnings()
15
15
 
16
16
  try:
17
17
  entrypoint_cli()
@@ -459,6 +459,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
459
459
  ephemeral_disk: Optional[int] = None,
460
460
  # current default: first-party, future default: main-package
461
461
  include_source: Optional[bool] = None,
462
+ experimental_options: Optional[dict[str, str]] = None,
462
463
  _experimental_proxy_ip: Optional[str] = None,
463
464
  _experimental_custom_scaling_factor: Optional[float] = None,
464
465
  _experimental_enable_gpu_snapshot: bool = False,
@@ -819,6 +820,8 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
819
820
  i6pn_enabled=i6pn_enabled,
820
821
  schedule=schedule.proto_message if schedule is not None else None,
821
822
  snapshot_debug=config.get("snapshot_debug"),
823
+ experimental_options=experimental_options or {},
824
+ # ---
822
825
  _experimental_group_size=cluster_size or 0, # Experimental: Clustered functions
823
826
  _experimental_concurrent_cancellations=True,
824
827
  _experimental_proxy_ip=_experimental_proxy_ip,
@@ -856,6 +859,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
856
859
  use_method_name=function_definition.use_method_name,
857
860
  method_definitions=function_definition.method_definitions,
858
861
  method_definitions_set=function_definition.method_definitions_set,
862
+ experimental_options=experimental_options or {},
859
863
  _experimental_group_size=function_definition._experimental_group_size,
860
864
  _experimental_buffer_containers=function_definition._experimental_buffer_containers,
861
865
  _experimental_custom_scaling=function_definition._experimental_custom_scaling,
@@ -913,6 +917,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
913
917
  raise InvalidError(f"Function {info.function_name} is too large to deploy.")
914
918
  raise
915
919
  function_creation_status.set_response(response)
920
+
916
921
  # needed for modal.serve file watching
917
922
  serve_mounts = {m for m in all_mounts if m.is_local()}
918
923
  serve_mounts |= image._serve_mounts
@@ -10,6 +10,8 @@ from typing import TYPE_CHECKING, Optional
10
10
 
11
11
  from grpclib import GRPCError, Status
12
12
 
13
+ from modal_proto import api_pb2
14
+
13
15
  from ._utils.async_utils import TaskContext
14
16
  from .client import _Client
15
17
  from .exception import NotFoundError
@@ -34,6 +36,10 @@ class StatusRow:
34
36
  if self._spinner is not None:
35
37
  self._spinner.update(text=message)
36
38
 
39
+ def warning(self, warning: api_pb2.Warning):
40
+ if self._step_node is not None:
41
+ self._step_node.add(f"[yellow]:warning:[/yellow] {warning.message}")
42
+
37
43
  def finish(self, message):
38
44
  if self._step_node is not None and self._spinner is not None:
39
45
  from ._output import OutputManager
@@ -584,6 +584,8 @@ class FunctionCreationStatus:
584
584
  suffix = _get_suffix_from_web_url_info(url_info)
585
585
  # TODO: this is only printed when we're showing progress. Maybe move this somewhere else.
586
586
  web_url = self.response.handle_metadata.web_url
587
+ for warning in self.response.server_warnings:
588
+ self.status_row.warning(warning)
587
589
  self.status_row.finish(
588
590
  f"Created web function {self.tag} => [magenta underline]{web_url}[/magenta underline]"
589
591
  f"{proxy_auth_suffix}{suffix}"
@@ -595,7 +597,10 @@ class FunctionCreationStatus:
595
597
  custom_domain_status_row.finish(
596
598
  f"Custom domain for {self.tag} => [magenta underline]{custom_domain.url}[/magenta underline]"
597
599
  )
600
+
598
601
  else:
602
+ for warning in self.response.server_warnings:
603
+ self.status_row.warning(warning)
599
604
  self.status_row.finish(f"Created function {self.tag}.")
600
605
  if self.response.function.method_definitions_set:
601
606
  for method_definition in self.response.function.method_definitions.values():
@@ -613,6 +613,7 @@ class _App:
613
613
  i6pn: Optional[bool] = None, # Whether to enable IPv6 container networking within the region.
614
614
  # Whether the function's home package should be included in the image - defaults to True
615
615
  include_source: Optional[bool] = None, # When `False`, don't automatically add the App source to the container.
616
+ experimental_options: Optional[dict[str, Any]] = None,
616
617
  # Parameters below here are experimental. Use with caution!
617
618
  _experimental_scheduler_placement: Optional[
618
619
  SchedulerPlacement
@@ -780,10 +781,11 @@ class _App:
780
781
  block_network=block_network,
781
782
  max_inputs=max_inputs,
782
783
  scheduler_placement=scheduler_placement,
783
- _experimental_proxy_ip=_experimental_proxy_ip,
784
784
  i6pn_enabled=i6pn_enabled,
785
785
  cluster_size=cluster_size, # Experimental: Clustered functions
786
786
  include_source=include_source if include_source is not None else self._include_source_default,
787
+ experimental_options={k: str(v) for k, v in (experimental_options or {}).items()},
788
+ _experimental_proxy_ip=_experimental_proxy_ip,
787
789
  _experimental_enable_gpu_snapshot=_experimental_enable_gpu_snapshot,
788
790
  )
789
791
 
@@ -836,6 +838,7 @@ class _App:
836
838
  # Use `max_inputs = 1` for single-use containers.
837
839
  max_inputs: Optional[int] = None,
838
840
  include_source: Optional[bool] = None, # When `False`, don't automatically add the App source to the container.
841
+ experimental_options: Optional[dict[str, Any]] = None,
839
842
  # Parameters below here are experimental. Use with caution!
840
843
  _experimental_scheduler_placement: Optional[
841
844
  SchedulerPlacement
@@ -947,6 +950,7 @@ class _App:
947
950
  max_inputs=max_inputs,
948
951
  scheduler_placement=scheduler_placement,
949
952
  include_source=include_source if include_source is not None else self._include_source_default,
953
+ experimental_options={k: str(v) for k, v in (experimental_options or {}).items()},
950
954
  _experimental_proxy_ip=_experimental_proxy_ip,
951
955
  _experimental_custom_scaling_factor=_experimental_custom_scaling_factor,
952
956
  _experimental_enable_gpu_snapshot=_experimental_enable_gpu_snapshot,
@@ -192,6 +192,7 @@ class _App:
192
192
  max_inputs: typing.Optional[int] = None,
193
193
  i6pn: typing.Optional[bool] = None,
194
194
  include_source: typing.Optional[bool] = None,
195
+ experimental_options: typing.Optional[dict[str, typing.Any]] = None,
195
196
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
196
197
  _experimental_proxy_ip: typing.Optional[str] = None,
197
198
  _experimental_custom_scaling_factor: typing.Optional[float] = None,
@@ -239,6 +240,7 @@ class _App:
239
240
  block_network: bool = False,
240
241
  max_inputs: typing.Optional[int] = None,
241
242
  include_source: typing.Optional[bool] = None,
243
+ experimental_options: typing.Optional[dict[str, typing.Any]] = None,
242
244
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
243
245
  _experimental_proxy_ip: typing.Optional[str] = None,
244
246
  _experimental_custom_scaling_factor: typing.Optional[float] = None,
@@ -432,6 +434,7 @@ class App:
432
434
  max_inputs: typing.Optional[int] = None,
433
435
  i6pn: typing.Optional[bool] = None,
434
436
  include_source: typing.Optional[bool] = None,
437
+ experimental_options: typing.Optional[dict[str, typing.Any]] = None,
435
438
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
436
439
  _experimental_proxy_ip: typing.Optional[str] = None,
437
440
  _experimental_custom_scaling_factor: typing.Optional[float] = None,
@@ -479,6 +482,7 @@ class App:
479
482
  block_network: bool = False,
480
483
  max_inputs: typing.Optional[int] = None,
481
484
  include_source: typing.Optional[bool] = None,
485
+ experimental_options: typing.Optional[dict[str, typing.Any]] = None,
482
486
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
483
487
  _experimental_proxy_ip: typing.Optional[str] = None,
484
488
  _experimental_custom_scaling_factor: typing.Optional[float] = None,
@@ -161,8 +161,8 @@ def setup_rich_traceback() -> None:
161
161
  install(suppress=[synchronicity, grpclib, click, typer], extra_lines=1)
162
162
 
163
163
 
164
- def highlight_modal_deprecation_warnings() -> None:
165
- """Patch the warnings module to make client deprecation warnings more salient in the CLI."""
164
+ def highlight_modal_warnings() -> None:
165
+ """Patch the warnings module to make certain warnings more salient in the CLI."""
166
166
  base_showwarning = warnings.showwarning
167
167
 
168
168
  def showwarning(warning, category, filename, lineno, file=None, line=None):
@@ -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.11"
30
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.74.13"
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.11"
88
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.74.13"
89
89
  ): ...
90
90
  def is_closed(self) -> bool: ...
91
91
  @property
@@ -98,6 +98,7 @@ class Function(
98
98
  max_inputs: typing.Optional[int] = None,
99
99
  ephemeral_disk: typing.Optional[int] = None,
100
100
  include_source: typing.Optional[bool] = None,
101
+ experimental_options: typing.Optional[dict[str, str]] = None,
101
102
  _experimental_proxy_ip: typing.Optional[str] = None,
102
103
  _experimental_custom_scaling_factor: typing.Optional[float] = None,
103
104
  _experimental_enable_gpu_snapshot: bool = False,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 0.74.11
3
+ Version: 0.74.13
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -1341,6 +1341,11 @@ message Function {
1341
1341
 
1342
1342
  AutoscalerSettings autoscaler_settings = 79; // Bundle of parameters related to autoscaling
1343
1343
  FunctionSchema function_schema = 80;
1344
+
1345
+ // For server-side experimental functionality. Prefer using this over individual _experimental_* fields.
1346
+ // Note the value type as string. Internally we'll coerce all values to string with str().
1347
+ // On the server, it's necessary to convert back to the most natural type (e.g. int) when relevant.
1348
+ map<string, string> experimental_options = 81;
1344
1349
  }
1345
1350
 
1346
1351
  message FunctionAsyncInvokeRequest {
@@ -1425,6 +1430,7 @@ message FunctionCreateResponse {
1425
1430
  string __deprecated_web_url = 2 [ deprecated = true]; // Used up until 0.62.212
1426
1431
  Function function = 4;
1427
1432
  FunctionHandleMetadata handle_metadata = 5;
1433
+ repeated Warning server_warnings = 6;
1428
1434
  }
1429
1435
 
1430
1436
  message FunctionData {
@@ -1490,6 +1496,8 @@ message FunctionData {
1490
1496
 
1491
1497
  AutoscalerSettings autoscaler_settings = 31; // Bundle of parameters related to autoscaling
1492
1498
  FunctionSchema function_schema = 32;
1499
+
1500
+ map<string, string> experimental_options = 33;
1493
1501
  }
1494
1502
 
1495
1503
  message FunctionExtended {
@@ -2881,13 +2889,13 @@ message VolumeGetOrCreateRequest {
2881
2889
  string environment_name = 3;
2882
2890
  ObjectCreationType object_creation_type = 4;
2883
2891
  string app_id = 5; // only used with OBJECT_CREATION_TYPE_ANONYMOUS_OWNED_BY_APP
2884
- VolumeFsVersion version = 6 [deprecated = true];
2885
- VolumeMetadata metadata = 7;
2892
+ VolumeFsVersion version = 6;
2886
2893
  }
2887
2894
 
2888
2895
  message VolumeGetOrCreateResponse {
2889
2896
  string volume_id = 1;
2890
- VolumeFsVersion version = 2;
2897
+ VolumeFsVersion version = 2 [deprecated = true];
2898
+ VolumeMetadata metadata = 3;
2891
2899
  }
2892
2900
 
2893
2901
  message VolumeHeartbeatRequest {
@@ -3028,6 +3036,7 @@ message Warning {
3028
3036
  WARNING_TYPE_UNSPECIFIED = 0;
3029
3037
  WARNING_TYPE_CLIENT_DEPRECATION = 1;
3030
3038
  WARNING_TYPE_RESOURCE_LIMIT = 2;
3039
+ WARNING_TYPE_FUNCTION_CONFIGURATION = 3;
3031
3040
  }
3032
3041
  WarningType type = 1;
3033
3042
  string message = 2;