modal 1.2.0__tar.gz → 1.2.1__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 (200) hide show
  1. {modal-1.2.0 → modal-1.2.1}/PKG-INFO +5 -5
  2. {modal-1.2.0 → modal-1.2.1}/README.md +4 -4
  3. {modal-1.2.0 → modal-1.2.1}/modal/_container_entrypoint.py +4 -1
  4. {modal-1.2.0 → modal-1.2.1}/modal/_partial_function.py +28 -3
  5. {modal-1.2.0 → modal-1.2.1}/modal/_utils/function_utils.py +4 -0
  6. modal-1.2.1/modal/_utils/task_command_router_client.py +537 -0
  7. {modal-1.2.0 → modal-1.2.1}/modal/app.py +93 -54
  8. {modal-1.2.0 → modal-1.2.1}/modal/app.pyi +48 -18
  9. {modal-1.2.0 → modal-1.2.1}/modal/cli/_download.py +19 -3
  10. {modal-1.2.0 → modal-1.2.1}/modal/cli/cluster.py +4 -2
  11. {modal-1.2.0 → modal-1.2.1}/modal/cli/container.py +4 -2
  12. {modal-1.2.0 → modal-1.2.1}/modal/cli/entry_point.py +1 -0
  13. {modal-1.2.0 → modal-1.2.1}/modal/cli/launch.py +1 -2
  14. {modal-1.2.0 → modal-1.2.1}/modal/cli/run.py +6 -0
  15. {modal-1.2.0 → modal-1.2.1}/modal/cli/volume.py +7 -1
  16. {modal-1.2.0 → modal-1.2.1}/modal/client.pyi +2 -2
  17. {modal-1.2.0 → modal-1.2.1}/modal/cls.py +5 -12
  18. {modal-1.2.0 → modal-1.2.1}/modal/config.py +14 -0
  19. modal-1.2.1/modal/container_process.py +476 -0
  20. {modal-1.2.0 → modal-1.2.1}/modal/container_process.pyi +95 -32
  21. {modal-1.2.0 → modal-1.2.1}/modal/exception.py +4 -0
  22. {modal-1.2.0 → modal-1.2.1}/modal/experimental/flash.py +21 -47
  23. {modal-1.2.0 → modal-1.2.1}/modal/experimental/flash.pyi +6 -20
  24. {modal-1.2.0 → modal-1.2.1}/modal/functions.pyi +6 -6
  25. modal-1.2.1/modal/io_streams.py +804 -0
  26. {modal-1.2.0 → modal-1.2.1}/modal/io_streams.pyi +220 -95
  27. {modal-1.2.0 → modal-1.2.1}/modal/partial_function.pyi +4 -1
  28. {modal-1.2.0 → modal-1.2.1}/modal/runner.py +39 -36
  29. {modal-1.2.0 → modal-1.2.1}/modal/runner.pyi +40 -24
  30. {modal-1.2.0 → modal-1.2.1}/modal/sandbox.py +130 -11
  31. {modal-1.2.0 → modal-1.2.1}/modal/sandbox.pyi +145 -9
  32. {modal-1.2.0 → modal-1.2.1}/modal/volume.py +23 -3
  33. {modal-1.2.0 → modal-1.2.1}/modal/volume.pyi +30 -0
  34. {modal-1.2.0 → modal-1.2.1}/modal.egg-info/PKG-INFO +5 -5
  35. {modal-1.2.0 → modal-1.2.1}/modal.egg-info/SOURCES.txt +1 -0
  36. {modal-1.2.0 → modal-1.2.1}/modal_proto/api.proto +2 -26
  37. {modal-1.2.0 → modal-1.2.1}/modal_proto/api_grpc.py +0 -32
  38. {modal-1.2.0 → modal-1.2.1}/modal_proto/api_pb2.py +327 -367
  39. {modal-1.2.0 → modal-1.2.1}/modal_proto/api_pb2.pyi +6 -69
  40. {modal-1.2.0 → modal-1.2.1}/modal_proto/api_pb2_grpc.py +0 -67
  41. {modal-1.2.0 → modal-1.2.1}/modal_proto/api_pb2_grpc.pyi +0 -22
  42. {modal-1.2.0 → modal-1.2.1}/modal_proto/modal_api_grpc.py +0 -2
  43. {modal-1.2.0 → modal-1.2.1}/modal_proto/sandbox_router.proto +0 -4
  44. {modal-1.2.0 → modal-1.2.1}/modal_proto/sandbox_router_pb2.pyi +0 -4
  45. {modal-1.2.0 → modal-1.2.1}/modal_proto/task_command_router.proto +1 -1
  46. {modal-1.2.0 → modal-1.2.1}/modal_proto/task_command_router_pb2.py +2 -2
  47. {modal-1.2.0 → modal-1.2.1}/modal_version/__init__.py +1 -1
  48. modal-1.2.0/modal/container_process.py +0 -196
  49. modal-1.2.0/modal/io_streams.py +0 -471
  50. {modal-1.2.0 → modal-1.2.1}/LICENSE +0 -0
  51. {modal-1.2.0 → modal-1.2.1}/modal/__init__.py +0 -0
  52. {modal-1.2.0 → modal-1.2.1}/modal/__main__.py +0 -0
  53. {modal-1.2.0 → modal-1.2.1}/modal/_billing.py +0 -0
  54. {modal-1.2.0 → modal-1.2.1}/modal/_clustered_functions.py +0 -0
  55. {modal-1.2.0 → modal-1.2.1}/modal/_clustered_functions.pyi +0 -0
  56. {modal-1.2.0 → modal-1.2.1}/modal/_functions.py +0 -0
  57. {modal-1.2.0 → modal-1.2.1}/modal/_ipython.py +0 -0
  58. {modal-1.2.0 → modal-1.2.1}/modal/_location.py +0 -0
  59. {modal-1.2.0 → modal-1.2.1}/modal/_object.py +0 -0
  60. {modal-1.2.0 → modal-1.2.1}/modal/_output.py +0 -0
  61. {modal-1.2.0 → modal-1.2.1}/modal/_pty.py +0 -0
  62. {modal-1.2.0 → modal-1.2.1}/modal/_resolver.py +0 -0
  63. {modal-1.2.0 → modal-1.2.1}/modal/_resources.py +0 -0
  64. {modal-1.2.0 → modal-1.2.1}/modal/_runtime/__init__.py +0 -0
  65. {modal-1.2.0 → modal-1.2.1}/modal/_runtime/asgi.py +0 -0
  66. {modal-1.2.0 → modal-1.2.1}/modal/_runtime/container_io_manager.py +0 -0
  67. {modal-1.2.0 → modal-1.2.1}/modal/_runtime/container_io_manager.pyi +0 -0
  68. {modal-1.2.0 → modal-1.2.1}/modal/_runtime/execution_context.py +0 -0
  69. {modal-1.2.0 → modal-1.2.1}/modal/_runtime/execution_context.pyi +0 -0
  70. {modal-1.2.0 → modal-1.2.1}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  71. {modal-1.2.0 → modal-1.2.1}/modal/_runtime/telemetry.py +0 -0
  72. {modal-1.2.0 → modal-1.2.1}/modal/_runtime/user_code_imports.py +0 -0
  73. {modal-1.2.0 → modal-1.2.1}/modal/_serialization.py +0 -0
  74. {modal-1.2.0 → modal-1.2.1}/modal/_traceback.py +0 -0
  75. {modal-1.2.0 → modal-1.2.1}/modal/_tunnel.py +0 -0
  76. {modal-1.2.0 → modal-1.2.1}/modal/_tunnel.pyi +0 -0
  77. {modal-1.2.0 → modal-1.2.1}/modal/_type_manager.py +0 -0
  78. {modal-1.2.0 → modal-1.2.1}/modal/_utils/__init__.py +0 -0
  79. {modal-1.2.0 → modal-1.2.1}/modal/_utils/app_utils.py +0 -0
  80. {modal-1.2.0 → modal-1.2.1}/modal/_utils/async_utils.py +0 -0
  81. {modal-1.2.0 → modal-1.2.1}/modal/_utils/auth_token_manager.py +0 -0
  82. {modal-1.2.0 → modal-1.2.1}/modal/_utils/blob_utils.py +0 -0
  83. {modal-1.2.0 → modal-1.2.1}/modal/_utils/bytes_io_segment_payload.py +0 -0
  84. {modal-1.2.0 → modal-1.2.1}/modal/_utils/deprecation.py +0 -0
  85. {modal-1.2.0 → modal-1.2.1}/modal/_utils/docker_utils.py +0 -0
  86. {modal-1.2.0 → modal-1.2.1}/modal/_utils/git_utils.py +0 -0
  87. {modal-1.2.0 → modal-1.2.1}/modal/_utils/grpc_testing.py +0 -0
  88. {modal-1.2.0 → modal-1.2.1}/modal/_utils/grpc_utils.py +0 -0
  89. {modal-1.2.0 → modal-1.2.1}/modal/_utils/hash_utils.py +0 -0
  90. {modal-1.2.0 → modal-1.2.1}/modal/_utils/http_utils.py +0 -0
  91. {modal-1.2.0 → modal-1.2.1}/modal/_utils/jwt_utils.py +0 -0
  92. {modal-1.2.0 → modal-1.2.1}/modal/_utils/logger.py +0 -0
  93. {modal-1.2.0 → modal-1.2.1}/modal/_utils/mount_utils.py +0 -0
  94. {modal-1.2.0 → modal-1.2.1}/modal/_utils/name_utils.py +0 -0
  95. {modal-1.2.0 → modal-1.2.1}/modal/_utils/package_utils.py +0 -0
  96. {modal-1.2.0 → modal-1.2.1}/modal/_utils/pattern_utils.py +0 -0
  97. {modal-1.2.0 → modal-1.2.1}/modal/_utils/rand_pb_testing.py +0 -0
  98. {modal-1.2.0 → modal-1.2.1}/modal/_utils/shell_utils.py +0 -0
  99. {modal-1.2.0 → modal-1.2.1}/modal/_utils/time_utils.py +0 -0
  100. {modal-1.2.0 → modal-1.2.1}/modal/_vendor/__init__.py +0 -0
  101. {modal-1.2.0 → modal-1.2.1}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  102. {modal-1.2.0 → modal-1.2.1}/modal/_vendor/cloudpickle.py +0 -0
  103. {modal-1.2.0 → modal-1.2.1}/modal/_vendor/tblib.py +0 -0
  104. {modal-1.2.0 → modal-1.2.1}/modal/_watcher.py +0 -0
  105. {modal-1.2.0 → modal-1.2.1}/modal/billing.py +0 -0
  106. {modal-1.2.0 → modal-1.2.1}/modal/builder/2023.12.312.txt +0 -0
  107. {modal-1.2.0 → modal-1.2.1}/modal/builder/2023.12.txt +0 -0
  108. {modal-1.2.0 → modal-1.2.1}/modal/builder/2024.04.txt +0 -0
  109. {modal-1.2.0 → modal-1.2.1}/modal/builder/2024.10.txt +0 -0
  110. {modal-1.2.0 → modal-1.2.1}/modal/builder/2025.06.txt +0 -0
  111. {modal-1.2.0 → modal-1.2.1}/modal/builder/PREVIEW.txt +0 -0
  112. {modal-1.2.0 → modal-1.2.1}/modal/builder/README.md +0 -0
  113. {modal-1.2.0 → modal-1.2.1}/modal/builder/base-images.json +0 -0
  114. {modal-1.2.0 → modal-1.2.1}/modal/call_graph.py +0 -0
  115. {modal-1.2.0 → modal-1.2.1}/modal/cli/__init__.py +0 -0
  116. {modal-1.2.0 → modal-1.2.1}/modal/cli/_traceback.py +0 -0
  117. {modal-1.2.0 → modal-1.2.1}/modal/cli/app.py +0 -0
  118. {modal-1.2.0 → modal-1.2.1}/modal/cli/config.py +0 -0
  119. {modal-1.2.0 → modal-1.2.1}/modal/cli/dict.py +0 -0
  120. {modal-1.2.0 → modal-1.2.1}/modal/cli/environment.py +0 -0
  121. {modal-1.2.0 → modal-1.2.1}/modal/cli/import_refs.py +0 -0
  122. {modal-1.2.0 → modal-1.2.1}/modal/cli/network_file_system.py +0 -0
  123. {modal-1.2.0 → modal-1.2.1}/modal/cli/profile.py +0 -0
  124. {modal-1.2.0 → modal-1.2.1}/modal/cli/programs/__init__.py +0 -0
  125. {modal-1.2.0 → modal-1.2.1}/modal/cli/programs/launch_instance_ssh.py +0 -0
  126. {modal-1.2.0 → modal-1.2.1}/modal/cli/programs/run_jupyter.py +0 -0
  127. {modal-1.2.0 → modal-1.2.1}/modal/cli/programs/run_marimo.py +0 -0
  128. {modal-1.2.0 → modal-1.2.1}/modal/cli/programs/vscode.py +0 -0
  129. {modal-1.2.0 → modal-1.2.1}/modal/cli/queues.py +0 -0
  130. {modal-1.2.0 → modal-1.2.1}/modal/cli/secret.py +0 -0
  131. {modal-1.2.0 → modal-1.2.1}/modal/cli/token.py +0 -0
  132. {modal-1.2.0 → modal-1.2.1}/modal/cli/utils.py +0 -0
  133. {modal-1.2.0 → modal-1.2.1}/modal/client.py +0 -0
  134. {modal-1.2.0 → modal-1.2.1}/modal/cloud_bucket_mount.py +0 -0
  135. {modal-1.2.0 → modal-1.2.1}/modal/cloud_bucket_mount.pyi +0 -0
  136. {modal-1.2.0 → modal-1.2.1}/modal/cls.pyi +0 -0
  137. {modal-1.2.0 → modal-1.2.1}/modal/dict.py +0 -0
  138. {modal-1.2.0 → modal-1.2.1}/modal/dict.pyi +0 -0
  139. {modal-1.2.0 → modal-1.2.1}/modal/environments.py +0 -0
  140. {modal-1.2.0 → modal-1.2.1}/modal/environments.pyi +0 -0
  141. {modal-1.2.0 → modal-1.2.1}/modal/experimental/__init__.py +0 -0
  142. {modal-1.2.0 → modal-1.2.1}/modal/experimental/ipython.py +0 -0
  143. {modal-1.2.0 → modal-1.2.1}/modal/file_io.py +0 -0
  144. {modal-1.2.0 → modal-1.2.1}/modal/file_io.pyi +0 -0
  145. {modal-1.2.0 → modal-1.2.1}/modal/file_pattern_matcher.py +0 -0
  146. {modal-1.2.0 → modal-1.2.1}/modal/functions.py +0 -0
  147. {modal-1.2.0 → modal-1.2.1}/modal/gpu.py +0 -0
  148. {modal-1.2.0 → modal-1.2.1}/modal/image.py +0 -0
  149. {modal-1.2.0 → modal-1.2.1}/modal/image.pyi +0 -0
  150. {modal-1.2.0 → modal-1.2.1}/modal/mount.py +0 -0
  151. {modal-1.2.0 → modal-1.2.1}/modal/mount.pyi +0 -0
  152. {modal-1.2.0 → modal-1.2.1}/modal/network_file_system.py +0 -0
  153. {modal-1.2.0 → modal-1.2.1}/modal/network_file_system.pyi +0 -0
  154. {modal-1.2.0 → modal-1.2.1}/modal/object.py +0 -0
  155. {modal-1.2.0 → modal-1.2.1}/modal/object.pyi +0 -0
  156. {modal-1.2.0 → modal-1.2.1}/modal/output.py +0 -0
  157. {modal-1.2.0 → modal-1.2.1}/modal/parallel_map.py +0 -0
  158. {modal-1.2.0 → modal-1.2.1}/modal/parallel_map.pyi +0 -0
  159. {modal-1.2.0 → modal-1.2.1}/modal/partial_function.py +0 -0
  160. {modal-1.2.0 → modal-1.2.1}/modal/proxy.py +0 -0
  161. {modal-1.2.0 → modal-1.2.1}/modal/proxy.pyi +0 -0
  162. {modal-1.2.0 → modal-1.2.1}/modal/py.typed +0 -0
  163. {modal-1.2.0 → modal-1.2.1}/modal/queue.py +0 -0
  164. {modal-1.2.0 → modal-1.2.1}/modal/queue.pyi +0 -0
  165. {modal-1.2.0 → modal-1.2.1}/modal/retries.py +0 -0
  166. {modal-1.2.0 → modal-1.2.1}/modal/running_app.py +0 -0
  167. {modal-1.2.0 → modal-1.2.1}/modal/schedule.py +0 -0
  168. {modal-1.2.0 → modal-1.2.1}/modal/scheduler_placement.py +0 -0
  169. {modal-1.2.0 → modal-1.2.1}/modal/secret.py +0 -0
  170. {modal-1.2.0 → modal-1.2.1}/modal/secret.pyi +0 -0
  171. {modal-1.2.0 → modal-1.2.1}/modal/serving.py +0 -0
  172. {modal-1.2.0 → modal-1.2.1}/modal/serving.pyi +0 -0
  173. {modal-1.2.0 → modal-1.2.1}/modal/snapshot.py +0 -0
  174. {modal-1.2.0 → modal-1.2.1}/modal/snapshot.pyi +0 -0
  175. {modal-1.2.0 → modal-1.2.1}/modal/stream_type.py +0 -0
  176. {modal-1.2.0 → modal-1.2.1}/modal/token_flow.py +0 -0
  177. {modal-1.2.0 → modal-1.2.1}/modal/token_flow.pyi +0 -0
  178. {modal-1.2.0 → modal-1.2.1}/modal.egg-info/dependency_links.txt +0 -0
  179. {modal-1.2.0 → modal-1.2.1}/modal.egg-info/entry_points.txt +0 -0
  180. {modal-1.2.0 → modal-1.2.1}/modal.egg-info/requires.txt +0 -0
  181. {modal-1.2.0 → modal-1.2.1}/modal.egg-info/top_level.txt +0 -0
  182. {modal-1.2.0 → modal-1.2.1}/modal_docs/__init__.py +0 -0
  183. {modal-1.2.0 → modal-1.2.1}/modal_docs/gen_cli_docs.py +0 -0
  184. {modal-1.2.0 → modal-1.2.1}/modal_docs/gen_reference_docs.py +0 -0
  185. {modal-1.2.0 → modal-1.2.1}/modal_docs/mdmd/__init__.py +0 -0
  186. {modal-1.2.0 → modal-1.2.1}/modal_docs/mdmd/mdmd.py +0 -0
  187. {modal-1.2.0 → modal-1.2.1}/modal_docs/mdmd/signatures.py +0 -0
  188. {modal-1.2.0 → modal-1.2.1}/modal_proto/__init__.py +0 -0
  189. {modal-1.2.0 → modal-1.2.1}/modal_proto/py.typed +0 -0
  190. {modal-1.2.0 → modal-1.2.1}/modal_proto/sandbox_router_grpc.py +0 -0
  191. {modal-1.2.0 → modal-1.2.1}/modal_proto/sandbox_router_pb2.py +0 -0
  192. {modal-1.2.0 → modal-1.2.1}/modal_proto/sandbox_router_pb2_grpc.py +0 -0
  193. {modal-1.2.0 → modal-1.2.1}/modal_proto/sandbox_router_pb2_grpc.pyi +0 -0
  194. {modal-1.2.0 → modal-1.2.1}/modal_proto/task_command_router_grpc.py +0 -0
  195. {modal-1.2.0 → modal-1.2.1}/modal_proto/task_command_router_pb2.pyi +0 -0
  196. {modal-1.2.0 → modal-1.2.1}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  197. {modal-1.2.0 → modal-1.2.1}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  198. {modal-1.2.0 → modal-1.2.1}/modal_version/__main__.py +0 -0
  199. {modal-1.2.0 → modal-1.2.1}/pyproject.toml +0 -0
  200. {modal-1.2.0 → modal-1.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -32,14 +32,14 @@ Requires-Dist: watchfiles
32
32
  Requires-Dist: typing_extensions~=4.6
33
33
  Dynamic: license-file
34
34
 
35
- # Modal Python Library
35
+ # Modal Python SDK
36
36
 
37
37
  [![PyPI Version](https://img.shields.io/pypi/v/modal.svg)](https://pypi.org/project/modal/)
38
38
  [![License](https://img.shields.io/badge/license-apache_2.0-darkviolet.svg)](https://github.com/modal-labs/modal-client/blob/master/LICENSE)
39
39
  [![Tests](https://github.com/modal-labs/modal-client/actions/workflows/ci-cd.yml/badge.svg)](https://github.com/modal-labs/modal-client/actions/workflows/ci-cd.yml)
40
40
  [![Slack](https://img.shields.io/badge/slack-join-blue.svg?logo=slack)](https://modal.com/slack)
41
41
 
42
- The [Modal](https://modal.com/) Python library provides convenient, on-demand
42
+ The [Modal](https://modal.com/) Python SDK provides convenient, on-demand
43
43
  access to serverless cloud compute from Python scripts on your local computer.
44
44
 
45
45
  ## Documentation
@@ -53,10 +53,10 @@ a [user guide](https://modal.com/docs/guide), and the detailed
53
53
 
54
54
  **This library requires Python 3.9 – 3.13.**
55
55
 
56
- Install the package with `pip`:
56
+ Install the package with `uv` or `pip`:
57
57
 
58
58
  ```bash
59
- pip install modal
59
+ uv pip install modal
60
60
  ```
61
61
 
62
62
  You can create a Modal account (or link your existing one) directly on the
@@ -1,11 +1,11 @@
1
- # Modal Python Library
1
+ # Modal Python SDK
2
2
 
3
3
  [![PyPI Version](https://img.shields.io/pypi/v/modal.svg)](https://pypi.org/project/modal/)
4
4
  [![License](https://img.shields.io/badge/license-apache_2.0-darkviolet.svg)](https://github.com/modal-labs/modal-client/blob/master/LICENSE)
5
5
  [![Tests](https://github.com/modal-labs/modal-client/actions/workflows/ci-cd.yml/badge.svg)](https://github.com/modal-labs/modal-client/actions/workflows/ci-cd.yml)
6
6
  [![Slack](https://img.shields.io/badge/slack-join-blue.svg?logo=slack)](https://modal.com/slack)
7
7
 
8
- The [Modal](https://modal.com/) Python library provides convenient, on-demand
8
+ The [Modal](https://modal.com/) Python SDK provides convenient, on-demand
9
9
  access to serverless cloud compute from Python scripts on your local computer.
10
10
 
11
11
  ## Documentation
@@ -19,10 +19,10 @@ a [user guide](https://modal.com/docs/guide), and the detailed
19
19
 
20
20
  **This library requires Python 3.9 – 3.13.**
21
21
 
22
- Install the package with `pip`:
22
+ Install the package with `uv` or `pip`:
23
23
 
24
24
  ```bash
25
- pip install modal
25
+ uv pip install modal
26
26
  ```
27
27
 
28
28
  You can create a Modal account (or link your existing one) directly on the
@@ -450,7 +450,10 @@ def main(container_args: api_pb2.ContainerArguments, client: Client):
450
450
  f"Function has {len(service.service_deps)} dependencies"
451
451
  f" but container got {len(dep_object_ids)} object ids.\n"
452
452
  f"Code deps: {service.service_deps}\n"
453
- f"Object ids: {dep_object_ids}"
453
+ f"Object ids: {dep_object_ids}\n"
454
+ "\n"
455
+ "This can happen if you are defining Modal objects under a conditional statement "
456
+ "that evaluates differently in the local and remote environments."
454
457
  )
455
458
  for object_id, obj in zip(dep_object_ids, service.service_deps):
456
459
  metadata: Message = container_app.object_handle_metadata[object_id]
@@ -19,7 +19,7 @@ from ._functions import _Function
19
19
  from ._utils.async_utils import synchronizer
20
20
  from ._utils.deprecation import deprecation_warning
21
21
  from ._utils.function_utils import callable_has_non_self_params
22
- from .config import logger
22
+ from .config import config, logger
23
23
  from .exception import InvalidError
24
24
 
25
25
  MAX_MAX_BATCH_SIZE = 1000
@@ -93,6 +93,26 @@ NullaryFuncOrMethod = Union[Callable[[], Any], Callable[[Any], Any]]
93
93
  NullaryMethod = Callable[[Any], Any]
94
94
 
95
95
 
96
+ def verify_concurrent_params(params: _PartialFunctionParams, is_flash: bool = False) -> None:
97
+ def _verify_concurrent_params_with_flash_settings(params: _PartialFunctionParams) -> None:
98
+ if params.max_concurrent_inputs is not None:
99
+ raise TypeError(
100
+ "@modal.concurrent(max_inputs=...) is not yet supported for Flash functions. "
101
+ "Use `@modal.concurrent(target_inputs=...)` instead."
102
+ )
103
+ if params.target_concurrent_inputs is None:
104
+ raise TypeError("`@modal.concurrent()` missing required argument: `target_inputs`.")
105
+
106
+ def _verify_concurrent_params(params: _PartialFunctionParams) -> None:
107
+ if params.max_concurrent_inputs is None:
108
+ raise TypeError("`@modal.concurrent()` missing required argument: `max_inputs`.")
109
+
110
+ if is_flash:
111
+ _verify_concurrent_params_with_flash_settings(params)
112
+ else:
113
+ _verify_concurrent_params(params)
114
+
115
+
96
116
  class _PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
97
117
  """Object produced by a decorator in the `modal` namespace
98
118
 
@@ -378,6 +398,7 @@ def _fastapi_endpoint(
378
398
  method=method,
379
399
  web_endpoint_docs=docs,
380
400
  requested_suffix=label or "",
401
+ ephemeral_suffix=config.get("dev_suffix"),
381
402
  async_mode=api_pb2.WEBHOOK_ASYNC_MODE_AUTO,
382
403
  custom_domains=_parse_custom_domains(custom_domains),
383
404
  requires_proxy_auth=requires_proxy_auth,
@@ -446,6 +467,7 @@ def _web_endpoint(
446
467
  method=method,
447
468
  web_endpoint_docs=docs,
448
469
  requested_suffix=label or "",
470
+ ephemeral_suffix=config.get("dev_suffix"),
449
471
  async_mode=api_pb2.WEBHOOK_ASYNC_MODE_AUTO,
450
472
  custom_domains=_parse_custom_domains(custom_domains),
451
473
  requires_proxy_auth=requires_proxy_auth,
@@ -505,6 +527,7 @@ def _asgi_app(
505
527
  webhook_config = api_pb2.WebhookConfig(
506
528
  type=api_pb2.WEBHOOK_TYPE_ASGI_APP,
507
529
  requested_suffix=label or "",
530
+ ephemeral_suffix=config.get("dev_suffix"),
508
531
  async_mode=api_pb2.WEBHOOK_ASYNC_MODE_AUTO,
509
532
  custom_domains=_parse_custom_domains(custom_domains),
510
533
  requires_proxy_auth=requires_proxy_auth,
@@ -562,6 +585,7 @@ def _wsgi_app(
562
585
  webhook_config = api_pb2.WebhookConfig(
563
586
  type=api_pb2.WEBHOOK_TYPE_WSGI_APP,
564
587
  requested_suffix=label or "",
588
+ ephemeral_suffix=config.get("dev_suffix"),
565
589
  async_mode=api_pb2.WEBHOOK_ASYNC_MODE_AUTO,
566
590
  custom_domains=_parse_custom_domains(custom_domains),
567
591
  requires_proxy_auth=requires_proxy_auth,
@@ -623,6 +647,7 @@ def _web_server(
623
647
  webhook_config = api_pb2.WebhookConfig(
624
648
  type=api_pb2.WEBHOOK_TYPE_WEB_SERVER,
625
649
  requested_suffix=label or "",
650
+ ephemeral_suffix=config.get("dev_suffix"),
626
651
  async_mode=api_pb2.WEBHOOK_ASYNC_MODE_AUTO,
627
652
  custom_domains=_parse_custom_domains(custom_domains),
628
653
  web_server_port=port,
@@ -760,7 +785,7 @@ def _batched(
760
785
  def _concurrent(
761
786
  _warn_parentheses_missing=None, # mdmd:line-hidden
762
787
  *,
763
- max_inputs: int, # Hard limit on each container's input concurrency
788
+ max_inputs: Optional[int] = None, # Hard limit on each container's input concurrency
764
789
  target_inputs: Optional[int] = None, # Input concurrency that Modal's autoscaler should target
765
790
  ) -> Callable[
766
791
  [Union[Callable[P, ReturnType], _PartialFunction[P, ReturnType, ReturnType]]],
@@ -812,7 +837,7 @@ def _concurrent(
812
837
  "Positional arguments are not allowed. Did you forget parentheses? Suggestion: `@modal.concurrent()`."
813
838
  )
814
839
 
815
- if target_inputs and target_inputs > max_inputs:
840
+ if max_inputs is not None and target_inputs is not None and target_inputs > max_inputs:
816
841
  raise InvalidError("`target_inputs` parameter cannot be greater than `max_inputs`.")
817
842
 
818
843
  flags = _PartialFunctionFlags.CONCURRENT
@@ -75,6 +75,10 @@ def is_global_object(object_qual_name: str):
75
75
  return "<locals>" not in object_qual_name.split(".")
76
76
 
77
77
 
78
+ def is_flash_object(experimental_options: Optional[dict[str, Any]]) -> bool:
79
+ return experimental_options.get("flash", False) if experimental_options else False
80
+
81
+
78
82
  def is_method_fn(object_qual_name: str):
79
83
  # methods have names like Cls.foo.
80
84
  if "<locals>" in object_qual_name: