modAL 1.1.5.dev15__tar.gz → 1.1.5.dev17__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 (190) hide show
  1. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/PKG-INFO +1 -1
  2. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/blob_utils.py +4 -4
  3. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/client.pyi +2 -2
  4. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/sandbox.py +28 -1
  5. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/sandbox.pyi +63 -0
  6. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal.egg-info/PKG-INFO +1 -1
  7. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_version/__init__.py +1 -1
  8. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/LICENSE +0 -0
  9. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/README.md +0 -0
  10. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/__init__.py +0 -0
  11. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/__main__.py +0 -0
  12. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_clustered_functions.py +0 -0
  13. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_clustered_functions.pyi +0 -0
  14. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_container_entrypoint.py +0 -0
  15. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_functions.py +0 -0
  16. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_ipython.py +0 -0
  17. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_location.py +0 -0
  18. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_object.py +0 -0
  19. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_output.py +0 -0
  20. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_partial_function.py +0 -0
  21. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_pty.py +0 -0
  22. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_resolver.py +0 -0
  23. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_resources.py +0 -0
  24. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_runtime/__init__.py +0 -0
  25. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_runtime/asgi.py +0 -0
  26. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_runtime/container_io_manager.py +0 -0
  27. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_runtime/container_io_manager.pyi +0 -0
  28. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_runtime/execution_context.py +0 -0
  29. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_runtime/execution_context.pyi +0 -0
  30. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  31. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_runtime/telemetry.py +0 -0
  32. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_runtime/user_code_imports.py +0 -0
  33. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_serialization.py +0 -0
  34. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_traceback.py +0 -0
  35. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_tunnel.py +0 -0
  36. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_tunnel.pyi +0 -0
  37. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_type_manager.py +0 -0
  38. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/__init__.py +0 -0
  39. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/app_utils.py +0 -0
  40. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/async_utils.py +0 -0
  41. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/auth_token_manager.py +0 -0
  42. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/bytes_io_segment_payload.py +0 -0
  43. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/deprecation.py +0 -0
  44. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/docker_utils.py +0 -0
  45. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/function_utils.py +0 -0
  46. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/git_utils.py +0 -0
  47. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/grpc_testing.py +0 -0
  48. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/grpc_utils.py +0 -0
  49. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/hash_utils.py +0 -0
  50. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/http_utils.py +0 -0
  51. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/jwt_utils.py +0 -0
  52. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/logger.py +0 -0
  53. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/mount_utils.py +0 -0
  54. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/name_utils.py +0 -0
  55. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/package_utils.py +0 -0
  56. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/pattern_utils.py +0 -0
  57. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/rand_pb_testing.py +0 -0
  58. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/shell_utils.py +0 -0
  59. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_utils/time_utils.py +0 -0
  60. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_vendor/__init__.py +0 -0
  61. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  62. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_vendor/cloudpickle.py +0 -0
  63. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_vendor/tblib.py +0 -0
  64. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/_watcher.py +0 -0
  65. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/app.py +0 -0
  66. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/app.pyi +0 -0
  67. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/builder/2023.12.312.txt +0 -0
  68. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/builder/2023.12.txt +0 -0
  69. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/builder/2024.04.txt +0 -0
  70. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/builder/2024.10.txt +0 -0
  71. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/builder/2025.06.txt +0 -0
  72. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/builder/PREVIEW.txt +0 -0
  73. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/builder/README.md +0 -0
  74. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/builder/base-images.json +0 -0
  75. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/call_graph.py +0 -0
  76. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/__init__.py +0 -0
  77. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/_download.py +0 -0
  78. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/_traceback.py +0 -0
  79. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/app.py +0 -0
  80. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/cluster.py +0 -0
  81. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/config.py +0 -0
  82. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/container.py +0 -0
  83. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/dict.py +0 -0
  84. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/entry_point.py +0 -0
  85. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/environment.py +0 -0
  86. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/import_refs.py +0 -0
  87. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/launch.py +0 -0
  88. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/network_file_system.py +0 -0
  89. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/profile.py +0 -0
  90. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/programs/__init__.py +0 -0
  91. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/programs/launch_instance_ssh.py +0 -0
  92. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/programs/run_jupyter.py +0 -0
  93. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/programs/run_marimo.py +0 -0
  94. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/programs/vscode.py +0 -0
  95. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/queues.py +0 -0
  96. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/run.py +0 -0
  97. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/secret.py +0 -0
  98. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/token.py +0 -0
  99. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/utils.py +0 -0
  100. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cli/volume.py +0 -0
  101. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/client.py +0 -0
  102. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cloud_bucket_mount.py +0 -0
  103. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cloud_bucket_mount.pyi +0 -0
  104. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cls.py +0 -0
  105. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/cls.pyi +0 -0
  106. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/config.py +0 -0
  107. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/container_process.py +0 -0
  108. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/container_process.pyi +0 -0
  109. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/dict.py +0 -0
  110. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/dict.pyi +0 -0
  111. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/environments.py +0 -0
  112. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/environments.pyi +0 -0
  113. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/exception.py +0 -0
  114. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/experimental/__init__.py +0 -0
  115. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/experimental/flash.py +0 -0
  116. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/experimental/flash.pyi +0 -0
  117. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/experimental/ipython.py +0 -0
  118. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/file_io.py +0 -0
  119. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/file_io.pyi +0 -0
  120. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/file_pattern_matcher.py +0 -0
  121. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/functions.py +0 -0
  122. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/functions.pyi +0 -0
  123. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/gpu.py +0 -0
  124. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/image.py +0 -0
  125. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/image.pyi +0 -0
  126. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/io_streams.py +0 -0
  127. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/io_streams.pyi +0 -0
  128. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/mount.py +0 -0
  129. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/mount.pyi +0 -0
  130. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/network_file_system.py +0 -0
  131. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/network_file_system.pyi +0 -0
  132. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/object.py +0 -0
  133. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/object.pyi +0 -0
  134. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/output.py +0 -0
  135. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/parallel_map.py +0 -0
  136. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/parallel_map.pyi +0 -0
  137. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/partial_function.py +0 -0
  138. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/partial_function.pyi +0 -0
  139. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/proxy.py +0 -0
  140. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/proxy.pyi +0 -0
  141. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/py.typed +0 -0
  142. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/queue.py +0 -0
  143. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/queue.pyi +0 -0
  144. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/retries.py +0 -0
  145. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/runner.py +0 -0
  146. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/runner.pyi +0 -0
  147. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/running_app.py +0 -0
  148. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/schedule.py +0 -0
  149. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/scheduler_placement.py +0 -0
  150. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/secret.py +0 -0
  151. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/secret.pyi +0 -0
  152. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/serving.py +0 -0
  153. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/serving.pyi +0 -0
  154. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/snapshot.py +0 -0
  155. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/snapshot.pyi +0 -0
  156. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/stream_type.py +0 -0
  157. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/token_flow.py +0 -0
  158. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/token_flow.pyi +0 -0
  159. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/volume.py +0 -0
  160. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal/volume.pyi +0 -0
  161. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal.egg-info/SOURCES.txt +0 -0
  162. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal.egg-info/dependency_links.txt +0 -0
  163. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal.egg-info/entry_points.txt +0 -0
  164. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal.egg-info/requires.txt +0 -0
  165. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal.egg-info/top_level.txt +0 -0
  166. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_docs/__init__.py +0 -0
  167. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_docs/gen_cli_docs.py +0 -0
  168. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_docs/gen_reference_docs.py +0 -0
  169. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_docs/mdmd/__init__.py +0 -0
  170. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_docs/mdmd/mdmd.py +0 -0
  171. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_docs/mdmd/signatures.py +0 -0
  172. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/__init__.py +0 -0
  173. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/api.proto +0 -0
  174. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/api_grpc.py +0 -0
  175. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/api_pb2.py +0 -0
  176. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/api_pb2.pyi +0 -0
  177. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/api_pb2_grpc.py +0 -0
  178. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/api_pb2_grpc.pyi +0 -0
  179. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/modal_api_grpc.py +0 -0
  180. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/modal_options_grpc.py +0 -0
  181. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/options.proto +0 -0
  182. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/options_grpc.py +0 -0
  183. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/options_pb2.py +0 -0
  184. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/options_pb2.pyi +0 -0
  185. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/options_pb2_grpc.py +0 -0
  186. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/options_pb2_grpc.pyi +0 -0
  187. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_proto/py.typed +0 -0
  188. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/modal_version/__main__.py +0 -0
  189. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/pyproject.toml +0 -0
  190. {modal-1.1.5.dev15 → modal-1.1.5.dev17}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.1.5.dev15
3
+ Version: 1.1.5.dev17
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -85,7 +85,7 @@ async def _upload_to_s3_url(
85
85
  ) as resp:
86
86
  # S3 signal to slow down request rate.
87
87
  if resp.status == 503:
88
- logger.warning("Received SlowDown signal from S3, sleeping for 1 second before retrying.")
88
+ logger.debug("Received SlowDown signal from S3, sleeping for 1 second before retrying.")
89
89
  await asyncio.sleep(1)
90
90
 
91
91
  if resp.status != 200:
@@ -283,7 +283,7 @@ async def blob_upload_with_r2_failure_info(payload: bytes, stub: ModalClientModa
283
283
  logger.debug(f"Uploading large blob of size {size_mib:.2f} MiB")
284
284
  t0 = time.time()
285
285
  if isinstance(payload, str):
286
- logger.warning("Blob uploading string, not bytes - auto-encoding as utf8")
286
+ logger.debug("Blob uploading string, not bytes - auto-encoding as utf8")
287
287
  payload = payload.encode("utf8")
288
288
  upload_hashes = get_upload_hashes(payload)
289
289
  blob_id, r2_failed, r2_throughput_bytes_s = await _blob_upload(upload_hashes, payload, stub)
@@ -317,7 +317,7 @@ async def _download_from_url(download_url: str) -> bytes:
317
317
  async with ClientSessionRegistry.get_session().get(download_url) as s3_resp:
318
318
  # S3 signal to slow down request rate.
319
319
  if s3_resp.status == 503:
320
- logger.warning("Received SlowDown signal from S3, sleeping for 1 second before retrying.")
320
+ logger.debug("Received SlowDown signal from S3, sleeping for 1 second before retrying.")
321
321
  await asyncio.sleep(1)
322
322
 
323
323
  if s3_resp.status != 200:
@@ -349,7 +349,7 @@ async def blob_iter(blob_id: str, stub: ModalClientModal) -> AsyncIterator[bytes
349
349
  async with ClientSessionRegistry.get_session().get(download_url) as s3_resp:
350
350
  # S3 signal to slow down request rate.
351
351
  if s3_resp.status == 503:
352
- logger.warning("Received SlowDown signal from S3, sleeping for 1 second before retrying.")
352
+ logger.debug("Received SlowDown signal from S3, sleeping for 1 second before retrying.")
353
353
  await asyncio.sleep(1)
354
354
 
355
355
  if s3_resp.status != 200:
@@ -33,7 +33,7 @@ class _Client:
33
33
  server_url: str,
34
34
  client_type: int,
35
35
  credentials: typing.Optional[tuple[str, str]],
36
- version: str = "1.1.5.dev15",
36
+ version: str = "1.1.5.dev17",
37
37
  ):
38
38
  """mdmd:hidden
39
39
  The Modal client object is not intended to be instantiated directly by users.
@@ -164,7 +164,7 @@ class Client:
164
164
  server_url: str,
165
165
  client_type: int,
166
166
  credentials: typing.Optional[tuple[str, str]],
167
- version: str = "1.1.5.dev15",
167
+ version: str = "1.1.5.dev17",
168
168
  ):
169
169
  """mdmd:hidden
170
170
  The Modal client object is not intended to be instantiated directly by users.
@@ -1,9 +1,11 @@
1
1
  # Copyright Modal Labs 2022
2
2
  import asyncio
3
+ import json
3
4
  import os
4
5
  import time
5
6
  from collections.abc import AsyncGenerator, Sequence
6
- from typing import TYPE_CHECKING, AsyncIterator, Literal, Optional, Union, overload
7
+ from dataclasses import dataclass
8
+ from typing import TYPE_CHECKING, Any, AsyncIterator, Literal, Optional, Union, overload
7
9
 
8
10
  from .config import config, logger
9
11
 
@@ -99,6 +101,14 @@ class DefaultSandboxNameOverride(str):
99
101
  _DEFAULT_SANDBOX_NAME_OVERRIDE = DefaultSandboxNameOverride()
100
102
 
101
103
 
104
+ @dataclass(frozen=True)
105
+ class SandboxConnectCredentials:
106
+ """Simple data structure storing credentials for making HTTP connections to a sandbox."""
107
+
108
+ url: str
109
+ token: str
110
+
111
+
102
112
  class _Sandbox(_Object, type_prefix="sb"):
103
113
  """A `Sandbox` object lets you interact with a running sandbox. This API is similar to Python's
104
114
  [asyncio.subprocess.Process](https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.subprocess.Process).
@@ -626,6 +636,23 @@ class _Sandbox(_Object, type_prefix="sb"):
626
636
 
627
637
  return self._tunnels
628
638
 
639
+ async def create_connect_token(
640
+ self, metadata: Optional[Union[str, dict[str, Any]]] = None
641
+ ) -> SandboxConnectCredentials:
642
+ """Create a token for making HTTP connections to the sandbox.
643
+
644
+ Also accepts an optional metadata string or dict to associate with the token. This metadata
645
+ will be added to the headers by the proxy when forwarding requests to the sandbox."""
646
+ if metadata is not None and isinstance(metadata, dict):
647
+ try:
648
+ metadata = json.dumps(metadata)
649
+ except Exception as e:
650
+ raise InvalidError(f"Failed to serialize metadata: {e}")
651
+
652
+ req = api_pb2.SandboxCreateConnectTokenRequest(sandbox_id=self.object_id, metadata=metadata)
653
+ resp = await retry_transient_errors(self._client.stub.SandboxCreateConnectToken, req)
654
+ return SandboxConnectCredentials(resp.url, resp.token)
655
+
629
656
  async def reload_volumes(self) -> None:
630
657
  """Reload all Volumes mounted in the Sandbox.
631
658
 
@@ -39,6 +39,36 @@ class DefaultSandboxNameOverride(str):
39
39
 
40
40
  _DEFAULT_SANDBOX_NAME_OVERRIDE: DefaultSandboxNameOverride
41
41
 
42
+ class SandboxConnectCredentials:
43
+ """Simple data structure storing credentials for making HTTP connections to a sandbox."""
44
+
45
+ url: str
46
+ token: str
47
+
48
+ def __init__(self, url: str, token: str) -> None:
49
+ """Initialize self. See help(type(self)) for accurate signature."""
50
+ ...
51
+
52
+ def __repr__(self):
53
+ """Return repr(self)."""
54
+ ...
55
+
56
+ def __eq__(self, other):
57
+ """Return self==value."""
58
+ ...
59
+
60
+ def __setattr__(self, name, value):
61
+ """Implement setattr(self, name, value)."""
62
+ ...
63
+
64
+ def __delattr__(self, name):
65
+ """Implement delattr(self, name)."""
66
+ ...
67
+
68
+ def __hash__(self):
69
+ """Return hash(self)."""
70
+ ...
71
+
42
72
  class _Sandbox(modal._object._Object):
43
73
  """A `Sandbox` object lets you interact with a running sandbox. This API is similar to Python's
44
74
  [asyncio.subprocess.Process](https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.subprocess.Process).
@@ -224,6 +254,16 @@ class _Sandbox(modal._object._Object):
224
254
  """
225
255
  ...
226
256
 
257
+ async def create_connect_token(
258
+ self, metadata: typing.Union[str, dict[str, typing.Any], None] = None
259
+ ) -> SandboxConnectCredentials:
260
+ """Create a token for making HTTP connections to the sandbox.
261
+
262
+ Also accepts an optional metadata string or dict to associate with the token. This metadata
263
+ will be added to the headers by the proxy when forwarding requests to the sandbox.
264
+ """
265
+ ...
266
+
227
267
  async def reload_volumes(self) -> None:
228
268
  """Reload all Volumes mounted in the Sandbox.
229
269
 
@@ -708,6 +748,29 @@ class Sandbox(modal.object.Object):
708
748
 
709
749
  tunnels: __tunnels_spec[typing_extensions.Self]
710
750
 
751
+ class __create_connect_token_spec(typing_extensions.Protocol[SUPERSELF]):
752
+ def __call__(
753
+ self, /, metadata: typing.Union[str, dict[str, typing.Any], None] = None
754
+ ) -> SandboxConnectCredentials:
755
+ """Create a token for making HTTP connections to the sandbox.
756
+
757
+ Also accepts an optional metadata string or dict to associate with the token. This metadata
758
+ will be added to the headers by the proxy when forwarding requests to the sandbox.
759
+ """
760
+ ...
761
+
762
+ async def aio(
763
+ self, /, metadata: typing.Union[str, dict[str, typing.Any], None] = None
764
+ ) -> SandboxConnectCredentials:
765
+ """Create a token for making HTTP connections to the sandbox.
766
+
767
+ Also accepts an optional metadata string or dict to associate with the token. This metadata
768
+ will be added to the headers by the proxy when forwarding requests to the sandbox.
769
+ """
770
+ ...
771
+
772
+ create_connect_token: __create_connect_token_spec[typing_extensions.Self]
773
+
711
774
  class __reload_volumes_spec(typing_extensions.Protocol[SUPERSELF]):
712
775
  def __call__(self, /) -> None:
713
776
  """Reload all Volumes mounted in the Sandbox.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.1.5.dev15
3
+ Version: 1.1.5.dev17
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2025
2
2
  """Supplies the current version of the modal client library."""
3
3
 
4
- __version__ = "1.1.5.dev15"
4
+ __version__ = "1.1.5.dev17"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes