modal 1.0.6.dev54__tar.gz → 1.0.6.dev56__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.

Potentially problematic release.


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

Files changed (188) hide show
  1. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/PKG-INFO +1 -1
  2. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_functions.py +1 -1
  3. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_partial_function.py +6 -1
  4. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_runtime/container_io_manager.py +5 -1
  5. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/function_utils.py +6 -3
  6. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/app.py +15 -1
  7. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/client.pyi +2 -2
  8. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/functions.pyi +6 -6
  9. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal.egg-info/PKG-INFO +1 -1
  10. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_version/__init__.py +1 -1
  11. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/LICENSE +0 -0
  12. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/README.md +0 -0
  13. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/__init__.py +0 -0
  14. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/__main__.py +0 -0
  15. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_clustered_functions.py +0 -0
  16. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_clustered_functions.pyi +0 -0
  17. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_container_entrypoint.py +0 -0
  18. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_ipython.py +0 -0
  19. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_location.py +0 -0
  20. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_object.py +0 -0
  21. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_output.py +0 -0
  22. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_pty.py +0 -0
  23. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_resolver.py +0 -0
  24. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_resources.py +0 -0
  25. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_runtime/__init__.py +0 -0
  26. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_runtime/asgi.py +0 -0
  27. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_runtime/container_io_manager.pyi +0 -0
  28. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_runtime/execution_context.py +0 -0
  29. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_runtime/execution_context.pyi +0 -0
  30. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  31. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_runtime/telemetry.py +0 -0
  32. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_runtime/user_code_imports.py +0 -0
  33. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_serialization.py +0 -0
  34. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_traceback.py +0 -0
  35. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_tunnel.py +0 -0
  36. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_tunnel.pyi +0 -0
  37. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_type_manager.py +0 -0
  38. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/__init__.py +0 -0
  39. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/app_utils.py +0 -0
  40. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/async_utils.py +0 -0
  41. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/auth_token_manager.py +0 -0
  42. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/blob_utils.py +0 -0
  43. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/bytes_io_segment_payload.py +0 -0
  44. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/deprecation.py +0 -0
  45. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/docker_utils.py +0 -0
  46. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/git_utils.py +0 -0
  47. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/grpc_testing.py +0 -0
  48. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/grpc_utils.py +0 -0
  49. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/hash_utils.py +0 -0
  50. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/http_utils.py +0 -0
  51. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/jwt_utils.py +0 -0
  52. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/logger.py +0 -0
  53. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/mount_utils.py +0 -0
  54. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/name_utils.py +0 -0
  55. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/package_utils.py +0 -0
  56. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/pattern_utils.py +0 -0
  57. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/rand_pb_testing.py +0 -0
  58. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/shell_utils.py +0 -0
  59. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_utils/time_utils.py +0 -0
  60. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_vendor/__init__.py +0 -0
  61. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  62. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_vendor/cloudpickle.py +0 -0
  63. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_vendor/tblib.py +0 -0
  64. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/_watcher.py +0 -0
  65. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/app.pyi +0 -0
  66. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/call_graph.py +0 -0
  67. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/__init__.py +0 -0
  68. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/_download.py +0 -0
  69. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/_traceback.py +0 -0
  70. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/app.py +0 -0
  71. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/cluster.py +0 -0
  72. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/config.py +0 -0
  73. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/container.py +0 -0
  74. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/dict.py +0 -0
  75. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/entry_point.py +0 -0
  76. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/environment.py +0 -0
  77. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/import_refs.py +0 -0
  78. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/launch.py +0 -0
  79. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/network_file_system.py +0 -0
  80. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/profile.py +0 -0
  81. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/programs/__init__.py +0 -0
  82. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/programs/run_jupyter.py +0 -0
  83. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/programs/vscode.py +0 -0
  84. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/queues.py +0 -0
  85. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/run.py +0 -0
  86. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/secret.py +0 -0
  87. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/token.py +0 -0
  88. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/utils.py +0 -0
  89. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cli/volume.py +0 -0
  90. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/client.py +0 -0
  91. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cloud_bucket_mount.py +0 -0
  92. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cloud_bucket_mount.pyi +0 -0
  93. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cls.py +0 -0
  94. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/cls.pyi +0 -0
  95. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/config.py +0 -0
  96. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/container_process.py +0 -0
  97. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/container_process.pyi +0 -0
  98. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/dict.py +0 -0
  99. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/dict.pyi +0 -0
  100. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/environments.py +0 -0
  101. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/environments.pyi +0 -0
  102. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/exception.py +0 -0
  103. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/experimental/__init__.py +0 -0
  104. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/experimental/flash.py +0 -0
  105. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/experimental/flash.pyi +0 -0
  106. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/experimental/ipython.py +0 -0
  107. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/file_io.py +0 -0
  108. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/file_io.pyi +0 -0
  109. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/file_pattern_matcher.py +0 -0
  110. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/functions.py +0 -0
  111. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/gpu.py +0 -0
  112. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/image.py +0 -0
  113. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/image.pyi +0 -0
  114. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/io_streams.py +0 -0
  115. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/io_streams.pyi +0 -0
  116. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/mount.py +0 -0
  117. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/mount.pyi +0 -0
  118. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/network_file_system.py +0 -0
  119. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/network_file_system.pyi +0 -0
  120. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/object.py +0 -0
  121. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/object.pyi +0 -0
  122. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/output.py +0 -0
  123. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/parallel_map.py +0 -0
  124. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/parallel_map.pyi +0 -0
  125. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/partial_function.py +0 -0
  126. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/partial_function.pyi +0 -0
  127. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/proxy.py +0 -0
  128. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/proxy.pyi +0 -0
  129. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/py.typed +0 -0
  130. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/queue.py +0 -0
  131. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/queue.pyi +0 -0
  132. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/requirements/2023.12.312.txt +0 -0
  133. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/requirements/2023.12.txt +0 -0
  134. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/requirements/2024.04.txt +0 -0
  135. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/requirements/2024.10.txt +0 -0
  136. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/requirements/2025.06.txt +0 -0
  137. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/requirements/PREVIEW.txt +0 -0
  138. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/requirements/README.md +0 -0
  139. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/requirements/base-images.json +0 -0
  140. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/retries.py +0 -0
  141. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/runner.py +0 -0
  142. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/runner.pyi +0 -0
  143. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/running_app.py +0 -0
  144. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/sandbox.py +0 -0
  145. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/sandbox.pyi +0 -0
  146. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/schedule.py +0 -0
  147. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/scheduler_placement.py +0 -0
  148. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/secret.py +0 -0
  149. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/secret.pyi +0 -0
  150. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/serving.py +0 -0
  151. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/serving.pyi +0 -0
  152. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/snapshot.py +0 -0
  153. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/snapshot.pyi +0 -0
  154. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/stream_type.py +0 -0
  155. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/token_flow.py +0 -0
  156. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/token_flow.pyi +0 -0
  157. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/volume.py +0 -0
  158. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal/volume.pyi +0 -0
  159. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal.egg-info/SOURCES.txt +0 -0
  160. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal.egg-info/dependency_links.txt +0 -0
  161. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal.egg-info/entry_points.txt +0 -0
  162. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal.egg-info/requires.txt +0 -0
  163. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal.egg-info/top_level.txt +0 -0
  164. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_docs/__init__.py +0 -0
  165. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_docs/gen_cli_docs.py +0 -0
  166. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_docs/gen_reference_docs.py +0 -0
  167. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_docs/mdmd/__init__.py +0 -0
  168. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_docs/mdmd/mdmd.py +0 -0
  169. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_docs/mdmd/signatures.py +0 -0
  170. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/__init__.py +0 -0
  171. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/api.proto +0 -0
  172. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/api_grpc.py +0 -0
  173. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/api_pb2.py +0 -0
  174. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/api_pb2.pyi +0 -0
  175. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/api_pb2_grpc.py +0 -0
  176. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/api_pb2_grpc.pyi +0 -0
  177. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/modal_api_grpc.py +0 -0
  178. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/modal_options_grpc.py +0 -0
  179. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/options.proto +0 -0
  180. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/options_grpc.py +0 -0
  181. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/options_pb2.py +0 -0
  182. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/options_pb2.pyi +0 -0
  183. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/options_pb2_grpc.py +0 -0
  184. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/options_pb2_grpc.pyi +0 -0
  185. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_proto/py.typed +0 -0
  186. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/modal_version/__main__.py +0 -0
  187. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/pyproject.toml +0 -0
  188. {modal-1.0.6.dev54 → modal-1.0.6.dev56}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.6.dev54
3
+ Version: 1.0.6.dev56
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -334,7 +334,7 @@ class _Invocation:
334
334
  items_total: Union[int, None] = None
335
335
  async with aclosing(
336
336
  async_merge(
337
- _stream_function_call_data(self.client, self.function_call_id, variant="data_out"),
337
+ _stream_function_call_data(self.client, None, self.function_call_id, variant="data_out"),
338
338
  callable_to_agen(self.run_function),
339
339
  )
340
340
  ) as streamer:
@@ -836,7 +836,12 @@ def _concurrent(
836
836
 
837
837
 
838
838
  # NOTE: clustered is currently exposed through modal.experimental, not the top-level namespace
839
- def _clustered(size: int, broadcast: bool = True, rdma: bool = False):
839
+ def _clustered(
840
+ size: int, broadcast: bool = True, rdma: bool = False
841
+ ) -> Callable[
842
+ [Union[Callable[P, ReturnType], _PartialFunction[P, ReturnType, ReturnType]]],
843
+ _PartialFunction[P, ReturnType, ReturnType],
844
+ ]:
840
845
  """Provision clusters of colocated and networked containers for the Function.
841
846
 
842
847
  Parameters:
@@ -486,7 +486,11 @@ class _ContainerIOManager:
486
486
 
487
487
  async def get_data_in(self, function_call_id: str) -> AsyncIterator[Any]:
488
488
  """Read from the `data_in` stream of a function call."""
489
- async for data in _stream_function_call_data(self._client, function_call_id, "data_in"):
489
+ stub = self._client.stub
490
+ if self.input_plane_server_url:
491
+ stub = await self._client.get_stub(self.input_plane_server_url)
492
+
493
+ async for data in _stream_function_call_data(self._client, stub, function_call_id, "data_in"):
490
494
  yield data
491
495
 
492
496
  async def put_data_out(
@@ -386,9 +386,12 @@ def callable_has_non_self_non_default_params(f: Callable[..., Any]) -> bool:
386
386
 
387
387
 
388
388
  async def _stream_function_call_data(
389
- client, function_call_id: str, variant: Literal["data_in", "data_out"]
389
+ client, stub, function_call_id: str, variant: Literal["data_in", "data_out"]
390
390
  ) -> AsyncGenerator[Any, None]:
391
391
  """Read from the `data_in` or `data_out` stream of a function call."""
392
+ if stub is None:
393
+ stub = client.stub
394
+
392
395
  last_index = 0
393
396
 
394
397
  # TODO(gongy): generalize this logic as util for unary streams
@@ -396,9 +399,9 @@ async def _stream_function_call_data(
396
399
  delay_ms = 1
397
400
 
398
401
  if variant == "data_in":
399
- stub_fn = client.stub.FunctionCallGetDataIn
402
+ stub_fn = stub.FunctionCallGetDataIn
400
403
  elif variant == "data_out":
401
- stub_fn = client.stub.FunctionCallGetDataOut
404
+ stub_fn = stub.FunctionCallGetDataOut
402
405
  else:
403
406
  raise ValueError(f"Invalid variant {variant}")
404
407
 
@@ -930,13 +930,24 @@ class _App:
930
930
  else:
931
931
  max_concurrent_inputs = allow_concurrent_inputs
932
932
  target_concurrent_inputs = None
933
+
934
+ if wrapped_cls.flags & _PartialFunctionFlags.CLUSTERED:
935
+ cluster_size = wrapped_cls.params.cluster_size
936
+ else:
937
+ cluster_size = None
933
938
  else:
934
939
  user_cls = wrapped_cls
935
940
  max_concurrent_inputs = allow_concurrent_inputs
936
941
  target_concurrent_inputs = None
942
+ cluster_size = None
937
943
  if not inspect.isclass(user_cls):
938
944
  raise TypeError("The @app.cls decorator must be used on a class.")
939
945
 
946
+ interface_methods = _find_partial_methods_for_user_cls(user_cls, _PartialFunctionFlags.interface_flags())
947
+ if cluster_size:
948
+ if len(interface_methods) > 1:
949
+ raise InvalidError(f"Modal class {user_cls.__name__} cannot have multiple methods when clustered.")
950
+
940
951
  batch_functions = _find_partial_methods_for_user_cls(user_cls, _PartialFunctionFlags.BATCHED)
941
952
  if batch_functions:
942
953
  if len(batch_functions) > 1:
@@ -966,6 +977,8 @@ class _App:
966
977
 
967
978
  info = FunctionInfo(None, serialized=serialized, user_cls=user_cls)
968
979
 
980
+ i6pn_enabled = i6pn or cluster_size is not None
981
+
969
982
  cls_func = _Function.from_local(
970
983
  info,
971
984
  app=self,
@@ -994,7 +1007,8 @@ class _App:
994
1007
  restrict_modal_access=restrict_modal_access,
995
1008
  max_inputs=max_inputs,
996
1009
  scheduler_placement=scheduler_placement,
997
- i6pn_enabled=i6pn or False,
1010
+ i6pn_enabled=i6pn_enabled,
1011
+ cluster_size=cluster_size,
998
1012
  include_source=include_source if include_source is not None else self._include_source_default,
999
1013
  experimental_options={k: str(v) for k, v in (experimental_options or {}).items()},
1000
1014
  _experimental_proxy_ip=_experimental_proxy_ip,
@@ -33,7 +33,7 @@ class _Client:
33
33
  server_url: str,
34
34
  client_type: int,
35
35
  credentials: typing.Optional[tuple[str, str]],
36
- version: str = "1.0.6.dev54",
36
+ version: str = "1.0.6.dev56",
37
37
  ):
38
38
  """mdmd:hidden
39
39
  The Modal client object is not intended to be instantiated directly by users.
@@ -163,7 +163,7 @@ class Client:
163
163
  server_url: str,
164
164
  client_type: int,
165
165
  credentials: typing.Optional[tuple[str, str]],
166
- version: str = "1.0.6.dev54",
166
+ version: str = "1.0.6.dev56",
167
167
  ):
168
168
  """mdmd:hidden
169
169
  The Modal client object is not intended to be instantiated directly by users.
@@ -428,7 +428,7 @@ class Function(
428
428
 
429
429
  _call_generator: ___call_generator_spec[typing_extensions.Self]
430
430
 
431
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
431
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
432
432
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
433
433
  """Calls the function remotely, executing it with the given arguments and returning the execution's result."""
434
434
  ...
@@ -437,7 +437,7 @@ class Function(
437
437
  """Calls the function remotely, executing it with the given arguments and returning the execution's result."""
438
438
  ...
439
439
 
440
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
440
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
441
441
 
442
442
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
443
443
  def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
@@ -464,7 +464,7 @@ class Function(
464
464
  """
465
465
  ...
466
466
 
467
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
467
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
468
468
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
469
469
  """[Experimental] Calls the function with the given arguments, without waiting for the results.
470
470
 
@@ -488,7 +488,7 @@ class Function(
488
488
  ...
489
489
 
490
490
  _experimental_spawn: ___experimental_spawn_spec[
491
- modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
491
+ modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
492
492
  ]
493
493
 
494
494
  class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER, SUPERSELF]):
@@ -497,7 +497,7 @@ class Function(
497
497
 
498
498
  _spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P, typing_extensions.Self]
499
499
 
500
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
500
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
501
501
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
502
502
  """Calls the function with the given arguments, without waiting for the results.
503
503
 
@@ -518,7 +518,7 @@ class Function(
518
518
  """
519
519
  ...
520
520
 
521
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
521
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
522
522
 
523
523
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
524
524
  """Return the inner Python object wrapped by this Modal Function."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.6.dev54
3
+ Version: 1.0.6.dev56
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2025
2
2
  """Supplies the current version of the modal client library."""
3
3
 
4
- __version__ = "1.0.6.dev54"
4
+ __version__ = "1.0.6.dev56"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes