modal 1.0.5.dev12__tar.gz → 1.0.5.dev13__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 (184) hide show
  1. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/PKG-INFO +1 -1
  2. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_functions.py +21 -3
  3. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/grpc_utils.py +8 -3
  4. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/client.pyi +2 -2
  5. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal.egg-info/PKG-INFO +1 -1
  6. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/api.proto +1 -0
  7. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/api_pb2.py +508 -508
  8. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/api_pb2.pyi +8 -2
  9. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_version/__init__.py +1 -1
  10. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/LICENSE +0 -0
  11. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/README.md +0 -0
  12. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/__init__.py +0 -0
  13. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/__main__.py +0 -0
  14. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_clustered_functions.py +0 -0
  15. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_clustered_functions.pyi +0 -0
  16. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_container_entrypoint.py +0 -0
  17. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_ipython.py +0 -0
  18. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_location.py +0 -0
  19. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_object.py +0 -0
  20. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_output.py +0 -0
  21. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_partial_function.py +0 -0
  22. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_pty.py +0 -0
  23. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_resolver.py +0 -0
  24. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_resources.py +0 -0
  25. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_runtime/__init__.py +0 -0
  26. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_runtime/asgi.py +0 -0
  27. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_runtime/container_io_manager.py +0 -0
  28. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_runtime/container_io_manager.pyi +0 -0
  29. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_runtime/execution_context.py +0 -0
  30. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_runtime/execution_context.pyi +0 -0
  31. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  32. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_runtime/telemetry.py +0 -0
  33. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_runtime/user_code_imports.py +0 -0
  34. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_serialization.py +0 -0
  35. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_traceback.py +0 -0
  36. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_tunnel.py +0 -0
  37. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_tunnel.pyi +0 -0
  38. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_type_manager.py +0 -0
  39. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/__init__.py +0 -0
  40. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/app_utils.py +0 -0
  41. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/async_utils.py +0 -0
  42. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/blob_utils.py +0 -0
  43. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/bytes_io_segment_payload.py +0 -0
  44. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/deprecation.py +0 -0
  45. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/docker_utils.py +0 -0
  46. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/function_utils.py +0 -0
  47. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/git_utils.py +0 -0
  48. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/grpc_testing.py +0 -0
  49. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/hash_utils.py +0 -0
  50. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/http_utils.py +0 -0
  51. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/jwt_utils.py +0 -0
  52. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/logger.py +0 -0
  53. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/mount_utils.py +0 -0
  54. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/name_utils.py +0 -0
  55. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/package_utils.py +0 -0
  56. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/pattern_utils.py +0 -0
  57. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/rand_pb_testing.py +0 -0
  58. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/shell_utils.py +0 -0
  59. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_utils/time_utils.py +0 -0
  60. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_vendor/__init__.py +0 -0
  61. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  62. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_vendor/cloudpickle.py +0 -0
  63. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_vendor/tblib.py +0 -0
  64. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/_watcher.py +0 -0
  65. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/app.py +0 -0
  66. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/app.pyi +0 -0
  67. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/call_graph.py +0 -0
  68. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/__init__.py +0 -0
  69. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/_download.py +0 -0
  70. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/_traceback.py +0 -0
  71. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/app.py +0 -0
  72. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/cluster.py +0 -0
  73. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/config.py +0 -0
  74. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/container.py +0 -0
  75. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/dict.py +0 -0
  76. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/entry_point.py +0 -0
  77. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/environment.py +0 -0
  78. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/import_refs.py +0 -0
  79. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/launch.py +0 -0
  80. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/network_file_system.py +0 -0
  81. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/profile.py +0 -0
  82. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/programs/__init__.py +0 -0
  83. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/programs/run_jupyter.py +0 -0
  84. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/programs/vscode.py +0 -0
  85. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/queues.py +0 -0
  86. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/run.py +0 -0
  87. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/secret.py +0 -0
  88. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/token.py +0 -0
  89. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/utils.py +0 -0
  90. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cli/volume.py +0 -0
  91. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/client.py +0 -0
  92. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cloud_bucket_mount.py +0 -0
  93. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cloud_bucket_mount.pyi +0 -0
  94. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cls.py +0 -0
  95. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/cls.pyi +0 -0
  96. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/config.py +0 -0
  97. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/container_process.py +0 -0
  98. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/container_process.pyi +0 -0
  99. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/dict.py +0 -0
  100. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/dict.pyi +0 -0
  101. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/environments.py +0 -0
  102. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/environments.pyi +0 -0
  103. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/exception.py +0 -0
  104. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/experimental/__init__.py +0 -0
  105. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/experimental/ipython.py +0 -0
  106. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/file_io.py +0 -0
  107. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/file_io.pyi +0 -0
  108. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/file_pattern_matcher.py +0 -0
  109. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/functions.py +0 -0
  110. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/functions.pyi +0 -0
  111. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/gpu.py +0 -0
  112. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/image.py +0 -0
  113. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/image.pyi +0 -0
  114. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/io_streams.py +0 -0
  115. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/io_streams.pyi +0 -0
  116. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/mount.py +0 -0
  117. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/mount.pyi +0 -0
  118. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/network_file_system.py +0 -0
  119. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/network_file_system.pyi +0 -0
  120. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/object.py +0 -0
  121. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/object.pyi +0 -0
  122. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/output.py +0 -0
  123. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/parallel_map.py +0 -0
  124. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/parallel_map.pyi +0 -0
  125. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/partial_function.py +0 -0
  126. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/partial_function.pyi +0 -0
  127. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/proxy.py +0 -0
  128. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/proxy.pyi +0 -0
  129. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/py.typed +0 -0
  130. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/queue.py +0 -0
  131. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/queue.pyi +0 -0
  132. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/requirements/2023.12.312.txt +0 -0
  133. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/requirements/2023.12.txt +0 -0
  134. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/requirements/2024.04.txt +0 -0
  135. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/requirements/2024.10.txt +0 -0
  136. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/requirements/PREVIEW.txt +0 -0
  137. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/requirements/README.md +0 -0
  138. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/requirements/base-images.json +0 -0
  139. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/retries.py +0 -0
  140. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/runner.py +0 -0
  141. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/runner.pyi +0 -0
  142. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/running_app.py +0 -0
  143. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/sandbox.py +0 -0
  144. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/sandbox.pyi +0 -0
  145. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/schedule.py +0 -0
  146. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/scheduler_placement.py +0 -0
  147. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/secret.py +0 -0
  148. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/secret.pyi +0 -0
  149. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/serving.py +0 -0
  150. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/serving.pyi +0 -0
  151. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/snapshot.py +0 -0
  152. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/snapshot.pyi +0 -0
  153. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/stream_type.py +0 -0
  154. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/token_flow.py +0 -0
  155. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/token_flow.pyi +0 -0
  156. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/volume.py +0 -0
  157. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal/volume.pyi +0 -0
  158. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal.egg-info/SOURCES.txt +0 -0
  159. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal.egg-info/dependency_links.txt +0 -0
  160. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal.egg-info/entry_points.txt +0 -0
  161. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal.egg-info/requires.txt +0 -0
  162. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal.egg-info/top_level.txt +0 -0
  163. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_docs/__init__.py +0 -0
  164. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_docs/gen_cli_docs.py +0 -0
  165. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_docs/gen_reference_docs.py +0 -0
  166. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_docs/mdmd/__init__.py +0 -0
  167. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_docs/mdmd/mdmd.py +0 -0
  168. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_docs/mdmd/signatures.py +0 -0
  169. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/__init__.py +0 -0
  170. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/api_grpc.py +0 -0
  171. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/api_pb2_grpc.py +0 -0
  172. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/api_pb2_grpc.pyi +0 -0
  173. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/modal_api_grpc.py +0 -0
  174. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/modal_options_grpc.py +0 -0
  175. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/options.proto +0 -0
  176. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/options_grpc.py +0 -0
  177. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/options_pb2.py +0 -0
  178. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/options_pb2.pyi +0 -0
  179. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/options_pb2_grpc.py +0 -0
  180. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/options_pb2_grpc.pyi +0 -0
  181. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_proto/py.typed +0 -0
  182. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/modal_version/__main__.py +0 -0
  183. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/pyproject.toml +0 -0
  184. {modal-1.0.5.dev12 → modal-1.0.5.dev13}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.5.dev12
3
+ Version: 1.0.5.dev13
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -356,12 +356,14 @@ class _InputPlaneInvocation:
356
356
  client: _Client,
357
357
  input_item: api_pb2.FunctionPutInputsItem,
358
358
  function_id: str,
359
+ input_plane_region: str,
359
360
  ):
360
361
  self.stub = stub
361
362
  self.client = client # Used by the deserializer.
362
363
  self.attempt_token = attempt_token
363
364
  self.input_item = input_item
364
365
  self.function_id = function_id
366
+ self.input_plane_region = input_plane_region
365
367
 
366
368
  @staticmethod
367
369
  async def create(
@@ -371,6 +373,7 @@ class _InputPlaneInvocation:
371
373
  *,
372
374
  client: _Client,
373
375
  input_plane_url: str,
376
+ input_plane_region: str,
374
377
  ) -> "_InputPlaneInvocation":
375
378
  stub = await client.get_stub(input_plane_url)
376
379
 
@@ -384,10 +387,13 @@ class _InputPlaneInvocation:
384
387
  parent_input_id=current_input_id() or "",
385
388
  input=input_item,
386
389
  )
387
- response = await retry_transient_errors(stub.AttemptStart, request)
390
+ metadata: list[tuple[str, str]] = []
391
+ if input_plane_region and input_plane_region != "":
392
+ metadata.append(("x-modal-input-plane-region", input_plane_region))
393
+ response = await retry_transient_errors(stub.AttemptStart, request, metadata=metadata)
388
394
  attempt_token = response.attempt_token
389
395
 
390
- return _InputPlaneInvocation(stub, attempt_token, client, input_item, function_id)
396
+ return _InputPlaneInvocation(stub, attempt_token, client, input_item, function_id, input_plane_region)
391
397
 
392
398
  async def run_function(self) -> Any:
393
399
  # This will retry when the server returns GENERIC_STATUS_INTERNAL_FAILURE, i.e. lost inputs or worker preemption
@@ -399,10 +405,14 @@ class _InputPlaneInvocation:
399
405
  timeout_secs=OUTPUTS_TIMEOUT,
400
406
  requested_at=time.time(),
401
407
  )
408
+ metadata: list[tuple[str, str]] = []
409
+ if self.input_plane_region and self.input_plane_region != "":
410
+ metadata.append(("x-modal-input-plane-region", self.input_plane_region))
402
411
  await_response: api_pb2.AttemptAwaitResponse = await retry_transient_errors(
403
412
  self.stub.AttemptAwait,
404
413
  await_request,
405
414
  attempt_timeout=OUTPUTS_TIMEOUT + ATTEMPT_TIMEOUT_GRACE_PERIOD,
415
+ metadata=metadata,
406
416
  )
407
417
 
408
418
  if await_response.HasField("output"):
@@ -419,7 +429,11 @@ class _InputPlaneInvocation:
419
429
  attempt_token=self.attempt_token,
420
430
  )
421
431
  # TODO(ryan): Add exponential backoff?
422
- retry_response = await retry_transient_errors(self.stub.AttemptRetry, retry_request)
432
+ retry_response = await retry_transient_errors(
433
+ self.stub.AttemptRetry,
434
+ retry_request,
435
+ metadata=metadata,
436
+ )
423
437
  self.attempt_token = retry_response.attempt_token
424
438
  continue
425
439
 
@@ -779,6 +793,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
779
793
  req.method_definitions[method_name].CopyFrom(method_definition)
780
794
  elif webhook_config:
781
795
  req.webhook_config.CopyFrom(webhook_config)
796
+
782
797
  response = await retry_transient_errors(resolver.client.stub.FunctionPrecreate, req)
783
798
  self._hydrate(response.function_id, resolver.client, response.handle_metadata)
784
799
 
@@ -1383,6 +1398,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1383
1398
  self._method_handle_metadata = dict(metadata.method_handle_metadata)
1384
1399
  self._definition_id = metadata.definition_id
1385
1400
  self._input_plane_url = metadata.input_plane_url
1401
+ self._input_plane_region = metadata.input_plane_region
1386
1402
 
1387
1403
  def _get_metadata(self):
1388
1404
  # Overridden concrete implementation of base class method
@@ -1398,6 +1414,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1398
1414
  method_handle_metadata=self._method_handle_metadata,
1399
1415
  function_schema=self._metadata.function_schema if self._metadata else None,
1400
1416
  input_plane_url=self._input_plane_url,
1417
+ input_plane_region=self._input_plane_region,
1401
1418
  )
1402
1419
 
1403
1420
  def _check_no_web_url(self, fn_name: str):
@@ -1493,6 +1510,7 @@ Use the `Function.get_web_url()` method instead.
1493
1510
  kwargs,
1494
1511
  client=self.client,
1495
1512
  input_plane_url=self._input_plane_url,
1513
+ input_plane_region=self._input_plane_region,
1496
1514
  )
1497
1515
  else:
1498
1516
  invocation = await _Invocation.create(
@@ -198,6 +198,7 @@ async def retry_transient_errors(
198
198
  total_timeout: Optional[float] = None, # timeout for the entire function call
199
199
  attempt_timeout_floor=2.0, # always have at least this much timeout (only for total_timeout)
200
200
  retry_warning_message: Optional[RetryWarningMessage] = None,
201
+ metadata: list[tuple[str, str]] = [],
201
202
  ) -> ResponseType:
202
203
  """Retry on transient gRPC failures with back-off until max_retries is reached.
203
204
  If max_retries is None, retry forever."""
@@ -216,9 +217,13 @@ async def retry_transient_errors(
216
217
  total_deadline = None
217
218
 
218
219
  while True:
219
- metadata = [("x-idempotency-key", idempotency_key), ("x-retry-attempt", str(n_retries))]
220
+ attempt_metadata = [
221
+ ("x-idempotency-key", idempotency_key),
222
+ ("x-retry-attempt", str(n_retries)),
223
+ *metadata,
224
+ ]
220
225
  if n_retries > 0:
221
- metadata.append(("x-retry-delay", str(time.time() - t0)))
226
+ attempt_metadata.append(("x-retry-delay", str(time.time() - t0)))
222
227
  timeouts = []
223
228
  if attempt_timeout is not None:
224
229
  timeouts.append(attempt_timeout)
@@ -229,7 +234,7 @@ async def retry_transient_errors(
229
234
  else:
230
235
  timeout = None
231
236
  try:
232
- return await fn(*args, metadata=metadata, timeout=timeout)
237
+ return await fn(*args, metadata=attempt_metadata, timeout=timeout)
233
238
  except (StreamTerminatedError, GRPCError, OSError, asyncio.TimeoutError, AttributeError) as exc:
234
239
  if isinstance(exc, GRPCError) and exc.status not in status_codes:
235
240
  if exc.status == Status.UNAUTHENTICATED:
@@ -31,7 +31,7 @@ class _Client:
31
31
  server_url: str,
32
32
  client_type: int,
33
33
  credentials: typing.Optional[tuple[str, str]],
34
- version: str = "1.0.5.dev12",
34
+ version: str = "1.0.5.dev13",
35
35
  ):
36
36
  """mdmd:hidden
37
37
  The Modal client object is not intended to be instantiated directly by users.
@@ -160,7 +160,7 @@ class Client:
160
160
  server_url: str,
161
161
  client_type: int,
162
162
  credentials: typing.Optional[tuple[str, str]],
163
- version: str = "1.0.5.dev12",
163
+ version: str = "1.0.5.dev13",
164
164
  ):
165
165
  """mdmd:hidden
166
166
  The Modal client object is not intended to be instantiated directly by users.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.5.dev12
3
+ Version: 1.0.5.dev13
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -1703,6 +1703,7 @@ message FunctionHandleMetadata {
1703
1703
  map<string, FunctionHandleMetadata> method_handle_metadata = 44;
1704
1704
  FunctionSchema function_schema = 45;
1705
1705
  optional string input_plane_url = 46;
1706
+ optional string input_plane_region = 47;
1706
1707
  }
1707
1708
 
1708
1709
  message FunctionInput {