modal 1.5.2.dev18__tar.gz → 1.5.2.dev19__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 (231) hide show
  1. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/PKG-INFO +1 -1
  2. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/grpc_utils.py +20 -12
  3. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/name_utils.py +8 -2
  4. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/task_command_router_client.py +2 -2
  5. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/app.py +0 -3
  6. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/app.pyi +0 -2
  7. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/client.pyi +2 -2
  8. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/functions.pyi +6 -6
  9. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal.egg-info/PKG-INFO +1 -1
  10. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/api_pb2.py +106 -119
  11. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/api_pb2.pyi +1 -21
  12. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_version/__init__.py +1 -1
  13. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/LICENSE +0 -0
  14. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/README.md +0 -0
  15. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/__init__.py +0 -0
  16. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/__main__.py +0 -0
  17. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_billing.py +0 -0
  18. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_clustered_functions.py +0 -0
  19. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_clustered_functions.pyi +0 -0
  20. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_container_entrypoint.py +0 -0
  21. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_environments.py +0 -0
  22. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_function_variants.py +0 -0
  23. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_functions.py +0 -0
  24. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_grpc_client.py +0 -0
  25. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_image.py +0 -0
  26. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_ipython.py +0 -0
  27. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_load_context.py +0 -0
  28. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_location.py +0 -0
  29. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_logs.py +0 -0
  30. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_object.py +0 -0
  31. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_output/__init__.py +0 -0
  32. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_output/manager.py +0 -0
  33. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_output/pty.py +0 -0
  34. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_output/rich.py +0 -0
  35. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_output/status.py +0 -0
  36. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_partial_function.py +0 -0
  37. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_resolver.py +0 -0
  38. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_resources.py +0 -0
  39. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/__init__.py +0 -0
  40. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/asgi.py +0 -0
  41. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/container_io_manager.py +0 -0
  42. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/container_io_manager.pyi +0 -0
  43. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/execution_context.py +0 -0
  44. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/execution_context.pyi +0 -0
  45. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  46. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/task_lifecycle_manager.py +0 -0
  47. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
  48. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/telemetry.py +0 -0
  49. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/user_code_event_loop.py +0 -0
  50. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/user_code_imports.py +0 -0
  51. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_serialization.py +0 -0
  52. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_server.py +0 -0
  53. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_traceback.py +0 -0
  54. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_tunnel.py +0 -0
  55. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_tunnel.pyi +0 -0
  56. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_type_manager.py +0 -0
  57. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/__init__.py +0 -0
  58. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/app_utils.py +0 -0
  59. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/async_utils.py +0 -0
  60. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/auth_token_manager.py +0 -0
  61. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/blob_utils.py +0 -0
  62. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/browser_utils.py +0 -0
  63. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/bytes_io_segment_payload.py +0 -0
  64. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/curl_utils.py +0 -0
  65. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/deprecation.py +0 -0
  66. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/docker_utils.py +0 -0
  67. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/function_utils.py +0 -0
  68. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/git_utils.py +0 -0
  69. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/grpc_testing.py +0 -0
  70. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/hash_utils.py +0 -0
  71. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/http_utils.py +0 -0
  72. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/jwt_utils.py +0 -0
  73. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/logger.py +0 -0
  74. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/mount_utils.py +0 -0
  75. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/package_utils.py +0 -0
  76. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/pattern_utils.py +0 -0
  77. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/proxy_support.py +0 -0
  78. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/rand_pb_testing.py +0 -0
  79. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/sandbox_fs_utils.py +0 -0
  80. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/shell_utils.py +0 -0
  81. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/time_utils.py +0 -0
  82. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_vendor/__init__.py +0 -0
  83. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  84. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_vendor/cloudpickle.py +0 -0
  85. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_vendor/tblib.py +0 -0
  86. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_vendor/version.py +0 -0
  87. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_watcher.py +0 -0
  88. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_workspace.py +0 -0
  89. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/billing.py +0 -0
  90. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/billing.pyi +0 -0
  91. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/2023.12.312.txt +0 -0
  92. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/2023.12.txt +0 -0
  93. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/2024.04.txt +0 -0
  94. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/2024.10.txt +0 -0
  95. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/2025.06.txt +0 -0
  96. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/PREVIEW.txt +0 -0
  97. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/README.md +0 -0
  98. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/base-images.json +0 -0
  99. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/call_graph.py +0 -0
  100. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/__init__.py +0 -0
  101. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/_download.py +0 -0
  102. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/_help.py +0 -0
  103. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/_traceback.py +0 -0
  104. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/app.py +0 -0
  105. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/billing.py +0 -0
  106. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/bootstrap.py +0 -0
  107. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/changelog.py +0 -0
  108. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/cluster.py +0 -0
  109. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/config.py +0 -0
  110. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/container.py +0 -0
  111. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/curl.py +0 -0
  112. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/dashboard.py +0 -0
  113. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/dict.py +0 -0
  114. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/endpoint.py +0 -0
  115. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/entry_point.py +0 -0
  116. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/environment.py +0 -0
  117. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/image.py +0 -0
  118. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/import_refs.py +0 -0
  119. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/launch.py +0 -0
  120. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/logo.py +0 -0
  121. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/network_file_system.py +0 -0
  122. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/profile.py +0 -0
  123. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/programs/__init__.py +0 -0
  124. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/programs/run_jupyter.py +0 -0
  125. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/programs/vscode.py +0 -0
  126. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/queues.py +0 -0
  127. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/run.py +0 -0
  128. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/secret.py +0 -0
  129. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/selector.py +0 -0
  130. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/shell.py +0 -0
  131. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/skills.py +0 -0
  132. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/token.py +0 -0
  133. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/utils.py +0 -0
  134. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/volume.py +0 -0
  135. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/workspace.py +0 -0
  136. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/client.py +0 -0
  137. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cloud_bucket_mount.py +0 -0
  138. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cloud_bucket_mount.pyi +0 -0
  139. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cls.py +0 -0
  140. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cls.pyi +0 -0
  141. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/config.py +0 -0
  142. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/container_process.py +0 -0
  143. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/container_process.pyi +0 -0
  144. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/dict.py +0 -0
  145. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/dict.pyi +0 -0
  146. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/environments.py +0 -0
  147. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/environments.pyi +0 -0
  148. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/exception.py +0 -0
  149. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/experimental/__init__.py +0 -0
  150. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/experimental/flash.py +0 -0
  151. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/experimental/flash.pyi +0 -0
  152. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/experimental/ipython.py +0 -0
  153. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/file_io.py +0 -0
  154. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/file_io.pyi +0 -0
  155. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/file_pattern_matcher.py +0 -0
  156. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/functions.py +0 -0
  157. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/image.py +0 -0
  158. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/image.pyi +0 -0
  159. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/io_streams.py +0 -0
  160. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/io_streams.pyi +0 -0
  161. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/mount.py +0 -0
  162. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/mount.pyi +0 -0
  163. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/network_file_system.py +0 -0
  164. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/network_file_system.pyi +0 -0
  165. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/object.py +0 -0
  166. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/object.pyi +0 -0
  167. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/output.py +0 -0
  168. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/parallel_map.py +0 -0
  169. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/parallel_map.pyi +0 -0
  170. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/partial_function.py +0 -0
  171. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/partial_function.pyi +0 -0
  172. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/proxy.py +0 -0
  173. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/proxy.pyi +0 -0
  174. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/py.typed +0 -0
  175. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/queue.py +0 -0
  176. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/queue.pyi +0 -0
  177. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/retries.py +0 -0
  178. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/runner.py +0 -0
  179. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/runner.pyi +0 -0
  180. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/running_app.py +0 -0
  181. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/sandbox.py +0 -0
  182. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/sandbox.pyi +0 -0
  183. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/sandbox_fs.py +0 -0
  184. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/sandbox_fs.pyi +0 -0
  185. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/schedule.py +0 -0
  186. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/scheduler_placement.py +0 -0
  187. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/secret.py +0 -0
  188. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/secret.pyi +0 -0
  189. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/server.py +0 -0
  190. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/server.pyi +0 -0
  191. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/serving.py +0 -0
  192. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/serving.pyi +0 -0
  193. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/skills/modal/SKILL.md +0 -0
  194. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/snapshot.py +0 -0
  195. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/snapshot.pyi +0 -0
  196. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/stream_type.py +0 -0
  197. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/token_flow.py +0 -0
  198. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/token_flow.pyi +0 -0
  199. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/types.py +0 -0
  200. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/volume.py +0 -0
  201. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/volume.pyi +0 -0
  202. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/workspace.py +0 -0
  203. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/workspace.pyi +0 -0
  204. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal.egg-info/SOURCES.txt +0 -0
  205. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal.egg-info/dependency_links.txt +0 -0
  206. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal.egg-info/entry_points.txt +0 -0
  207. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal.egg-info/requires.txt +0 -0
  208. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal.egg-info/top_level.txt +0 -0
  209. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/__init__.py +0 -0
  210. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/gen_cli_docs.py +0 -0
  211. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/gen_cli_docs_main.py +0 -0
  212. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/gen_reference_docs.py +0 -0
  213. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/gen_reference_docs_main.py +0 -0
  214. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/mdmd/__init__.py +0 -0
  215. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/mdmd/mdmd.py +0 -0
  216. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/mdmd/signatures.py +0 -0
  217. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/mdmd/types.py +0 -0
  218. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/__init__.py +0 -0
  219. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/api_grpc.py +0 -0
  220. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/api_pb2_grpc.py +0 -0
  221. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/api_pb2_grpc.pyi +0 -0
  222. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/modal_api_grpc.py +0 -0
  223. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/py.typed +0 -0
  224. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/task_command_router_grpc.py +0 -0
  225. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/task_command_router_pb2.py +0 -0
  226. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/task_command_router_pb2.pyi +0 -0
  227. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  228. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  229. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_version/__main__.py +0 -0
  230. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/pyproject.toml +0 -0
  231. {modal-1.5.2.dev18 → modal-1.5.2.dev19}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.5.2.dev18
3
+ Version: 1.5.2.dev19
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -163,7 +163,6 @@ RETRYABLE_GRPC_STATUS_CODES = [
163
163
  Status.UNKNOWN,
164
164
  ]
165
165
  SERVER_RETRY_WARNING_TIME_INTERVAL = 30.0
166
- # Initial per-attempt timeout for TCP/TLS handshake in connect_channel.
167
166
  DEFAULT_MAX_RETRIES = 3
168
167
 
169
168
 
@@ -308,11 +307,6 @@ def create_channel(
308
307
 
309
308
  # With 18 attempts, the max delays between calls is: 0.1 + 0.2 + 0.4 + 0.8 + 1.6 + 3.2 + 5*11 ~ 62
310
309
  @retry(n_attempts=18, base_delay=0.1, attempt_timeout=10.0, max_delay=5.0, total_timeout=63.0)
311
- async def connect_channel(channel: grpclib.client.Channel):
312
- """Connect to socket and raise exceptions when there is a connection issue."""
313
- await channel.__connect__()
314
-
315
-
316
310
  async def create_channel_with_fallbacks(
317
311
  server_url: str,
318
312
  metadata: dict[str, str] = {},
@@ -323,21 +317,35 @@ async def create_channel_with_fallbacks(
323
317
  `server_url` may be a single URL or a comma-separated list of URLs. The connection attempts
324
318
  are raced against each other and the first one to connect wins, which lets the client fail
325
319
  over to a secondary endpoint when the primary is unreachable (e.g. a DNS outage on the
326
- primary's domain). Attempts are staggered: the candidate at index `i` waits `i * stagger_delay`
327
- seconds before starting, so earlier URLs (e.g. the primary) get a head start and are preferred
328
- when reachable. Losing attempts are cancelled and their channels closed.
320
+ primary's domain).
321
+
322
+ Attempts are staggered so earlier URLs (e.g. the primary) get a head start and are preferred
323
+ when reachable: the candidate at index `i` waits up to `i * stagger_delay` seconds before
324
+ starting. That wait is cut short as soon as the previous candidate *fails*, so a fast failure
325
+ falls over to the next URL immediately instead of waiting out the full stagger. Losing attempts
326
+ are cancelled and their channels closed.
329
327
  """
330
328
  urls = [url.strip() for url in server_url.split(",")]
331
329
 
330
+ # Set when a candidate's connection attempt fails, letting the next candidate start immediately
331
+ # instead of waiting out its stagger delay.
332
+ failed = [asyncio.Event() for _ in urls]
333
+
332
334
  async def connect(index: int, url: str) -> grpclib.client.Channel:
333
- # Stagger the start so earlier URLs are preferred; once started, all attempts race.
334
- await asyncio.sleep(index * stagger_delay)
335
+ if index > 0:
336
+ # Stagger the start so earlier URLs are preferred, but start early if the previous
337
+ # candidate has already failed.
338
+ try:
339
+ await asyncio.wait_for(failed[index - 1].wait(), timeout=index * stagger_delay)
340
+ except asyncio.TimeoutError:
341
+ pass
335
342
  channel = create_channel(url, metadata)
336
343
  try:
337
- await connect_channel(channel)
344
+ await channel.__connect__()
338
345
  except BaseException:
339
346
  # Close the channel of a losing/cancelled attempt so its socket doesn't leak.
340
347
  channel.close()
348
+ failed[index].set()
341
349
  raise
342
350
  return channel
343
351
 
@@ -29,7 +29,13 @@ def is_valid_object_name(name: str) -> bool:
29
29
 
30
30
  def is_valid_environment_name(name: str) -> bool:
31
31
  # first char is alnum, the rest allows other chars
32
- return len(name) <= 64 and re.match(r"^[a-zA-Z0-9][a-zA-Z0-9-_.]+$", name) is not None
32
+ # The "en-" prefix is reserved for environment IDs, so that references
33
+ # to environments can be resolved by either name or ID unambiguously.
34
+ return (
35
+ len(name) <= 64
36
+ and re.match(r"^[a-zA-Z0-9][a-zA-Z0-9-_.]+$", name) is not None
37
+ and not name.lower().startswith("en-")
38
+ )
33
39
 
34
40
 
35
41
  def is_valid_tag(tag: str, max_length: int = 50) -> bool:
@@ -66,7 +72,7 @@ def check_environment_name(name: str) -> None:
66
72
  f"Invalid Environment name: '{name}'."
67
73
  "\n\nEnvironment names can only start with alphanumeric characters,"
68
74
  " may contain only alphanumeric characters, dashes, periods, and underscores,"
69
- " and must be shorter than 64 characters."
75
+ " must be shorter than 64 characters, and cannot start with 'en-'."
70
76
  )
71
77
  if not is_valid_environment_name(name):
72
78
  raise InvalidError(message)
@@ -32,8 +32,8 @@ from .grpc_utils import RETRYABLE_GRPC_STATUS_CODES
32
32
  async def _connect_channel(channel: grpclib.client.Channel):
33
33
  """Connect to the command router channel.
34
34
 
35
- Uses a longer retry budget than grpc_utils.connect_channel. In rare cases the sandbox
36
- may take a long time to start on the worker after scheduling.
35
+ Uses a longer retry budget than grpc_utils.create_channel_with_fallbacks. In rare cases the
36
+ sandbox may take a long time to start on the worker after scheduling.
37
37
 
38
38
  Retries with exponential backoff (1, 2, 4, 8, 10, 10, ...) capped at 10s per delay.
39
39
  Total sleep between attempts: 1 + 2 + 4 + 8 + 10*29 = 305s (~5 min).
@@ -1266,9 +1266,6 @@ class _App:
1266
1266
 
1267
1267
  return wrapper
1268
1268
 
1269
- def _experimental_server(self, **kwargs):
1270
- return self.server(**kwargs)
1271
-
1272
1269
  def server(
1273
1270
  self,
1274
1271
  _warn_parentheses_missing=None, # mdmd:line-hidden
@@ -728,7 +728,6 @@ class _App:
728
728
  """
729
729
  ...
730
730
 
731
- def _experimental_server(self, **kwargs): ...
732
731
  def server(
733
732
  self,
734
733
  _warn_parentheses_missing=None,
@@ -1733,7 +1732,6 @@ class App:
1733
1732
  """
1734
1733
  ...
1735
1734
 
1736
- def _experimental_server(self, **kwargs): ...
1737
1735
  def server(
1738
1736
  self,
1739
1737
  _warn_parentheses_missing=None,
@@ -35,7 +35,7 @@ class _Client:
35
35
  server_url: str,
36
36
  client_type: int,
37
37
  credentials: typing.Optional[tuple[str, str]],
38
- version: str = "1.5.2.dev18",
38
+ version: str = "1.5.2.dev19",
39
39
  ):
40
40
  """mdmd:hidden
41
41
  The Modal client object is not intended to be instantiated directly by users.
@@ -205,7 +205,7 @@ class Client:
205
205
  server_url: str,
206
206
  client_type: int,
207
207
  credentials: typing.Optional[tuple[str, str]],
208
- version: str = "1.5.2.dev18",
208
+ version: str = "1.5.2.dev19",
209
209
  ):
210
210
  """mdmd:hidden
211
211
  The Modal client object is not intended to be instantiated directly by users.
@@ -491,7 +491,7 @@ class Function(
491
491
 
492
492
  _call_generator: ___call_generator_spec
493
493
 
494
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
494
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
495
495
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
496
496
  """Calls the function remotely, executing it with the given arguments and returning the execution's result.
497
497
 
@@ -516,7 +516,7 @@ class Function(
516
516
  """
517
517
  ...
518
518
 
519
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P]
519
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType]
520
520
 
521
521
  class __remote_gen_spec(typing_extensions.Protocol):
522
522
  def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
@@ -566,7 +566,7 @@ class Function(
566
566
  """
567
567
  ...
568
568
 
569
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
569
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
570
570
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
571
571
  """[Experimental] Calls the function with the given arguments, without waiting for the results.
572
572
 
@@ -599,7 +599,7 @@ class Function(
599
599
  """
600
600
  ...
601
601
 
602
- _experimental_spawn: ___experimental_spawn_spec[modal._functions.ReturnType, modal._functions.P]
602
+ _experimental_spawn: ___experimental_spawn_spec[modal._functions.P, modal._functions.ReturnType]
603
603
 
604
604
  class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
605
605
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
@@ -607,7 +607,7 @@ class Function(
607
607
 
608
608
  _spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
609
609
 
610
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
610
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
611
611
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
612
612
  """Calls the function with the given arguments, without waiting for the results.
613
613
 
@@ -640,7 +640,7 @@ class Function(
640
640
  """
641
641
  ...
642
642
 
643
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P]
643
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType]
644
644
 
645
645
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
646
646
  """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.5.2.dev18
3
+ Version: 1.5.2.dev19
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0