modAL 1.0.5__tar.gz → 1.0.5.dev1__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 (202) hide show
  1. {modal-1.0.5 → modal-1.0.5.dev1}/PKG-INFO +2 -2
  2. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_clustered_functions.pyi +3 -13
  3. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_functions.py +46 -84
  4. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_partial_function.py +1 -1
  5. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_runtime/container_io_manager.pyi +40 -222
  6. modal-1.0.5.dev1/modal/_runtime/execution_context.pyi +24 -0
  7. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_serialization.py +2 -25
  8. modal-1.0.5.dev1/modal/_tunnel.pyi +37 -0
  9. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/blob_utils.py +19 -56
  10. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/function_utils.py +7 -33
  11. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/grpc_utils.py +4 -11
  12. {modal-1.0.5 → modal-1.0.5.dev1}/modal/app.py +5 -5
  13. modal-1.0.5.dev1/modal/app.pyi +510 -0
  14. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/run.py +1 -2
  15. modal-1.0.5.dev1/modal/client.pyi +223 -0
  16. modal-1.0.5.dev1/modal/cloud_bucket_mount.pyi +51 -0
  17. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cls.py +7 -7
  18. modal-1.0.5.dev1/modal/cls.pyi +308 -0
  19. modal-1.0.5.dev1/modal/container_process.pyi +86 -0
  20. {modal-1.0.5 → modal-1.0.5.dev1}/modal/dict.py +4 -4
  21. modal-1.0.5.dev1/modal/dict.pyi +209 -0
  22. {modal-1.0.5 → modal-1.0.5.dev1}/modal/environments.pyi +9 -41
  23. {modal-1.0.5 → modal-1.0.5.dev1}/modal/exception.py +2 -6
  24. {modal-1.0.5 → modal-1.0.5.dev1}/modal/experimental/__init__.py +0 -90
  25. {modal-1.0.5 → modal-1.0.5.dev1}/modal/experimental/ipython.py +7 -11
  26. {modal-1.0.5 → modal-1.0.5.dev1}/modal/file_io.pyi +45 -236
  27. modal-1.0.5.dev1/modal/functions.pyi +382 -0
  28. {modal-1.0.5 → modal-1.0.5.dev1}/modal/gpu.py +1 -1
  29. {modal-1.0.5 → modal-1.0.5.dev1}/modal/image.py +1 -1
  30. modal-1.0.5.dev1/modal/image.pyi +610 -0
  31. {modal-1.0.5 → modal-1.0.5.dev1}/modal/io_streams.py +4 -8
  32. modal-1.0.5.dev1/modal/io_streams.pyi +124 -0
  33. {modal-1.0.5 → modal-1.0.5.dev1}/modal/mount.pyi +31 -261
  34. {modal-1.0.5 → modal-1.0.5.dev1}/modal/network_file_system.py +3 -3
  35. modal-1.0.5.dev1/modal/network_file_system.pyi +222 -0
  36. {modal-1.0.5 → modal-1.0.5.dev1}/modal/object.pyi +9 -48
  37. {modal-1.0.5 → modal-1.0.5.dev1}/modal/parallel_map.py +9 -80
  38. {modal-1.0.5 → modal-1.0.5.dev1}/modal/parallel_map.pyi +15 -160
  39. modal-1.0.5.dev1/modal/partial_function.pyi +172 -0
  40. {modal-1.0.5 → modal-1.0.5.dev1}/modal/proxy.py +1 -1
  41. modal-1.0.5.dev1/modal/proxy.pyi +12 -0
  42. {modal-1.0.5 → modal-1.0.5.dev1}/modal/queue.py +4 -4
  43. modal-1.0.5.dev1/modal/queue.pyi +300 -0
  44. {modal-1.0.5 → modal-1.0.5.dev1}/modal/runner.pyi +22 -160
  45. {modal-1.0.5 → modal-1.0.5.dev1}/modal/sandbox.py +7 -8
  46. {modal-1.0.5 → modal-1.0.5.dev1}/modal/sandbox.pyi +50 -310
  47. {modal-1.0.5 → modal-1.0.5.dev1}/modal/schedule.py +1 -1
  48. {modal-1.0.5 → modal-1.0.5.dev1}/modal/secret.py +2 -2
  49. modal-1.0.5.dev1/modal/secret.pyi +93 -0
  50. modal-1.0.5.dev1/modal/snapshot.pyi +18 -0
  51. {modal-1.0.5 → modal-1.0.5.dev1}/modal/token_flow.pyi +8 -28
  52. {modal-1.0.5 → modal-1.0.5.dev1}/modal/volume.py +4 -41
  53. modal-1.0.5.dev1/modal/volume.pyi +537 -0
  54. {modal-1.0.5 → modal-1.0.5.dev1}/modal.egg-info/PKG-INFO +2 -2
  55. {modal-1.0.5 → modal-1.0.5.dev1}/modal.egg-info/requires.txt +1 -1
  56. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/api.proto +0 -56
  57. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/api_grpc.py +0 -48
  58. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/api_pb2.py +780 -874
  59. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/api_pb2.pyi +8 -194
  60. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/api_pb2_grpc.py +0 -100
  61. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/api_pb2_grpc.pyi +0 -32
  62. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/modal_api_grpc.py +0 -3
  63. {modal-1.0.5 → modal-1.0.5.dev1}/modal_version/__init__.py +1 -1
  64. {modal-1.0.5 → modal-1.0.5.dev1}/pyproject.toml +1 -1
  65. modal-1.0.5/modal/_runtime/execution_context.pyi +0 -78
  66. modal-1.0.5/modal/_tunnel.pyi +0 -405
  67. modal-1.0.5/modal/app.pyi +0 -1120
  68. modal-1.0.5/modal/client.pyi +0 -411
  69. modal-1.0.5/modal/cloud_bucket_mount.pyi +0 -239
  70. modal-1.0.5/modal/cls.pyi +0 -715
  71. modal-1.0.5/modal/container_process.pyi +0 -175
  72. modal-1.0.5/modal/dict.pyi +0 -611
  73. modal-1.0.5/modal/functions.pyi +0 -890
  74. modal-1.0.5/modal/image.pyi +0 -1792
  75. modal-1.0.5/modal/io_streams.pyi +0 -434
  76. modal-1.0.5/modal/network_file_system.pyi +0 -503
  77. modal-1.0.5/modal/partial_function.pyi +0 -413
  78. modal-1.0.5/modal/proxy.pyi +0 -37
  79. modal-1.0.5/modal/queue.pyi +0 -717
  80. modal-1.0.5/modal/secret.pyi +0 -242
  81. modal-1.0.5/modal/snapshot.pyi +0 -39
  82. modal-1.0.5/modal/volume.pyi +0 -1171
  83. {modal-1.0.5 → modal-1.0.5.dev1}/LICENSE +0 -0
  84. {modal-1.0.5 → modal-1.0.5.dev1}/README.md +0 -0
  85. {modal-1.0.5 → modal-1.0.5.dev1}/modal/__init__.py +0 -0
  86. {modal-1.0.5 → modal-1.0.5.dev1}/modal/__main__.py +0 -0
  87. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_clustered_functions.py +0 -0
  88. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_container_entrypoint.py +0 -0
  89. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_ipython.py +0 -0
  90. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_location.py +0 -0
  91. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_object.py +0 -0
  92. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_output.py +0 -0
  93. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_pty.py +0 -0
  94. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_resolver.py +0 -0
  95. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_resources.py +0 -0
  96. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_runtime/__init__.py +0 -0
  97. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_runtime/asgi.py +0 -0
  98. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_runtime/container_io_manager.py +0 -0
  99. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_runtime/execution_context.py +0 -0
  100. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  101. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_runtime/telemetry.py +0 -0
  102. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_runtime/user_code_imports.py +0 -0
  103. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_traceback.py +0 -0
  104. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_tunnel.py +0 -0
  105. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_type_manager.py +0 -0
  106. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/__init__.py +0 -0
  107. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/app_utils.py +0 -0
  108. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/async_utils.py +0 -0
  109. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/bytes_io_segment_payload.py +0 -0
  110. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/deprecation.py +0 -0
  111. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/docker_utils.py +0 -0
  112. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/git_utils.py +0 -0
  113. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/grpc_testing.py +0 -0
  114. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/hash_utils.py +0 -0
  115. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/http_utils.py +0 -0
  116. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/jwt_utils.py +0 -0
  117. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/logger.py +0 -0
  118. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/mount_utils.py +0 -0
  119. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/name_utils.py +0 -0
  120. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/package_utils.py +0 -0
  121. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/pattern_utils.py +0 -0
  122. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/rand_pb_testing.py +0 -0
  123. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/shell_utils.py +0 -0
  124. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_utils/time_utils.py +0 -0
  125. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_vendor/__init__.py +0 -0
  126. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  127. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_vendor/cloudpickle.py +0 -0
  128. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_vendor/tblib.py +0 -0
  129. {modal-1.0.5 → modal-1.0.5.dev1}/modal/_watcher.py +0 -0
  130. {modal-1.0.5 → modal-1.0.5.dev1}/modal/call_graph.py +0 -0
  131. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/__init__.py +0 -0
  132. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/_download.py +0 -0
  133. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/_traceback.py +0 -0
  134. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/app.py +0 -0
  135. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/cluster.py +0 -0
  136. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/config.py +0 -0
  137. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/container.py +0 -0
  138. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/dict.py +0 -0
  139. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/entry_point.py +0 -0
  140. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/environment.py +0 -0
  141. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/import_refs.py +0 -0
  142. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/launch.py +0 -0
  143. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/network_file_system.py +0 -0
  144. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/profile.py +0 -0
  145. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/programs/__init__.py +0 -0
  146. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/programs/run_jupyter.py +0 -0
  147. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/programs/vscode.py +0 -0
  148. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/queues.py +0 -0
  149. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/secret.py +0 -0
  150. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/token.py +0 -0
  151. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/utils.py +0 -0
  152. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cli/volume.py +0 -0
  153. {modal-1.0.5 → modal-1.0.5.dev1}/modal/client.py +0 -0
  154. {modal-1.0.5 → modal-1.0.5.dev1}/modal/cloud_bucket_mount.py +0 -0
  155. {modal-1.0.5 → modal-1.0.5.dev1}/modal/config.py +0 -0
  156. {modal-1.0.5 → modal-1.0.5.dev1}/modal/container_process.py +0 -0
  157. {modal-1.0.5 → modal-1.0.5.dev1}/modal/environments.py +0 -0
  158. {modal-1.0.5 → modal-1.0.5.dev1}/modal/file_io.py +0 -0
  159. {modal-1.0.5 → modal-1.0.5.dev1}/modal/file_pattern_matcher.py +0 -0
  160. {modal-1.0.5 → modal-1.0.5.dev1}/modal/functions.py +0 -0
  161. {modal-1.0.5 → modal-1.0.5.dev1}/modal/mount.py +0 -0
  162. {modal-1.0.5 → modal-1.0.5.dev1}/modal/object.py +0 -0
  163. {modal-1.0.5 → modal-1.0.5.dev1}/modal/output.py +0 -0
  164. {modal-1.0.5 → modal-1.0.5.dev1}/modal/partial_function.py +0 -0
  165. {modal-1.0.5 → modal-1.0.5.dev1}/modal/py.typed +0 -0
  166. {modal-1.0.5 → modal-1.0.5.dev1}/modal/requirements/2023.12.312.txt +0 -0
  167. {modal-1.0.5 → modal-1.0.5.dev1}/modal/requirements/2023.12.txt +0 -0
  168. {modal-1.0.5 → modal-1.0.5.dev1}/modal/requirements/2024.04.txt +0 -0
  169. {modal-1.0.5 → modal-1.0.5.dev1}/modal/requirements/2024.10.txt +0 -0
  170. {modal-1.0.5 → modal-1.0.5.dev1}/modal/requirements/PREVIEW.txt +0 -0
  171. {modal-1.0.5 → modal-1.0.5.dev1}/modal/requirements/README.md +0 -0
  172. {modal-1.0.5 → modal-1.0.5.dev1}/modal/requirements/base-images.json +0 -0
  173. {modal-1.0.5 → modal-1.0.5.dev1}/modal/retries.py +0 -0
  174. {modal-1.0.5 → modal-1.0.5.dev1}/modal/runner.py +0 -0
  175. {modal-1.0.5 → modal-1.0.5.dev1}/modal/running_app.py +0 -0
  176. {modal-1.0.5 → modal-1.0.5.dev1}/modal/scheduler_placement.py +0 -0
  177. {modal-1.0.5 → modal-1.0.5.dev1}/modal/serving.py +0 -0
  178. {modal-1.0.5 → modal-1.0.5.dev1}/modal/serving.pyi +0 -0
  179. {modal-1.0.5 → modal-1.0.5.dev1}/modal/snapshot.py +0 -0
  180. {modal-1.0.5 → modal-1.0.5.dev1}/modal/stream_type.py +0 -0
  181. {modal-1.0.5 → modal-1.0.5.dev1}/modal/token_flow.py +0 -0
  182. {modal-1.0.5 → modal-1.0.5.dev1}/modal.egg-info/SOURCES.txt +0 -0
  183. {modal-1.0.5 → modal-1.0.5.dev1}/modal.egg-info/dependency_links.txt +0 -0
  184. {modal-1.0.5 → modal-1.0.5.dev1}/modal.egg-info/entry_points.txt +0 -0
  185. {modal-1.0.5 → modal-1.0.5.dev1}/modal.egg-info/top_level.txt +0 -0
  186. {modal-1.0.5 → modal-1.0.5.dev1}/modal_docs/__init__.py +0 -0
  187. {modal-1.0.5 → modal-1.0.5.dev1}/modal_docs/gen_cli_docs.py +0 -0
  188. {modal-1.0.5 → modal-1.0.5.dev1}/modal_docs/gen_reference_docs.py +0 -0
  189. {modal-1.0.5 → modal-1.0.5.dev1}/modal_docs/mdmd/__init__.py +0 -0
  190. {modal-1.0.5 → modal-1.0.5.dev1}/modal_docs/mdmd/mdmd.py +0 -0
  191. {modal-1.0.5 → modal-1.0.5.dev1}/modal_docs/mdmd/signatures.py +0 -0
  192. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/__init__.py +0 -0
  193. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/modal_options_grpc.py +0 -0
  194. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/options.proto +0 -0
  195. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/options_grpc.py +0 -0
  196. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/options_pb2.py +0 -0
  197. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/options_pb2.pyi +0 -0
  198. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/options_pb2_grpc.py +0 -0
  199. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/options_pb2_grpc.pyi +0 -0
  200. {modal-1.0.5 → modal-1.0.5.dev1}/modal_proto/py.typed +0 -0
  201. {modal-1.0.5 → modal-1.0.5.dev1}/modal_version/__main__.py +0 -0
  202. {modal-1.0.5 → modal-1.0.5.dev1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.5
3
+ Version: 1.0.5.dev1
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -19,7 +19,7 @@ License-File: LICENSE
19
19
  Requires-Dist: aiohttp
20
20
  Requires-Dist: certifi
21
21
  Requires-Dist: click~=8.1.0
22
- Requires-Dist: grpclib<0.4.9,>=0.4.7
22
+ Requires-Dist: grpclib==0.4.7
23
23
  Requires-Dist: protobuf!=4.24.0,<7.0,>=3.19
24
24
  Requires-Dist: rich>=12.0.0
25
25
  Requires-Dist: synchronicity~=0.9.15
@@ -3,22 +3,12 @@ import typing
3
3
  import typing_extensions
4
4
 
5
5
  class ClusterInfo:
6
- """ClusterInfo(rank: int, container_ips: list[str])"""
7
-
8
6
  rank: int
9
7
  container_ips: list[str]
10
8
 
11
- def __init__(self, rank: int, container_ips: list[str]) -> None:
12
- """Initialize self. See help(type(self)) for accurate signature."""
13
- ...
14
-
15
- def __repr__(self):
16
- """Return repr(self)."""
17
- ...
18
-
19
- def __eq__(self, other):
20
- """Return self==value."""
21
- ...
9
+ def __init__(self, rank: int, container_ips: list[str]) -> None: ...
10
+ def __repr__(self): ...
11
+ def __eq__(self, other): ...
22
12
 
23
13
  def get_cluster_info() -> ClusterInfo: ...
24
14
  async def _initialize_clustered_function(client: modal.client._Client, task_id: str, world_size: int): ...
@@ -15,6 +15,7 @@ import typing_extensions
15
15
  from google.protobuf.message import Message
16
16
  from grpclib import GRPCError, Status
17
17
  from synchronicity.combined_types import MethodWithAio
18
+ from synchronicity.exceptions import UserCodeException
18
19
 
19
20
  from modal_proto import api_pb2
20
21
  from modal_proto.modal_api_grpc import ModalClientModal
@@ -62,6 +63,8 @@ from .cloud_bucket_mount import _CloudBucketMount, cloud_bucket_mounts_to_proto
62
63
  from .config import config
63
64
  from .exception import (
64
65
  ExecutionError,
66
+ FunctionTimeoutError,
67
+ InternalFailure,
65
68
  InvalidError,
66
69
  NotFoundError,
67
70
  OutputExpiredError,
@@ -141,13 +144,7 @@ class _Invocation:
141
144
  stub = client.stub
142
145
 
143
146
  function_id = function.object_id
144
- item = await _create_input(
145
- args,
146
- kwargs,
147
- stub,
148
- method_name=function._use_method_name,
149
- function_call_invocation_type=function_call_invocation_type,
150
- )
147
+ item = await _create_input(args, kwargs, stub, method_name=function._use_method_name)
151
148
 
152
149
  request = api_pb2.FunctionMapRequest(
153
150
  function_id=function_id,
@@ -260,7 +257,7 @@ class _Invocation:
260
257
  request,
261
258
  )
262
259
 
263
- async def _get_single_output(self, expected_jwt: Optional[str] = None) -> api_pb2.FunctionGetOutputsItem:
260
+ async def _get_single_output(self, expected_jwt: Optional[str] = None) -> Any:
264
261
  # waits indefinitely for a single result for the function, and clear the outputs buffer after
265
262
  item: api_pb2.FunctionGetOutputsItem = (
266
263
  await self.pop_function_call_outputs(
@@ -269,7 +266,7 @@ class _Invocation:
269
266
  input_jwts=[expected_jwt] if expected_jwt else None,
270
267
  )
271
268
  ).outputs[0]
272
- return item
269
+ return await _process_result(item.result, item.data_format, self.stub, self.client)
273
270
 
274
271
  async def run_function(self) -> Any:
275
272
  # Use retry logic only if retry policy is specified and
@@ -281,30 +278,23 @@ class _Invocation:
281
278
  or ctx.function_call_invocation_type != api_pb2.FUNCTION_CALL_INVOCATION_TYPE_SYNC
282
279
  or not ctx.sync_client_retries_enabled
283
280
  ):
284
- item = await self._get_single_output()
285
- return await _process_result(item.result, item.data_format, self.stub, self.client)
281
+ return await self._get_single_output()
286
282
 
287
283
  # User errors including timeouts are managed by the user specified retry policy.
288
284
  user_retry_manager = RetryManager(ctx.retry_policy)
289
285
 
290
286
  while True:
291
- item = await self._get_single_output(ctx.input_jwt)
292
- if item.result.status in (
293
- api_pb2.GenericResult.GENERIC_STATUS_SUCCESS,
294
- api_pb2.GenericResult.GENERIC_STATUS_TERMINATED,
295
- ):
296
- # success or cancellations are "final" results
297
- return await _process_result(item.result, item.data_format, self.stub, self.client)
298
-
299
- if item.result.status != api_pb2.GenericResult.GENERIC_STATUS_INTERNAL_FAILURE:
300
- # non-internal failures get a delay before retrying
287
+ try:
288
+ return await self._get_single_output(ctx.input_jwt)
289
+ except (UserCodeException, FunctionTimeoutError) as exc:
301
290
  delay_ms = user_retry_manager.get_delay_ms()
302
291
  if delay_ms is None:
303
- # no more retries, this should raise an error when the non-success status is converted
304
- # to an exception:
305
- return await _process_result(item.result, item.data_format, self.stub, self.client)
292
+ raise exc
306
293
  await asyncio.sleep(delay_ms / 1000)
307
-
294
+ except InternalFailure:
295
+ # For system failures on the server, we retry immediately,
296
+ # and the failure does not count towards the retry policy.
297
+ pass
308
298
  await self._retry_input()
309
299
 
310
300
  async def poll_function(self, timeout: Optional[float] = None):
@@ -362,14 +352,12 @@ class _InputPlaneInvocation:
362
352
  client: _Client,
363
353
  input_item: api_pb2.FunctionPutInputsItem,
364
354
  function_id: str,
365
- input_plane_region: str,
366
355
  ):
367
356
  self.stub = stub
368
357
  self.client = client # Used by the deserializer.
369
358
  self.attempt_token = attempt_token
370
359
  self.input_item = input_item
371
360
  self.function_id = function_id
372
- self.input_plane_region = input_plane_region
373
361
 
374
362
  @staticmethod
375
363
  async def create(
@@ -379,27 +367,21 @@ class _InputPlaneInvocation:
379
367
  *,
380
368
  client: _Client,
381
369
  input_plane_url: str,
382
- input_plane_region: str,
383
370
  ) -> "_InputPlaneInvocation":
384
371
  stub = await client.get_stub(input_plane_url)
385
372
 
386
373
  function_id = function.object_id
387
- control_plane_stub = client.stub
388
- # Note: Blob upload is done on the control plane stub, not the input plane stub!
389
- input_item = await _create_input(args, kwargs, control_plane_stub, method_name=function._use_method_name)
374
+ input_item = await _create_input(args, kwargs, stub, method_name=function._use_method_name)
390
375
 
391
376
  request = api_pb2.AttemptStartRequest(
392
377
  function_id=function_id,
393
378
  parent_input_id=current_input_id() or "",
394
379
  input=input_item,
395
380
  )
396
- metadata: list[tuple[str, str]] = []
397
- if input_plane_region and input_plane_region != "":
398
- metadata.append(("x-modal-input-plane-region", input_plane_region))
399
- response = await retry_transient_errors(stub.AttemptStart, request, metadata=metadata)
381
+ response = await retry_transient_errors(stub.AttemptStart, request)
400
382
  attempt_token = response.attempt_token
401
383
 
402
- return _InputPlaneInvocation(stub, attempt_token, client, input_item, function_id, input_plane_region)
384
+ return _InputPlaneInvocation(stub, attempt_token, client, input_item, function_id)
403
385
 
404
386
  async def run_function(self) -> Any:
405
387
  # This will retry when the server returns GENERIC_STATUS_INTERNAL_FAILURE, i.e. lost inputs or worker preemption
@@ -411,41 +393,33 @@ class _InputPlaneInvocation:
411
393
  timeout_secs=OUTPUTS_TIMEOUT,
412
394
  requested_at=time.time(),
413
395
  )
414
- metadata: list[tuple[str, str]] = []
415
- if self.input_plane_region and self.input_plane_region != "":
416
- metadata.append(("x-modal-input-plane-region", self.input_plane_region))
417
396
  await_response: api_pb2.AttemptAwaitResponse = await retry_transient_errors(
418
397
  self.stub.AttemptAwait,
419
398
  await_request,
420
399
  attempt_timeout=OUTPUTS_TIMEOUT + ATTEMPT_TIMEOUT_GRACE_PERIOD,
421
- metadata=metadata,
422
400
  )
423
401
 
424
- if await_response.HasField("output"):
425
- if await_response.output.result.status == api_pb2.GenericResult.GENERIC_STATUS_INTERNAL_FAILURE:
426
- internal_failure_count += 1
427
- # Limit the number of times we retry
428
- if internal_failure_count < MAX_INTERNAL_FAILURE_COUNT:
429
- # For system failures on the server, we retry immediately,
430
- # and the failure does not count towards the retry policy.
431
- retry_request = api_pb2.AttemptRetryRequest(
432
- function_id=self.function_id,
433
- parent_input_id=current_input_id() or "",
434
- input=self.input_item,
435
- attempt_token=self.attempt_token,
436
- )
437
- # TODO(ryan): Add exponential backoff?
438
- retry_response = await retry_transient_errors(
439
- self.stub.AttemptRetry,
440
- retry_request,
441
- metadata=metadata,
442
- )
443
- self.attempt_token = retry_response.attempt_token
444
- continue
445
-
446
- return await _process_result(
447
- await_response.output.result, await_response.output.data_format, self.stub, self.client
402
+ try:
403
+ if await_response.HasField("output"):
404
+ return await _process_result(
405
+ await_response.output.result, await_response.output.data_format, self.stub, self.client
406
+ )
407
+ except InternalFailure as e:
408
+ internal_failure_count += 1
409
+ # Limit the number of times we retry
410
+ if internal_failure_count >= MAX_INTERNAL_FAILURE_COUNT:
411
+ raise e
412
+ # For system failures on the server, we retry immediately,
413
+ # and the failure does not count towards the retry policy.
414
+ retry_request = api_pb2.AttemptRetryRequest(
415
+ function_id=self.function_id,
416
+ parent_input_id=current_input_id() or "",
417
+ input=self.input_item,
418
+ attempt_token=self.attempt_token,
448
419
  )
420
+ # TODO(ryan): Add exponential backoff?
421
+ retry_response = await retry_transient_errors(self.stub.AttemptRetry, retry_request)
422
+ self.attempt_token = retry_response.attempt_token
449
423
 
450
424
 
451
425
  # Wrapper type for api_pb2.FunctionStats
@@ -799,7 +773,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
799
773
  req.method_definitions[method_name].CopyFrom(method_definition)
800
774
  elif webhook_config:
801
775
  req.webhook_config.CopyFrom(webhook_config)
802
-
803
776
  response = await retry_transient_errors(resolver.client.stub.FunctionPrecreate, req)
804
777
  self._hydrate(response.function_id, resolver.client, response.handle_metadata)
805
778
 
@@ -854,7 +827,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
854
827
  mount_path=path,
855
828
  volume_id=volume.object_id,
856
829
  allow_background_commits=True,
857
- read_only=volume._read_only,
858
830
  )
859
831
  for path, volume in validated_volumes_no_cloud_buckets
860
832
  ]
@@ -1108,7 +1080,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1108
1080
  mount_path=path,
1109
1081
  volume_id=volume.object_id,
1110
1082
  allow_background_commits=True,
1111
- read_only=volume._read_only,
1112
1083
  )
1113
1084
  for path, volume in options.validated_volumes
1114
1085
  ]
@@ -1281,9 +1252,9 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1281
1252
  ) -> "_Function":
1282
1253
  """Reference a Function from a deployed App by its name.
1283
1254
 
1284
- This is a lazy method that defers hydrating the local
1285
- object with metadata from Modal servers until the first
1286
- time it is actually used.
1255
+ In contrast to `modal.Function.lookup`, this is a lazy method
1256
+ that defers hydrating the local object with metadata from
1257
+ Modal servers until the first time it is actually used.
1287
1258
 
1288
1259
  ```python
1289
1260
  f = modal.Function.from_name("other-app", "function")
@@ -1406,7 +1377,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1406
1377
  self._method_handle_metadata = dict(metadata.method_handle_metadata)
1407
1378
  self._definition_id = metadata.definition_id
1408
1379
  self._input_plane_url = metadata.input_plane_url
1409
- self._input_plane_region = metadata.input_plane_region
1410
1380
 
1411
1381
  def _get_metadata(self):
1412
1382
  # Overridden concrete implementation of base class method
@@ -1422,7 +1392,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1422
1392
  method_handle_metadata=self._method_handle_metadata,
1423
1393
  function_schema=self._metadata.function_schema if self._metadata else None,
1424
1394
  input_plane_url=self._input_plane_url,
1425
- input_plane_region=self._input_plane_region,
1426
1395
  )
1427
1396
 
1428
1397
  def _check_no_web_url(self, fn_name: str):
@@ -1469,11 +1438,7 @@ Use the `Function.get_web_url()` method instead.
1469
1438
 
1470
1439
  @live_method_gen
1471
1440
  async def _map(
1472
- self,
1473
- input_queue: _SynchronizedQueue,
1474
- order_outputs: bool,
1475
- return_exceptions: bool,
1476
- wrap_returned_exceptions: bool,
1441
+ self, input_queue: _SynchronizedQueue, order_outputs: bool, return_exceptions: bool
1477
1442
  ) -> AsyncGenerator[Any, None]:
1478
1443
  """mdmd:hidden
1479
1444
 
@@ -1501,7 +1466,6 @@ Use the `Function.get_web_url()` method instead.
1501
1466
  self.client,
1502
1467
  order_outputs,
1503
1468
  return_exceptions,
1504
- wrap_returned_exceptions,
1505
1469
  count_update_callback,
1506
1470
  api_pb2.FUNCTION_CALL_INVOCATION_TYPE_SYNC,
1507
1471
  )
@@ -1518,7 +1482,6 @@ Use the `Function.get_web_url()` method instead.
1518
1482
  kwargs,
1519
1483
  client=self.client,
1520
1484
  input_plane_url=self._input_plane_url,
1521
- input_plane_region=self._input_plane_region,
1522
1485
  )
1523
1486
  else:
1524
1487
  invocation = await _Invocation.create(
@@ -1699,9 +1662,8 @@ Use the `Function.get_web_url()` method instead.
1699
1662
  async def spawn(self, *args: P.args, **kwargs: P.kwargs) -> "_FunctionCall[ReturnType]":
1700
1663
  """Calls the function with the given arguments, without waiting for the results.
1701
1664
 
1702
- Returns a [`modal.FunctionCall`](https://modal.com/docs/reference/modal.FunctionCall) object
1703
- that can later be polled or waited for using
1704
- [`.get(timeout=...)`](https://modal.com/docs/reference/modal.FunctionCall#get).
1665
+ Returns a [`modal.FunctionCall`](/docs/reference/modal.FunctionCall) object, that can later be polled or
1666
+ waited for using [`.get(timeout=...)`](/docs/reference/modal.FunctionCall#get).
1705
1667
  Conceptually similar to `multiprocessing.pool.apply_async`, or a Future/Promise in other contexts.
1706
1668
  """
1707
1669
  self._check_no_web_url("spawn")
@@ -1777,7 +1739,7 @@ class _FunctionCall(typing.Generic[ReturnType], _Object, type_prefix="fc"):
1777
1739
  """Returns a structure representing the call graph from a given root
1778
1740
  call ID, along with the status of execution for each node.
1779
1741
 
1780
- See [`modal.call_graph`](https://modal.com/docs/reference/modal.call_graph) reference page
1742
+ See [`modal.call_graph`](/docs/reference/modal.call_graph) reference page
1781
1743
  for documentation on the structure of the returned `InputInfo` items.
1782
1744
  """
1783
1745
  assert self._client and self._client.stub
@@ -1791,7 +1753,7 @@ class _FunctionCall(typing.Generic[ReturnType], _Object, type_prefix="fc"):
1791
1753
  terminate_containers: bool = False,
1792
1754
  ):
1793
1755
  """Cancels the function call, which will stop its execution and mark its inputs as
1794
- [`TERMINATED`](https://modal.com/docs/reference/modal.call_graph#modalcall_graphinputstatus).
1756
+ [`TERMINATED`](/docs/reference/modal.call_graph#modalcall_graphinputstatus).
1795
1757
 
1796
1758
  If `terminate_containers=True` - the containers running the cancelled inputs are all terminated
1797
1759
  causing any non-cancelled inputs on those containers to be rescheduled in new containers.
@@ -538,7 +538,7 @@ def _wsgi_app(
538
538
  Web Server Gateway Interface (WSGI) is a standard for synchronous Python web apps.
539
539
  It has been [succeeded by the ASGI interface](https://asgi.readthedocs.io/en/latest/introduction.html#wsgi-compatibility)
540
540
  which is compatible with ASGI and supports additional functionality such as web sockets.
541
- Modal supports ASGI via [`asgi_app`](https://modal.com/docs/reference/modal.asgi_app).
541
+ Modal supports ASGI via [`asgi_app`](/docs/reference/modal.asgi_app).
542
542
 
543
543
  **Usage:**
544
544