modAL 1.3.6.dev13__tar.gz → 1.3.6.dev14__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 (210) hide show
  1. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/PKG-INFO +1 -1
  2. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_functions.py +7 -87
  3. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_partial_function.py +7 -63
  4. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_resources.py +3 -4
  5. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/deprecation.py +23 -44
  6. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/function_utils.py +17 -0
  7. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/app.py +11 -85
  8. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/app.pyi +6 -36
  9. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/entry_point.py +1 -1
  10. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/import_refs.py +2 -5
  11. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/client.pyi +2 -2
  12. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cls.py +3 -48
  13. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cls.pyi +2 -71
  14. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/dict.py +3 -21
  15. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/dict.pyi +5 -9
  16. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/experimental/__init__.py +9 -87
  17. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/functions.py +1 -2
  18. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/functions.pyi +1 -66
  19. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/image.py +37 -38
  20. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/image.pyi +26 -27
  21. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/mount.py +1 -0
  22. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/network_file_system.py +1 -5
  23. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/network_file_system.pyi +0 -5
  24. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/partial_function.pyi +2 -33
  25. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/queue.py +1 -3
  26. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/queue.pyi +0 -2
  27. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/runner.py +7 -9
  28. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/runner.pyi +8 -8
  29. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/sandbox.py +3 -23
  30. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/sandbox.pyi +8 -47
  31. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/secret.py +3 -12
  32. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/secret.pyi +0 -13
  33. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/serving.py +1 -1
  34. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/volume.py +2 -5
  35. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/volume.pyi +0 -5
  36. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal.egg-info/PKG-INFO +1 -1
  37. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal.egg-info/SOURCES.txt +0 -1
  38. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_docs/gen_reference_docs.py +0 -1
  39. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/api_grpc.py +16 -0
  40. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/api_pb2.py +494 -453
  41. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/api_pb2.pyi +101 -12
  42. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/api_pb2_grpc.py +33 -0
  43. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/api_pb2_grpc.pyi +10 -0
  44. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/modal_api_grpc.py +1 -0
  45. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_version/__init__.py +1 -1
  46. modal-1.3.6.dev13/modal/gpu.py +0 -225
  47. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/LICENSE +0 -0
  48. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/README.md +0 -0
  49. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/__init__.py +0 -0
  50. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/__main__.py +0 -0
  51. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_billing.py +0 -0
  52. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_clustered_functions.py +0 -0
  53. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_clustered_functions.pyi +0 -0
  54. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_container_entrypoint.py +0 -0
  55. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_grpc_client.py +0 -0
  56. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_ipython.py +0 -0
  57. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_load_context.py +0 -0
  58. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_location.py +0 -0
  59. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_logs.py +0 -0
  60. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_object.py +0 -0
  61. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_output/__init__.py +0 -0
  62. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_output/manager.py +0 -0
  63. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_output/pty.py +0 -0
  64. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_output/rich.py +0 -0
  65. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_output/status.py +0 -0
  66. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_resolver.py +0 -0
  67. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_runtime/__init__.py +0 -0
  68. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_runtime/asgi.py +0 -0
  69. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_runtime/container_io_manager.py +0 -0
  70. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_runtime/container_io_manager.pyi +0 -0
  71. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_runtime/execution_context.py +0 -0
  72. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_runtime/execution_context.pyi +0 -0
  73. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  74. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_runtime/telemetry.py +0 -0
  75. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_runtime/user_code_event_loop.py +0 -0
  76. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_runtime/user_code_imports.py +0 -0
  77. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_serialization.py +0 -0
  78. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_server.py +0 -0
  79. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_traceback.py +0 -0
  80. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_tunnel.py +0 -0
  81. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_tunnel.pyi +0 -0
  82. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_type_manager.py +0 -0
  83. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/__init__.py +0 -0
  84. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/app_utils.py +0 -0
  85. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/async_utils.py +0 -0
  86. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/auth_token_manager.py +0 -0
  87. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/blob_utils.py +0 -0
  88. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/browser_utils.py +0 -0
  89. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/bytes_io_segment_payload.py +0 -0
  90. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/docker_utils.py +0 -0
  91. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/git_utils.py +0 -0
  92. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/grpc_testing.py +0 -0
  93. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/grpc_utils.py +0 -0
  94. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/hash_utils.py +0 -0
  95. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/http_utils.py +0 -0
  96. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/jwt_utils.py +0 -0
  97. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/logger.py +0 -0
  98. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/mount_utils.py +0 -0
  99. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/name_utils.py +0 -0
  100. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/package_utils.py +0 -0
  101. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/pattern_utils.py +0 -0
  102. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/rand_pb_testing.py +0 -0
  103. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/sandbox_fs_utils.py +0 -0
  104. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/shell_utils.py +0 -0
  105. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/task_command_router_client.py +0 -0
  106. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_utils/time_utils.py +0 -0
  107. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_vendor/__init__.py +0 -0
  108. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  109. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_vendor/cloudpickle.py +0 -0
  110. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_vendor/tblib.py +0 -0
  111. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_vendor/version.py +0 -0
  112. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/_watcher.py +0 -0
  113. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/billing.py +0 -0
  114. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/builder/2023.12.312.txt +0 -0
  115. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/builder/2023.12.txt +0 -0
  116. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/builder/2024.04.txt +0 -0
  117. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/builder/2024.10.txt +0 -0
  118. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/builder/2025.06.txt +0 -0
  119. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/builder/PREVIEW.txt +0 -0
  120. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/builder/README.md +0 -0
  121. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/builder/base-images.json +0 -0
  122. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/call_graph.py +0 -0
  123. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/__init__.py +0 -0
  124. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/_download.py +0 -0
  125. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/_traceback.py +0 -0
  126. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/app.py +0 -0
  127. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/billing.py +0 -0
  128. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/changelog.py +0 -0
  129. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/cluster.py +0 -0
  130. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/config.py +0 -0
  131. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/container.py +0 -0
  132. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/dashboard.py +0 -0
  133. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/dict.py +0 -0
  134. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/environment.py +0 -0
  135. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/launch.py +0 -0
  136. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/network_file_system.py +0 -0
  137. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/profile.py +0 -0
  138. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/programs/__init__.py +0 -0
  139. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/programs/run_jupyter.py +0 -0
  140. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/programs/vscode.py +0 -0
  141. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/queues.py +0 -0
  142. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/run.py +0 -0
  143. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/secret.py +0 -0
  144. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/selector.py +0 -0
  145. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/shell.py +0 -0
  146. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/token.py +0 -0
  147. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/utils.py +0 -0
  148. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cli/volume.py +0 -0
  149. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/client.py +0 -0
  150. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cloud_bucket_mount.py +0 -0
  151. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/cloud_bucket_mount.pyi +0 -0
  152. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/config.py +0 -0
  153. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/container_process.py +0 -0
  154. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/container_process.pyi +0 -0
  155. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/environments.py +0 -0
  156. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/environments.pyi +0 -0
  157. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/exception.py +0 -0
  158. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/experimental/flash.py +0 -0
  159. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/experimental/flash.pyi +0 -0
  160. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/experimental/ipython.py +0 -0
  161. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/file_io.py +0 -0
  162. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/file_io.pyi +0 -0
  163. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/file_pattern_matcher.py +0 -0
  164. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/io_streams.py +0 -0
  165. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/io_streams.pyi +0 -0
  166. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/mount.pyi +0 -0
  167. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/object.py +0 -0
  168. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/object.pyi +0 -0
  169. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/output.py +0 -0
  170. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/parallel_map.py +0 -0
  171. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/parallel_map.pyi +0 -0
  172. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/partial_function.py +0 -0
  173. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/proxy.py +0 -0
  174. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/proxy.pyi +0 -0
  175. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/py.typed +0 -0
  176. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/retries.py +0 -0
  177. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/running_app.py +0 -0
  178. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/sandbox_fs.py +0 -0
  179. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/sandbox_fs.pyi +0 -0
  180. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/schedule.py +0 -0
  181. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/scheduler_placement.py +0 -0
  182. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/server.py +0 -0
  183. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/server.pyi +0 -0
  184. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/serving.pyi +0 -0
  185. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/snapshot.py +0 -0
  186. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/snapshot.pyi +0 -0
  187. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/stream_type.py +0 -0
  188. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/token_flow.py +0 -0
  189. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal/token_flow.pyi +0 -0
  190. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal.egg-info/dependency_links.txt +0 -0
  191. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal.egg-info/entry_points.txt +0 -0
  192. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal.egg-info/requires.txt +0 -0
  193. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal.egg-info/top_level.txt +0 -0
  194. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_docs/__init__.py +0 -0
  195. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_docs/gen_cli_docs.py +0 -0
  196. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_docs/gen_cli_docs_main.py +0 -0
  197. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_docs/gen_reference_docs_main.py +0 -0
  198. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_docs/mdmd/__init__.py +0 -0
  199. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_docs/mdmd/mdmd.py +0 -0
  200. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_docs/mdmd/signatures.py +0 -0
  201. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/__init__.py +0 -0
  202. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/py.typed +0 -0
  203. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/task_command_router_grpc.py +0 -0
  204. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/task_command_router_pb2.py +0 -0
  205. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/task_command_router_pb2.pyi +0 -0
  206. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  207. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  208. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/modal_version/__main__.py +0 -0
  209. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/pyproject.toml +0 -0
  210. {modal-1.3.6.dev13 → modal-1.3.6.dev14}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.3.6.dev13
3
+ Version: 1.3.6.dev14
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -2,7 +2,6 @@
2
2
  import asyncio
3
3
  import dataclasses
4
4
  import inspect
5
- import textwrap
6
5
  import time
7
6
  import typing
8
7
  import warnings
@@ -44,7 +43,6 @@ from ._utils.async_utils import (
44
43
  warn_if_generator_is_not_consumed,
45
44
  )
46
45
  from ._utils.blob_utils import MAX_OBJECT_SIZE_BYTES
47
- from ._utils.deprecation import deprecation_warning, warn_if_passing_namespace
48
46
  from ._utils.function_utils import (
49
47
  ATTEMPT_TIMEOUT_GRACE_PERIOD,
50
48
  OUTPUTS_TIMEOUT,
@@ -54,6 +52,7 @@ from ._utils.function_utils import (
54
52
  _stream_function_call_data,
55
53
  get_function_type,
56
54
  is_async,
55
+ parse_gpu_config,
57
56
  )
58
57
  from ._utils.grpc_utils import Retry, RetryWarningMessage
59
58
  from ._utils.mount_utils import validate_network_file_systems, validate_volumes, validate_volumes_by_object_id
@@ -67,7 +66,6 @@ from .exception import (
67
66
  NotFoundError,
68
67
  OutputExpiredError,
69
68
  )
70
- from .gpu import GPU_T, parse_gpu_config
71
69
  from .image import _Image
72
70
  from .mount import _get_client_mount, _Mount
73
71
  from .network_file_system import _NetworkFileSystem, network_file_system_mount_protos
@@ -587,7 +585,7 @@ class _FunctionSpec:
587
585
  network_file_systems: dict[Union[str, PurePosixPath], _NetworkFileSystem]
588
586
  volumes: dict[Union[str, PurePosixPath], Union[_Volume, _CloudBucketMount]]
589
587
  # TODO(irfansharif): Somehow assert that it's the first kind, in sandboxes
590
- gpus: Union[GPU_T, list[GPU_T]]
588
+ gpus: Optional[str | list[str]]
591
589
  cloud: Optional[str]
592
590
  cpu: Optional[Union[float, tuple[float, float]]]
593
591
  memory: Optional[Union[int, tuple[int, int]]]
@@ -666,7 +664,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
666
664
  secrets: Optional[Collection[_Secret]] = None,
667
665
  schedule: Optional[Schedule] = None,
668
666
  is_generator: bool = False,
669
- gpu: Union[GPU_T, list[GPU_T]] = None,
667
+ gpu: Optional[str | list[str]] = None,
670
668
  # TODO: maybe break this out into a separate decorator for notebooks.
671
669
  network_file_systems: dict[Union[str, PurePosixPath], _NetworkFileSystem] = {},
672
670
  volumes: dict[Union[str, PurePosixPath], Union[_Volume, _CloudBucketMount]] = {},
@@ -703,7 +701,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
703
701
  include_source: bool = True,
704
702
  experimental_options: Optional[dict[str, str]] = None,
705
703
  _experimental_proxy_ip: Optional[str] = None,
706
- _experimental_custom_scaling_factor: Optional[float] = None,
707
704
  restrict_output: bool = False,
708
705
  http_config: Optional[api_pb2.HTTPConfig] = None,
709
706
  ) -> "_Function":
@@ -799,11 +796,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
799
796
  f"for clustered Functions"
800
797
  )
801
798
 
802
- if _experimental_custom_scaling_factor is not None and (
803
- _experimental_custom_scaling_factor < 0 or _experimental_custom_scaling_factor > 1
804
- ):
805
- raise InvalidError("`_experimental_custom_scaling_factor` must be between 0.0 and 1.0 inclusive.")
806
-
807
799
  if not cloud and not is_builder_function:
808
800
  cloud = config.get("default_cloud")
809
801
 
@@ -1050,7 +1042,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1050
1042
  _experimental_group_size=cluster_size or 0, # Experimental: Clustered functions
1051
1043
  _experimental_concurrent_cancellations=True,
1052
1044
  _experimental_proxy_ip=_experimental_proxy_ip,
1053
- _experimental_custom_scaling=_experimental_custom_scaling_factor is not None,
1054
1045
  # --- These are deprecated in favor of autoscaler_settings
1055
1046
  warm_pool_size=min_containers or 0,
1056
1047
  concurrency_limit=max_containers or 0,
@@ -1122,8 +1113,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1122
1113
  function_data.ranked_functions.extend(ranked_functions)
1123
1114
  function_definition = None # function_definition is not used in this case
1124
1115
  else:
1125
- # TODO(irfansharif): Assert on this specific type once we get rid of python 3.9.
1126
- # assert isinstance(gpu, GPU_T) # includes the case where gpu==None case
1127
1116
  function_definition.resources.CopyFrom(
1128
1117
  convert_fn_config_to_resources_config(
1129
1118
  cpu=cpu, memory=memory, gpu=gpu, ephemeral_disk=ephemeral_disk, rdma=rdma
@@ -1170,7 +1159,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1170
1159
  obj._webhook_config = webhook_config # only set locally
1171
1160
 
1172
1161
  # Used to check whether we should rebuild a modal.Image which uses `run_function`.
1173
- gpus: list[GPU_T] = gpu if isinstance(gpu, list) else [gpu]
1162
+ gpus: list[str] = gpu if isinstance(gpu, list) else [gpu] if gpu else []
1174
1163
  obj._build_args = dict( # See get_build_def
1175
1164
  secrets=repr(secrets),
1176
1165
  gpu_config=repr([parse_gpu_config(_gpu) for _gpu in gpus]),
@@ -1358,43 +1347,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1358
1347
  # One idea would be for FunctionUpdateScheduleParams to return the current (coalesced) settings
1359
1348
  # and then we could return them here (would need some ad hoc dataclass, which I don't love)
1360
1349
 
1361
- @live_method
1362
- async def keep_warm(self, warm_pool_size: int) -> None:
1363
- """mdmd:hidden
1364
- Set the warm pool size for the Function.
1365
-
1366
- DEPRECATED: Please adapt your code to use the more general `update_autoscaler` method instead:
1367
-
1368
- ```python notest
1369
- f = modal.Function.from_name("my-app", "function")
1370
-
1371
- # Old pattern (deprecated)
1372
- f.keep_warm(2)
1373
-
1374
- # New pattern
1375
- f.update_autoscaler(min_containers=2)
1376
- ```
1377
- """
1378
- if self._is_method:
1379
- raise InvalidError(
1380
- textwrap.dedent(
1381
- """
1382
- The `.keep_warm()` method can not be used on Modal class *methods*.
1383
-
1384
- Call `.keep_warm()` on the class *instance* instead. All methods of a class are run by the same
1385
- container pool, and this method applies to the size of that container pool.
1386
- """
1387
- )
1388
- )
1389
-
1390
- deprecation_warning(
1391
- (2025, 5, 5),
1392
- "The .keep_warm() method has been deprecated in favor of the more general "
1393
- ".update_autoscaler(min_containers=...) method.",
1394
- show_source=True,
1395
- )
1396
- await self.update_autoscaler(min_containers=warm_pool_size)
1397
-
1398
1350
  @classmethod
1399
1351
  def _from_name(
1400
1352
  cls,
@@ -1444,7 +1396,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1444
1396
  app_name: str,
1445
1397
  name: str,
1446
1398
  *,
1447
- namespace=None, # mdmd:line-hidden
1448
1399
  environment_name: Optional[str] = None,
1449
1400
  client: Optional[_Client] = None,
1450
1401
  ) -> "_Function":
@@ -1459,17 +1410,11 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1459
1410
  ```
1460
1411
  """
1461
1412
  if "." in name:
1462
- class_name, method_name = name.split(".", 1)
1463
- deprecation_warning(
1464
- (2025, 2, 11),
1465
- "Looking up class methods using Function.from_name will be deprecated"
1466
- " in a future version of Modal.\nUse modal.Cls.from_name instead, e.g.\n\n"
1467
- f'{class_name} = modal.Cls.from_name("{app_name}", "{class_name}")\n'
1468
- f"instance = {class_name}(...)\n"
1469
- f"instance.{method_name}.remote(...)\n",
1413
+ raise InvalidError(
1414
+ f"Invalid Function name: {name!r}. "
1415
+ "If you are trying to look up a class method, use `modal.Cls.from_name` instead."
1470
1416
  )
1471
1417
 
1472
- warn_if_passing_namespace(namespace, "modal.Function.from_name")
1473
1418
  return cls._from_name(
1474
1419
  app_name, name, load_context_overrides=LoadContext(environment_name=environment_name, client=client)
1475
1420
  )
@@ -1587,21 +1532,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1587
1532
  + f"or call it locally: {self._function_name}.local()"
1588
1533
  )
1589
1534
 
1590
- # TODO (live_method on properties is not great, since it could be blocking the event loop from async contexts)
1591
- @property
1592
- @live_method
1593
- async def web_url(self) -> Optional[str]:
1594
- """mdmd:hidden
1595
- Deprecated. Use the `Function.get_web_url()` method instead.
1596
-
1597
- URL of a Function running as a web endpoint.
1598
- """
1599
- deprecation_msg = """The Function.web_url property will be removed in a future version of Modal.
1600
- Use the `Function.get_web_url()` method instead.
1601
- """
1602
- deprecation_warning((2025, 5, 6), deprecation_msg, pending=True)
1603
- return self._web_url
1604
-
1605
1535
  @live_method
1606
1536
  async def get_web_url(self) -> Optional[str]:
1607
1537
  """URL of a Function running as a web endpoint."""
@@ -2110,13 +2040,3 @@ class _FunctionCall(typing.Generic[ReturnType], _Object, type_prefix="fc"):
2110
2040
  except Exception as exc:
2111
2041
  # TODO: kill all running function calls
2112
2042
  raise exc
2113
-
2114
-
2115
- async def _gather(*function_calls: _FunctionCall[T]) -> typing.Sequence[T]:
2116
- """mdmd:hidden
2117
- Deprecated: Please use `modal.FunctionCall.gather()` instead."""
2118
- deprecation_warning(
2119
- (2025, 2, 24),
2120
- "`modal.functions.gather()` is deprecated; please use `modal.FunctionCall.gather()` instead.",
2121
- )
2122
- return await _FunctionCall.gather(*function_calls)
@@ -17,7 +17,7 @@ from modal_proto import api_pb2
17
17
 
18
18
  from ._functions import _Function
19
19
  from ._utils.async_utils import synchronizer
20
- from ._utils.deprecation import deprecation_warning
20
+ from ._utils.deprecation import deprecation_error
21
21
  from ._utils.function_utils import callable_has_non_self_params
22
22
  from .config import config
23
23
  from .exception import InvalidError
@@ -310,7 +310,7 @@ def _method(
310
310
  def wrapper(obj: Union[Callable[..., Any], _PartialFunction]) -> _PartialFunction:
311
311
  flags = _PartialFunctionFlags.CALLABLE_INTERFACE
312
312
 
313
- nonlocal is_generator # TODO(michael): we are likely to deprecate the explicit is_generator param
313
+ nonlocal is_generator
314
314
  if is_generator is None:
315
315
  callable = obj.raw_f if isinstance(obj, _PartialFunction) else obj
316
316
  is_generator = inspect.isgeneratorfunction(callable) or inspect.isasyncgenfunction(callable)
@@ -403,72 +403,16 @@ def _fastapi_endpoint(
403
403
 
404
404
  def _web_endpoint(
405
405
  _warn_parentheses_missing=None, # mdmd:line-hidden
406
- *,
407
- method: str = "GET", # REST method for the created endpoint.
408
- label: Optional[str] = None, # Label for created endpoint. Final subdomain will be <workspace>--<label>.modal.run.
409
- docs: bool = False, # Whether to enable interactive documentation for this endpoint at /docs.
410
- custom_domains: Optional[
411
- Iterable[str]
412
- ] = None, # Create an endpoint using a custom domain fully-qualified domain name (FQDN).
413
- requires_proxy_auth: bool = False, # Require Modal-Key and Modal-Secret HTTP Headers on requests.
414
- ) -> Callable[
415
- [Union[_PartialFunction[P, ReturnType, ReturnType], Callable[P, ReturnType]]],
416
- _PartialFunction[P, ReturnType, ReturnType],
417
- ]:
418
- """Register a basic web endpoint with this application.
419
-
406
+ *args,
407
+ **kwargs,
408
+ ) -> None:
409
+ """mdmd:hidden
420
410
  DEPRECATED: This decorator has been renamed to `@modal.fastapi_endpoint`.
421
-
422
- This is the simple way to create a web endpoint on Modal. The function
423
- behaves as a [FastAPI](https://fastapi.tiangolo.com/) handler and should
424
- return a response object to the caller.
425
-
426
- Endpoints created with `@modal.web_endpoint` are meant to be simple, single
427
- request handlers and automatically have
428
- [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) enabled.
429
- For more flexibility, use `@modal.asgi_app`.
430
-
431
- To learn how to use Modal with popular web frameworks, see the
432
- [guide on web endpoints](https://modal.com/docs/guide/webhooks).
433
411
  """
434
- if isinstance(_warn_parentheses_missing, str):
435
- # Probably passing the method string as a positional argument.
436
- raise InvalidError('Positional arguments are not allowed. Suggestion: `@modal.web_endpoint(method="GET")`.')
437
- elif _warn_parentheses_missing is not None:
438
- raise InvalidError(
439
- "Positional arguments are not allowed. Did you forget parentheses? Suggestion: `@modal.web_endpoint()`."
440
- )
441
-
442
- deprecation_warning(
412
+ deprecation_error(
443
413
  (2025, 3, 5), "The `@modal.web_endpoint` decorator has been renamed to `@modal.fastapi_endpoint`."
444
414
  )
445
415
 
446
- webhook_config = api_pb2.WebhookConfig(
447
- type=api_pb2.WEBHOOK_TYPE_FUNCTION,
448
- method=method,
449
- web_endpoint_docs=docs,
450
- requested_suffix=label or "",
451
- ephemeral_suffix=config.get("dev_suffix"),
452
- async_mode=api_pb2.WEBHOOK_ASYNC_MODE_AUTO,
453
- custom_domains=_parse_custom_domains(custom_domains),
454
- requires_proxy_auth=requires_proxy_auth,
455
- )
456
-
457
- flags = _PartialFunctionFlags.WEB_INTERFACE
458
- params = _PartialFunctionParams(webhook_config=webhook_config)
459
-
460
- def wrapper(
461
- obj: Union[_PartialFunction[P, ReturnType, ReturnType], Callable[P, ReturnType]],
462
- ) -> _PartialFunction[P, ReturnType, ReturnType]:
463
- if isinstance(obj, _PartialFunction):
464
- pf = obj.stack(flags, params)
465
- else:
466
- pf = _PartialFunction(obj, flags, params)
467
- pf.validate_obj_compatibility("web_endpoint")
468
- return pf
469
-
470
- return wrapper
471
-
472
416
 
473
417
  def _asgi_app(
474
418
  _warn_parentheses_missing=None, # mdmd:line-hidden
@@ -3,19 +3,18 @@ from typing import Optional, Union
3
3
 
4
4
  from modal_proto import api_pb2
5
5
 
6
+ from ._utils.function_utils import parse_gpu_config
6
7
  from .exception import InvalidError
7
- from .gpu import GPU_T, parse_gpu_config
8
8
 
9
9
 
10
10
  def convert_fn_config_to_resources_config(
11
11
  *,
12
12
  cpu: Optional[Union[float, tuple[float, float]]],
13
13
  memory: Optional[Union[int, tuple[int, int]]],
14
- gpu: GPU_T,
14
+ gpu: Optional[str],
15
15
  ephemeral_disk: Optional[int],
16
16
  rdma: Optional[bool] = None,
17
17
  ) -> api_pb2.Resources:
18
- gpu_config = parse_gpu_config(gpu)
19
18
  if cpu and isinstance(cpu, tuple):
20
19
  if not cpu[0]:
21
20
  raise InvalidError("CPU request must be a positive number")
@@ -45,7 +44,7 @@ def convert_fn_config_to_resources_config(
45
44
  return api_pb2.Resources(
46
45
  milli_cpu=milli_cpu,
47
46
  milli_cpu_max=milli_cpu_max,
48
- gpu_config=gpu_config,
47
+ gpu_config=parse_gpu_config(gpu),
49
48
  memory_mb=memory_mb,
50
49
  memory_mb_max=memory_mb_max,
51
50
  ephemeral_disk_mb=ephemeral_disk,
@@ -89,55 +89,34 @@ def renamed_parameter(
89
89
  return decorator
90
90
 
91
91
 
92
- def warn_on_renamed_autoscaler_settings(func: Callable[P, R]) -> Callable[P, R]:
93
- name_map = {
94
- "keep_warm": "min_containers",
95
- "concurrency_limit": "max_containers",
96
- "_experimental_buffer_containers": "buffer_containers",
97
- "container_idle_timeout": "scaledown_window",
98
- }
92
+ def handle_deprecated_parameters(func: Callable[P, R]) -> Callable[P, R]:
93
+ """Meta-decorator for modal.Function decorators that errors when deprecated parameters are passed.
94
+
95
+ We use this for a select parameters that might still be suggested by LLMs.
96
+ """
99
97
 
100
98
  @functools.wraps(func)
101
99
  def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
102
- mut_kwargs: dict[str, Any] = locals()["kwargs"] # Avoid referencing kwargs directly due to bug in sigtools
103
-
104
- substitutions = []
105
- old_params_used = name_map.keys() & mut_kwargs.keys()
106
- for old_param, new_param in name_map.items():
107
- if old_param in old_params_used:
108
- new_param = name_map[old_param]
109
- mut_kwargs[new_param] = mut_kwargs.pop(old_param)
110
- substitutions.append(f"- {old_param} -> {new_param}")
111
-
112
- if substitutions:
113
- substitution_string = "\n".join(substitutions)
114
- message = (
115
- "We have renamed several parameters related to autoscaling."
116
- " Please update your code to use the following new names:"
117
- f"\n\n{substitution_string}"
118
- "\n\nSee https://modal.com/docs/guide/modal-1-0-migration for more details."
100
+ _kwargs: dict[str, Any] = locals()["kwargs"] # Avoid referencing kwargs directly due to bug in sigtools
101
+
102
+ # Basic autoscaler parameters
103
+ autoscaler_settings = {
104
+ "keep_warm": "min_containers",
105
+ "concurrency_limit": "max_containers",
106
+ "container_idle_timeout": "scaledown_window",
107
+ }
108
+
109
+ for old_name, new_name in autoscaler_settings.items():
110
+ if old_name in _kwargs:
111
+ deprecation_error((2025, 2, 24), f"The '{old_name}' parameter has been renamed to '{new_name}'.")
112
+
113
+ # Input concurrency
114
+ if "allow_concurrent_inputs" in _kwargs:
115
+ deprecation_error(
116
+ (2025, 4, 9),
117
+ "The 'allow_concurrent_inputs' parameter is deprecated. Use the '@modal.concurrent' decorator instead.",
119
118
  )
120
- deprecation_warning((2025, 2, 24), message, show_source=True)
121
119
 
122
120
  return func(*args, **kwargs)
123
121
 
124
122
  return wrapper
125
-
126
-
127
- def warn_if_passing_namespace(
128
- namespace: Any,
129
- resource_name: str,
130
- ) -> None:
131
- """Issue deprecation warning for namespace parameter if non-None value is passed.
132
-
133
- Args:
134
- namespace: The namespace parameter value (may be None or actual value)
135
- resource_name: Name of the resource type for the warning message
136
- """
137
- if namespace is not None:
138
- deprecation_warning(
139
- (2025, 6, 30),
140
- f"The `namespace` parameter for `{resource_name}` is deprecated and will be"
141
- " removed in a future release. It is no longer needed, so can be removed"
142
- " from your code.",
143
- )
@@ -602,3 +602,20 @@ async def _create_input(
602
602
  ),
603
603
  idx=idx,
604
604
  )
605
+
606
+
607
+ def parse_gpu_config(value: Optional[str]) -> api_pb2.GPUConfig:
608
+ if value is None:
609
+ return api_pb2.GPUConfig()
610
+ elif isinstance(value, str):
611
+ count = 1
612
+ if ":" in value:
613
+ value, count_str = value.split(":", 1)
614
+ try:
615
+ count = int(count_str)
616
+ except ValueError:
617
+ raise InvalidError(f"Invalid GPU count: {count_str}. Value must be an integer.")
618
+ gpu_type = value.upper()
619
+ return api_pb2.GPUConfig(gpu_type=gpu_type, count=count)
620
+ else:
621
+ raise InvalidError(f"Invalid GPU config: {value!r}. Value must be a string or `None`")