modal 1.5.2.dev17__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.dev17 → modal-1.5.2.dev19}/PKG-INFO +1 -1
  2. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/grpc_utils.py +20 -12
  3. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/name_utils.py +8 -2
  4. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/task_command_router_client.py +2 -2
  5. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/app.py +0 -3
  6. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/app.pyi +0 -2
  7. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/client.pyi +2 -2
  8. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal.egg-info/PKG-INFO +1 -1
  9. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/api_grpc.py +16 -0
  10. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/api_pb2.py +106 -119
  11. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/api_pb2.pyi +1 -21
  12. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/api_pb2_grpc.py +33 -0
  13. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/api_pb2_grpc.pyi +10 -0
  14. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/modal_api_grpc.py +1 -0
  15. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_version/__init__.py +1 -1
  16. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/LICENSE +0 -0
  17. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/README.md +0 -0
  18. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/__init__.py +0 -0
  19. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/__main__.py +0 -0
  20. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_billing.py +0 -0
  21. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_clustered_functions.py +0 -0
  22. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_clustered_functions.pyi +0 -0
  23. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_container_entrypoint.py +0 -0
  24. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_environments.py +0 -0
  25. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_function_variants.py +0 -0
  26. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_functions.py +0 -0
  27. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_grpc_client.py +0 -0
  28. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_image.py +0 -0
  29. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_ipython.py +0 -0
  30. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_load_context.py +0 -0
  31. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_location.py +0 -0
  32. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_logs.py +0 -0
  33. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_object.py +0 -0
  34. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_output/__init__.py +0 -0
  35. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_output/manager.py +0 -0
  36. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_output/pty.py +0 -0
  37. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_output/rich.py +0 -0
  38. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_output/status.py +0 -0
  39. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_partial_function.py +0 -0
  40. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_resolver.py +0 -0
  41. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_resources.py +0 -0
  42. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_runtime/__init__.py +0 -0
  43. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_runtime/asgi.py +0 -0
  44. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_runtime/container_io_manager.py +0 -0
  45. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_runtime/container_io_manager.pyi +0 -0
  46. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_runtime/execution_context.py +0 -0
  47. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_runtime/execution_context.pyi +0 -0
  48. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  49. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_runtime/task_lifecycle_manager.py +0 -0
  50. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
  51. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_runtime/telemetry.py +0 -0
  52. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_runtime/user_code_event_loop.py +0 -0
  53. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_runtime/user_code_imports.py +0 -0
  54. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_serialization.py +0 -0
  55. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_server.py +0 -0
  56. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_traceback.py +0 -0
  57. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_tunnel.py +0 -0
  58. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_tunnel.pyi +0 -0
  59. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_type_manager.py +0 -0
  60. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/__init__.py +0 -0
  61. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/app_utils.py +0 -0
  62. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/async_utils.py +0 -0
  63. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/auth_token_manager.py +0 -0
  64. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/blob_utils.py +0 -0
  65. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/browser_utils.py +0 -0
  66. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/bytes_io_segment_payload.py +0 -0
  67. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/curl_utils.py +0 -0
  68. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/deprecation.py +0 -0
  69. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/docker_utils.py +0 -0
  70. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/function_utils.py +0 -0
  71. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/git_utils.py +0 -0
  72. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/grpc_testing.py +0 -0
  73. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/hash_utils.py +0 -0
  74. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/http_utils.py +0 -0
  75. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/jwt_utils.py +0 -0
  76. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/logger.py +0 -0
  77. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/mount_utils.py +0 -0
  78. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/package_utils.py +0 -0
  79. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/pattern_utils.py +0 -0
  80. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/proxy_support.py +0 -0
  81. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/rand_pb_testing.py +0 -0
  82. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/sandbox_fs_utils.py +0 -0
  83. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/shell_utils.py +0 -0
  84. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_utils/time_utils.py +0 -0
  85. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_vendor/__init__.py +0 -0
  86. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  87. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_vendor/cloudpickle.py +0 -0
  88. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_vendor/tblib.py +0 -0
  89. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_vendor/version.py +0 -0
  90. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_watcher.py +0 -0
  91. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/_workspace.py +0 -0
  92. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/billing.py +0 -0
  93. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/billing.pyi +0 -0
  94. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/builder/2023.12.312.txt +0 -0
  95. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/builder/2023.12.txt +0 -0
  96. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/builder/2024.04.txt +0 -0
  97. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/builder/2024.10.txt +0 -0
  98. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/builder/2025.06.txt +0 -0
  99. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/builder/PREVIEW.txt +0 -0
  100. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/builder/README.md +0 -0
  101. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/builder/base-images.json +0 -0
  102. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/call_graph.py +0 -0
  103. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/__init__.py +0 -0
  104. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/_download.py +0 -0
  105. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/_help.py +0 -0
  106. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/_traceback.py +0 -0
  107. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/app.py +0 -0
  108. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/billing.py +0 -0
  109. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/bootstrap.py +0 -0
  110. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/changelog.py +0 -0
  111. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/cluster.py +0 -0
  112. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/config.py +0 -0
  113. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/container.py +0 -0
  114. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/curl.py +0 -0
  115. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/dashboard.py +0 -0
  116. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/dict.py +0 -0
  117. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/endpoint.py +0 -0
  118. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/entry_point.py +0 -0
  119. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/environment.py +0 -0
  120. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/image.py +0 -0
  121. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/import_refs.py +0 -0
  122. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/launch.py +0 -0
  123. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/logo.py +0 -0
  124. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/network_file_system.py +0 -0
  125. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/profile.py +0 -0
  126. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/programs/__init__.py +0 -0
  127. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/programs/run_jupyter.py +0 -0
  128. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/programs/vscode.py +0 -0
  129. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/queues.py +0 -0
  130. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/run.py +0 -0
  131. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/secret.py +0 -0
  132. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/selector.py +0 -0
  133. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/shell.py +0 -0
  134. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/skills.py +0 -0
  135. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/token.py +0 -0
  136. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/utils.py +0 -0
  137. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/volume.py +0 -0
  138. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cli/workspace.py +0 -0
  139. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/client.py +0 -0
  140. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cloud_bucket_mount.py +0 -0
  141. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cloud_bucket_mount.pyi +0 -0
  142. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cls.py +0 -0
  143. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/cls.pyi +0 -0
  144. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/config.py +0 -0
  145. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/container_process.py +0 -0
  146. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/container_process.pyi +0 -0
  147. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/dict.py +0 -0
  148. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/dict.pyi +0 -0
  149. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/environments.py +0 -0
  150. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/environments.pyi +0 -0
  151. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/exception.py +0 -0
  152. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/experimental/__init__.py +0 -0
  153. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/experimental/flash.py +0 -0
  154. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/experimental/flash.pyi +0 -0
  155. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/experimental/ipython.py +0 -0
  156. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/file_io.py +0 -0
  157. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/file_io.pyi +0 -0
  158. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/file_pattern_matcher.py +0 -0
  159. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/functions.py +0 -0
  160. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/functions.pyi +0 -0
  161. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/image.py +0 -0
  162. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/image.pyi +0 -0
  163. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/io_streams.py +0 -0
  164. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/io_streams.pyi +0 -0
  165. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/mount.py +0 -0
  166. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/mount.pyi +0 -0
  167. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/network_file_system.py +0 -0
  168. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/network_file_system.pyi +0 -0
  169. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/object.py +0 -0
  170. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/object.pyi +0 -0
  171. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/output.py +0 -0
  172. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/parallel_map.py +0 -0
  173. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/parallel_map.pyi +0 -0
  174. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/partial_function.py +0 -0
  175. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/partial_function.pyi +0 -0
  176. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/proxy.py +0 -0
  177. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/proxy.pyi +0 -0
  178. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/py.typed +0 -0
  179. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/queue.py +0 -0
  180. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/queue.pyi +0 -0
  181. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/retries.py +0 -0
  182. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/runner.py +0 -0
  183. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/runner.pyi +0 -0
  184. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/running_app.py +0 -0
  185. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/sandbox.py +0 -0
  186. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/sandbox.pyi +0 -0
  187. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/sandbox_fs.py +0 -0
  188. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/sandbox_fs.pyi +0 -0
  189. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/schedule.py +0 -0
  190. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/scheduler_placement.py +0 -0
  191. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/secret.py +0 -0
  192. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/secret.pyi +0 -0
  193. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/server.py +0 -0
  194. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/server.pyi +0 -0
  195. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/serving.py +0 -0
  196. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/serving.pyi +0 -0
  197. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/skills/modal/SKILL.md +0 -0
  198. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/snapshot.py +0 -0
  199. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/snapshot.pyi +0 -0
  200. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/stream_type.py +0 -0
  201. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/token_flow.py +0 -0
  202. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/token_flow.pyi +0 -0
  203. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/types.py +0 -0
  204. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/volume.py +0 -0
  205. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/volume.pyi +0 -0
  206. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/workspace.py +0 -0
  207. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal/workspace.pyi +0 -0
  208. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal.egg-info/SOURCES.txt +0 -0
  209. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal.egg-info/dependency_links.txt +0 -0
  210. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal.egg-info/entry_points.txt +0 -0
  211. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal.egg-info/requires.txt +0 -0
  212. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal.egg-info/top_level.txt +0 -0
  213. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_docs/__init__.py +0 -0
  214. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_docs/gen_cli_docs.py +0 -0
  215. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_docs/gen_cli_docs_main.py +0 -0
  216. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_docs/gen_reference_docs.py +0 -0
  217. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_docs/gen_reference_docs_main.py +0 -0
  218. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_docs/mdmd/__init__.py +0 -0
  219. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_docs/mdmd/mdmd.py +0 -0
  220. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_docs/mdmd/signatures.py +0 -0
  221. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_docs/mdmd/types.py +0 -0
  222. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/__init__.py +0 -0
  223. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/py.typed +0 -0
  224. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/task_command_router_grpc.py +0 -0
  225. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/task_command_router_pb2.py +0 -0
  226. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/task_command_router_pb2.pyi +0 -0
  227. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  228. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  229. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/modal_version/__main__.py +0 -0
  230. {modal-1.5.2.dev17 → modal-1.5.2.dev19}/pyproject.toml +0 -0
  231. {modal-1.5.2.dev17 → 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.dev17
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.dev17",
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.dev17",
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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.5.2.dev17
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
@@ -583,6 +583,10 @@ class ModalClientBase(abc.ABC):
583
583
  async def SandboxGetFromName(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.SandboxGetFromNameRequest, modal_proto.api_pb2.SandboxGetFromNameResponse]') -> None:
584
584
  pass
585
585
 
586
+ @abc.abstractmethod
587
+ async def SandboxGetFromNameV2(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.SandboxGetFromNameRequest, modal_proto.api_pb2.SandboxGetFromNameResponse]') -> None:
588
+ pass
589
+
586
590
  @abc.abstractmethod
587
591
  async def SandboxGetLogs(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.SandboxGetLogsRequest, modal_proto.api_pb2.TaskLogsBatch]') -> None:
588
592
  pass
@@ -1755,6 +1759,12 @@ class ModalClientBase(abc.ABC):
1755
1759
  modal_proto.api_pb2.SandboxGetFromNameRequest,
1756
1760
  modal_proto.api_pb2.SandboxGetFromNameResponse,
1757
1761
  ),
1762
+ '/modal.client.ModalClient/SandboxGetFromNameV2': grpclib.const.Handler(
1763
+ self.SandboxGetFromNameV2,
1764
+ grpclib.const.Cardinality.UNARY_UNARY,
1765
+ modal_proto.api_pb2.SandboxGetFromNameRequest,
1766
+ modal_proto.api_pb2.SandboxGetFromNameResponse,
1767
+ ),
1758
1768
  '/modal.client.ModalClient/SandboxGetLogs': grpclib.const.Handler(
1759
1769
  self.SandboxGetLogs,
1760
1770
  grpclib.const.Cardinality.UNARY_STREAM,
@@ -3093,6 +3103,12 @@ class ModalClientStub:
3093
3103
  modal_proto.api_pb2.SandboxGetFromNameRequest,
3094
3104
  modal_proto.api_pb2.SandboxGetFromNameResponse,
3095
3105
  )
3106
+ self.SandboxGetFromNameV2 = grpclib.client.UnaryUnaryMethod(
3107
+ channel,
3108
+ '/modal.client.ModalClient/SandboxGetFromNameV2',
3109
+ modal_proto.api_pb2.SandboxGetFromNameRequest,
3110
+ modal_proto.api_pb2.SandboxGetFromNameResponse,
3111
+ )
3096
3112
  self.SandboxGetLogs = grpclib.client.UnaryStreamMethod(
3097
3113
  channel,
3098
3114
  '/modal.client.ModalClient/SandboxGetLogs',