modal 1.1.2.dev28__tar.gz → 1.1.2.dev29__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.2.dev28 → modal-1.1.2.dev29}/PKG-INFO +1 -1
  2. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/client.pyi +2 -2
  3. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/dict.py +57 -3
  4. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/dict.pyi +107 -0
  5. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/queue.py +57 -3
  6. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/queue.pyi +107 -0
  7. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/secret.py +60 -2
  8. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/secret.pyi +116 -0
  9. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/volume.py +55 -2
  10. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/volume.pyi +104 -0
  11. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal.egg-info/PKG-INFO +1 -1
  12. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_version/__init__.py +1 -1
  13. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/LICENSE +0 -0
  14. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/README.md +0 -0
  15. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/__init__.py +0 -0
  16. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/__main__.py +0 -0
  17. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_clustered_functions.py +0 -0
  18. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_clustered_functions.pyi +0 -0
  19. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_container_entrypoint.py +0 -0
  20. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_functions.py +0 -0
  21. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_ipython.py +0 -0
  22. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_location.py +0 -0
  23. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_object.py +0 -0
  24. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_output.py +0 -0
  25. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_partial_function.py +0 -0
  26. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_pty.py +0 -0
  27. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_resolver.py +0 -0
  28. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_resources.py +0 -0
  29. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_runtime/__init__.py +0 -0
  30. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_runtime/asgi.py +0 -0
  31. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_runtime/container_io_manager.py +0 -0
  32. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_runtime/container_io_manager.pyi +0 -0
  33. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_runtime/execution_context.py +0 -0
  34. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_runtime/execution_context.pyi +0 -0
  35. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  36. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_runtime/telemetry.py +0 -0
  37. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_runtime/user_code_imports.py +0 -0
  38. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_serialization.py +0 -0
  39. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_traceback.py +0 -0
  40. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_tunnel.py +0 -0
  41. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_tunnel.pyi +0 -0
  42. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_type_manager.py +0 -0
  43. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/__init__.py +0 -0
  44. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/app_utils.py +0 -0
  45. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/async_utils.py +0 -0
  46. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/auth_token_manager.py +0 -0
  47. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/blob_utils.py +0 -0
  48. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/bytes_io_segment_payload.py +0 -0
  49. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/deprecation.py +0 -0
  50. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/docker_utils.py +0 -0
  51. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/function_utils.py +0 -0
  52. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/git_utils.py +0 -0
  53. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/grpc_testing.py +0 -0
  54. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/grpc_utils.py +0 -0
  55. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/hash_utils.py +0 -0
  56. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/http_utils.py +0 -0
  57. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/jwt_utils.py +0 -0
  58. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/logger.py +0 -0
  59. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/mount_utils.py +0 -0
  60. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/name_utils.py +0 -0
  61. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/package_utils.py +0 -0
  62. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/pattern_utils.py +0 -0
  63. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/rand_pb_testing.py +0 -0
  64. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/shell_utils.py +0 -0
  65. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_utils/time_utils.py +0 -0
  66. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_vendor/__init__.py +0 -0
  67. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  68. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_vendor/cloudpickle.py +0 -0
  69. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_vendor/tblib.py +0 -0
  70. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/_watcher.py +0 -0
  71. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/app.py +0 -0
  72. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/app.pyi +0 -0
  73. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/builder/2023.12.312.txt +0 -0
  74. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/builder/2023.12.txt +0 -0
  75. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/builder/2024.04.txt +0 -0
  76. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/builder/2024.10.txt +0 -0
  77. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/builder/2025.06.txt +0 -0
  78. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/builder/PREVIEW.txt +0 -0
  79. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/builder/README.md +0 -0
  80. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/builder/base-images.json +0 -0
  81. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/call_graph.py +0 -0
  82. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/__init__.py +0 -0
  83. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/_download.py +0 -0
  84. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/_traceback.py +0 -0
  85. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/app.py +0 -0
  86. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/cluster.py +0 -0
  87. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/config.py +0 -0
  88. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/container.py +0 -0
  89. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/dict.py +0 -0
  90. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/entry_point.py +0 -0
  91. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/environment.py +0 -0
  92. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/import_refs.py +0 -0
  93. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/launch.py +0 -0
  94. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/network_file_system.py +0 -0
  95. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/profile.py +0 -0
  96. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/programs/__init__.py +0 -0
  97. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/programs/launch_instance_ssh.py +0 -0
  98. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/programs/run_jupyter.py +0 -0
  99. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/programs/run_marimo.py +0 -0
  100. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/programs/vscode.py +0 -0
  101. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/queues.py +0 -0
  102. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/run.py +0 -0
  103. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/secret.py +0 -0
  104. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/token.py +0 -0
  105. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/utils.py +0 -0
  106. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cli/volume.py +0 -0
  107. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/client.py +0 -0
  108. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cloud_bucket_mount.py +0 -0
  109. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cloud_bucket_mount.pyi +0 -0
  110. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cls.py +0 -0
  111. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/cls.pyi +0 -0
  112. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/config.py +0 -0
  113. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/container_process.py +0 -0
  114. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/container_process.pyi +0 -0
  115. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/environments.py +0 -0
  116. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/environments.pyi +0 -0
  117. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/exception.py +0 -0
  118. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/experimental/__init__.py +0 -0
  119. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/experimental/flash.py +0 -0
  120. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/experimental/flash.pyi +0 -0
  121. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/experimental/ipython.py +0 -0
  122. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/file_io.py +0 -0
  123. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/file_io.pyi +0 -0
  124. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/file_pattern_matcher.py +0 -0
  125. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/functions.py +0 -0
  126. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/functions.pyi +0 -0
  127. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/gpu.py +0 -0
  128. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/image.py +0 -0
  129. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/image.pyi +0 -0
  130. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/io_streams.py +0 -0
  131. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/io_streams.pyi +0 -0
  132. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/mount.py +0 -0
  133. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/mount.pyi +0 -0
  134. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/network_file_system.py +0 -0
  135. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/network_file_system.pyi +0 -0
  136. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/object.py +0 -0
  137. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/object.pyi +0 -0
  138. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/output.py +0 -0
  139. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/parallel_map.py +0 -0
  140. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/parallel_map.pyi +0 -0
  141. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/partial_function.py +0 -0
  142. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/partial_function.pyi +0 -0
  143. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/proxy.py +0 -0
  144. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/proxy.pyi +0 -0
  145. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/py.typed +0 -0
  146. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/retries.py +0 -0
  147. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/runner.py +0 -0
  148. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/runner.pyi +0 -0
  149. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/running_app.py +0 -0
  150. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/sandbox.py +0 -0
  151. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/sandbox.pyi +0 -0
  152. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/schedule.py +0 -0
  153. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/scheduler_placement.py +0 -0
  154. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/serving.py +0 -0
  155. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/serving.pyi +0 -0
  156. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/snapshot.py +0 -0
  157. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/snapshot.pyi +0 -0
  158. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/stream_type.py +0 -0
  159. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/token_flow.py +0 -0
  160. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal/token_flow.pyi +0 -0
  161. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal.egg-info/SOURCES.txt +0 -0
  162. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal.egg-info/dependency_links.txt +0 -0
  163. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal.egg-info/entry_points.txt +0 -0
  164. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal.egg-info/requires.txt +0 -0
  165. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal.egg-info/top_level.txt +0 -0
  166. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_docs/__init__.py +0 -0
  167. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_docs/gen_cli_docs.py +0 -0
  168. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_docs/gen_reference_docs.py +0 -0
  169. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_docs/mdmd/__init__.py +0 -0
  170. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_docs/mdmd/mdmd.py +0 -0
  171. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_docs/mdmd/signatures.py +0 -0
  172. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/__init__.py +0 -0
  173. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/api.proto +0 -0
  174. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/api_grpc.py +0 -0
  175. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/api_pb2.py +0 -0
  176. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/api_pb2.pyi +0 -0
  177. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/api_pb2_grpc.py +0 -0
  178. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/api_pb2_grpc.pyi +0 -0
  179. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/modal_api_grpc.py +0 -0
  180. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/modal_options_grpc.py +0 -0
  181. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/options.proto +0 -0
  182. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/options_grpc.py +0 -0
  183. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/options_pb2.py +0 -0
  184. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/options_pb2.pyi +0 -0
  185. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/options_pb2_grpc.py +0 -0
  186. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/options_pb2_grpc.pyi +0 -0
  187. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_proto/py.typed +0 -0
  188. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/modal_version/__main__.py +0 -0
  189. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/pyproject.toml +0 -0
  190. {modal-1.1.2.dev28 → modal-1.1.2.dev29}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.1.2.dev28
3
+ Version: 1.1.2.dev29
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -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.2.dev28",
36
+ version: str = "1.1.2.dev29",
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.2.dev28",
167
+ version: str = "1.1.2.dev29",
168
168
  ):
169
169
  """mdmd:hidden
170
170
  The Modal client object is not intended to be instantiated directly by users.
@@ -5,7 +5,7 @@ from datetime import datetime
5
5
  from typing import Any, Optional, Union
6
6
 
7
7
  from google.protobuf.message import Message
8
- from grpclib import GRPCError
8
+ from grpclib import GRPCError, Status
9
9
  from synchronicity import classproperty
10
10
  from synchronicity.async_wrap import asynccontextmanager
11
11
 
@@ -27,7 +27,7 @@ from ._utils.name_utils import check_object_name
27
27
  from ._utils.time_utils import as_timestamp, timestamp_to_localized_dt
28
28
  from .client import _Client
29
29
  from .config import logger
30
- from .exception import InvalidError, NotFoundError, RequestSizeError
30
+ from .exception import AlreadyExistsError, InvalidError, NotFoundError, RequestSizeError
31
31
 
32
32
 
33
33
  def _serialize_dict(data):
@@ -49,6 +49,58 @@ class DictInfo:
49
49
  class _DictManager:
50
50
  """Namespace with methods for managing named Dict objects."""
51
51
 
52
+ @staticmethod
53
+ async def create(
54
+ name: str, # Name to use for the new Dict
55
+ *,
56
+ allow_existing: bool = False, # If True, no-op when the Dict already exists
57
+ environment_name: Optional[str] = None, # Uses active environment if not specified
58
+ client: Optional[_Client] = None, # Optional client with Modal credentials
59
+ ) -> None:
60
+ """Create a new Dict object.
61
+
62
+ **Examples:**
63
+
64
+ ```python notest
65
+ modal.Dict.objects.create("my-dict")
66
+ ```
67
+
68
+ Dicts will be created in the active environment, or another one can be specified:
69
+
70
+ ```python notest
71
+ modal.Dict.objects.create("my-dict", environment_name="dev")
72
+ ```
73
+
74
+ By default, an error will be raised if the Dict already exists, but passing
75
+ `allow_existing=True` will make the creation attempt a no-op in this case.
76
+
77
+ ```python notest
78
+ modal.Dict.objects.create("my-dict", allow_existing=True)
79
+ ```
80
+
81
+ Note that this method does not return a local instance of the Dict. You can use
82
+ `modal.Dict.from_name` to perform a lookup after creation.
83
+
84
+ """
85
+ client = await _Client.from_env() if client is None else client
86
+ object_creation_type = (
87
+ api_pb2.OBJECT_CREATION_TYPE_CREATE_IF_MISSING
88
+ if allow_existing
89
+ else api_pb2.OBJECT_CREATION_TYPE_CREATE_FAIL_IF_EXISTS
90
+ )
91
+ req = api_pb2.DictGetOrCreateRequest(
92
+ deployment_name=name,
93
+ environment_name=_get_environment_name(environment_name),
94
+ object_creation_type=object_creation_type,
95
+ )
96
+ try:
97
+ await retry_transient_errors(client.stub.DictGetOrCreate, req)
98
+ except GRPCError as exc:
99
+ if exc.status == Status.ALREADY_EXISTS and not allow_existing:
100
+ raise AlreadyExistsError(exc.message)
101
+ else:
102
+ raise
103
+
52
104
  @staticmethod
53
105
  async def list(
54
106
  *,
@@ -89,7 +141,9 @@ class _DictManager:
89
141
  async def retrieve_page(created_before: float) -> bool:
90
142
  max_page_size = 100 if max_objects is None else min(100, max_objects - len(items))
91
143
  pagination = api_pb2.ListPagination(max_objects=max_page_size, created_before=created_before)
92
- req = api_pb2.DictListRequest(environment_name=environment_name, pagination=pagination)
144
+ req = api_pb2.DictListRequest(
145
+ environment_name=_get_environment_name(environment_name), pagination=pagination
146
+ )
93
147
  resp = await retry_transient_errors(client.stub.DictList, req)
94
148
  items.extend(resp.dicts)
95
149
  finished = (len(resp.dicts) < max_page_size) or (max_objects is not None and len(items) >= max_objects)
@@ -35,6 +35,40 @@ class DictInfo:
35
35
 
36
36
  class _DictManager:
37
37
  """Namespace with methods for managing named Dict objects."""
38
+ @staticmethod
39
+ async def create(
40
+ name: str,
41
+ *,
42
+ allow_existing: bool = False,
43
+ environment_name: typing.Optional[str] = None,
44
+ client: typing.Optional[modal.client._Client] = None,
45
+ ) -> None:
46
+ """Create a new Dict object.
47
+
48
+ **Examples:**
49
+
50
+ ```python notest
51
+ modal.Dict.objects.create("my-dict")
52
+ ```
53
+
54
+ Dicts will be created in the active environment, or another one can be specified:
55
+
56
+ ```python notest
57
+ modal.Dict.objects.create("my-dict", environment_name="dev")
58
+ ```
59
+
60
+ By default, an error will be raised if the Dict already exists, but passing
61
+ `allow_existing=True` will make the creation attempt a no-op in this case.
62
+
63
+ ```python notest
64
+ modal.Dict.objects.create("my-dict", allow_existing=True)
65
+ ```
66
+
67
+ Note that this method does not return a local instance of the Dict. You can use
68
+ `modal.Dict.from_name` to perform a lookup after creation.
69
+ """
70
+ ...
71
+
38
72
  @staticmethod
39
73
  async def list(
40
74
  *,
@@ -100,6 +134,79 @@ class DictManager:
100
134
  """Initialize self. See help(type(self)) for accurate signature."""
101
135
  ...
102
136
 
137
+ class __create_spec(typing_extensions.Protocol):
138
+ def __call__(
139
+ self,
140
+ /,
141
+ name: str,
142
+ *,
143
+ allow_existing: bool = False,
144
+ environment_name: typing.Optional[str] = None,
145
+ client: typing.Optional[modal.client.Client] = None,
146
+ ) -> None:
147
+ """Create a new Dict object.
148
+
149
+ **Examples:**
150
+
151
+ ```python notest
152
+ modal.Dict.objects.create("my-dict")
153
+ ```
154
+
155
+ Dicts will be created in the active environment, or another one can be specified:
156
+
157
+ ```python notest
158
+ modal.Dict.objects.create("my-dict", environment_name="dev")
159
+ ```
160
+
161
+ By default, an error will be raised if the Dict already exists, but passing
162
+ `allow_existing=True` will make the creation attempt a no-op in this case.
163
+
164
+ ```python notest
165
+ modal.Dict.objects.create("my-dict", allow_existing=True)
166
+ ```
167
+
168
+ Note that this method does not return a local instance of the Dict. You can use
169
+ `modal.Dict.from_name` to perform a lookup after creation.
170
+ """
171
+ ...
172
+
173
+ async def aio(
174
+ self,
175
+ /,
176
+ name: str,
177
+ *,
178
+ allow_existing: bool = False,
179
+ environment_name: typing.Optional[str] = None,
180
+ client: typing.Optional[modal.client.Client] = None,
181
+ ) -> None:
182
+ """Create a new Dict object.
183
+
184
+ **Examples:**
185
+
186
+ ```python notest
187
+ modal.Dict.objects.create("my-dict")
188
+ ```
189
+
190
+ Dicts will be created in the active environment, or another one can be specified:
191
+
192
+ ```python notest
193
+ modal.Dict.objects.create("my-dict", environment_name="dev")
194
+ ```
195
+
196
+ By default, an error will be raised if the Dict already exists, but passing
197
+ `allow_existing=True` will make the creation attempt a no-op in this case.
198
+
199
+ ```python notest
200
+ modal.Dict.objects.create("my-dict", allow_existing=True)
201
+ ```
202
+
203
+ Note that this method does not return a local instance of the Dict. You can use
204
+ `modal.Dict.from_name` to perform a lookup after creation.
205
+ """
206
+ ...
207
+
208
+ create: __create_spec
209
+
103
210
  class __list_spec(typing_extensions.Protocol):
104
211
  def __call__(
105
212
  self,
@@ -29,7 +29,7 @@ from ._utils.grpc_utils import retry_transient_errors
29
29
  from ._utils.name_utils import check_object_name
30
30
  from ._utils.time_utils import as_timestamp, timestamp_to_localized_dt
31
31
  from .client import _Client
32
- from .exception import InvalidError, NotFoundError, RequestSizeError
32
+ from .exception import AlreadyExistsError, InvalidError, NotFoundError, RequestSizeError
33
33
 
34
34
 
35
35
  @dataclass
@@ -47,10 +47,62 @@ class QueueInfo:
47
47
  class _QueueManager:
48
48
  """Namespace with methods for managing named Queue objects."""
49
49
 
50
+ @staticmethod
51
+ async def create(
52
+ name: str, # Name to use for the new Queue
53
+ *,
54
+ allow_existing: bool = False, # If True, no-op when the Queue already exists
55
+ environment_name: Optional[str] = None, # Uses active environment if not specified
56
+ client: Optional[_Client] = None, # Optional client with Modal credentials
57
+ ) -> None:
58
+ """Create a new Queue object.
59
+
60
+ **Examples:**
61
+
62
+ ```python notest
63
+ modal.Queue.objects.create("my-queue")
64
+ ```
65
+
66
+ Queues will be created in the active environment, or another one can be specified:
67
+
68
+ ```python notest
69
+ modal.Queue.objects.create("my-queue", environment_name="dev")
70
+ ```
71
+
72
+ By default, an error will be raised if the Queue already exists, but passing
73
+ `allow_existing=True` will make the creation attempt a no-op in this case.
74
+
75
+ ```python notest
76
+ modal.Queue.objects.create("my-queue", allow_existing=True)
77
+ ```
78
+
79
+ Note that this method does not return a local instance of the Queue. You can use
80
+ `modal.Queue.from_name` to perform a lookup after creation.
81
+
82
+ """
83
+ client = await _Client.from_env() if client is None else client
84
+ object_creation_type = (
85
+ api_pb2.OBJECT_CREATION_TYPE_CREATE_IF_MISSING
86
+ if allow_existing
87
+ else api_pb2.OBJECT_CREATION_TYPE_CREATE_FAIL_IF_EXISTS
88
+ )
89
+ req = api_pb2.QueueGetOrCreateRequest(
90
+ deployment_name=name,
91
+ environment_name=_get_environment_name(environment_name),
92
+ object_creation_type=object_creation_type,
93
+ )
94
+ try:
95
+ await retry_transient_errors(client.stub.QueueGetOrCreate, req)
96
+ except GRPCError as exc:
97
+ if exc.status == Status.ALREADY_EXISTS and not allow_existing:
98
+ raise AlreadyExistsError(exc.message)
99
+ else:
100
+ raise
101
+
50
102
  @staticmethod
51
103
  async def list(
52
104
  *,
53
- max_objects: Optional[int] = None, # Limit requests to this size
105
+ max_objects: Optional[int] = None, # Limit results to this size
54
106
  created_before: Optional[Union[datetime, str]] = None, # Limit based on creation date
55
107
  environment_name: str = "", # Uses active environment if not specified
56
108
  client: Optional[_Client] = None, # Optional client with Modal credentials
@@ -87,7 +139,9 @@ class _QueueManager:
87
139
  async def retrieve_page(created_before: float) -> bool:
88
140
  max_page_size = 100 if max_objects is None else min(100, max_objects - len(items))
89
141
  pagination = api_pb2.ListPagination(max_objects=max_page_size, created_before=created_before)
90
- req = api_pb2.QueueListRequest(environment_name=environment_name, pagination=pagination)
142
+ req = api_pb2.QueueListRequest(
143
+ environment_name=_get_environment_name(environment_name), pagination=pagination
144
+ )
91
145
  resp = await retry_transient_errors(client.stub.QueueList, req)
92
146
  items.extend(resp.queues)
93
147
  finished = (len(resp.queues) < max_page_size) or (max_objects is not None and len(items) >= max_objects)
@@ -33,6 +33,40 @@ class QueueInfo:
33
33
 
34
34
  class _QueueManager:
35
35
  """Namespace with methods for managing named Queue objects."""
36
+ @staticmethod
37
+ async def create(
38
+ name: str,
39
+ *,
40
+ allow_existing: bool = False,
41
+ environment_name: typing.Optional[str] = None,
42
+ client: typing.Optional[modal.client._Client] = None,
43
+ ) -> None:
44
+ """Create a new Queue object.
45
+
46
+ **Examples:**
47
+
48
+ ```python notest
49
+ modal.Queue.objects.create("my-queue")
50
+ ```
51
+
52
+ Queues will be created in the active environment, or another one can be specified:
53
+
54
+ ```python notest
55
+ modal.Queue.objects.create("my-queue", environment_name="dev")
56
+ ```
57
+
58
+ By default, an error will be raised if the Queue already exists, but passing
59
+ `allow_existing=True` will make the creation attempt a no-op in this case.
60
+
61
+ ```python notest
62
+ modal.Queue.objects.create("my-queue", allow_existing=True)
63
+ ```
64
+
65
+ Note that this method does not return a local instance of the Queue. You can use
66
+ `modal.Queue.from_name` to perform a lookup after creation.
67
+ """
68
+ ...
69
+
36
70
  @staticmethod
37
71
  async def list(
38
72
  *,
@@ -98,6 +132,79 @@ class QueueManager:
98
132
  """Initialize self. See help(type(self)) for accurate signature."""
99
133
  ...
100
134
 
135
+ class __create_spec(typing_extensions.Protocol):
136
+ def __call__(
137
+ self,
138
+ /,
139
+ name: str,
140
+ *,
141
+ allow_existing: bool = False,
142
+ environment_name: typing.Optional[str] = None,
143
+ client: typing.Optional[modal.client.Client] = None,
144
+ ) -> None:
145
+ """Create a new Queue object.
146
+
147
+ **Examples:**
148
+
149
+ ```python notest
150
+ modal.Queue.objects.create("my-queue")
151
+ ```
152
+
153
+ Queues will be created in the active environment, or another one can be specified:
154
+
155
+ ```python notest
156
+ modal.Queue.objects.create("my-queue", environment_name="dev")
157
+ ```
158
+
159
+ By default, an error will be raised if the Queue already exists, but passing
160
+ `allow_existing=True` will make the creation attempt a no-op in this case.
161
+
162
+ ```python notest
163
+ modal.Queue.objects.create("my-queue", allow_existing=True)
164
+ ```
165
+
166
+ Note that this method does not return a local instance of the Queue. You can use
167
+ `modal.Queue.from_name` to perform a lookup after creation.
168
+ """
169
+ ...
170
+
171
+ async def aio(
172
+ self,
173
+ /,
174
+ name: str,
175
+ *,
176
+ allow_existing: bool = False,
177
+ environment_name: typing.Optional[str] = None,
178
+ client: typing.Optional[modal.client.Client] = None,
179
+ ) -> None:
180
+ """Create a new Queue object.
181
+
182
+ **Examples:**
183
+
184
+ ```python notest
185
+ modal.Queue.objects.create("my-queue")
186
+ ```
187
+
188
+ Queues will be created in the active environment, or another one can be specified:
189
+
190
+ ```python notest
191
+ modal.Queue.objects.create("my-queue", environment_name="dev")
192
+ ```
193
+
194
+ By default, an error will be raised if the Queue already exists, but passing
195
+ `allow_existing=True` will make the creation attempt a no-op in this case.
196
+
197
+ ```python notest
198
+ modal.Queue.objects.create("my-queue", allow_existing=True)
199
+ ```
200
+
201
+ Note that this method does not return a local instance of the Queue. You can use
202
+ `modal.Queue.from_name` to perform a lookup after creation.
203
+ """
204
+ ...
205
+
206
+ create: __create_spec
207
+
101
208
  class __list_spec(typing_extensions.Protocol):
102
209
  def __call__(
103
210
  self,
@@ -19,7 +19,7 @@ from ._utils.grpc_utils import retry_transient_errors
19
19
  from ._utils.name_utils import check_object_name
20
20
  from ._utils.time_utils import as_timestamp, timestamp_to_localized_dt
21
21
  from .client import _Client
22
- from .exception import InvalidError, NotFoundError
22
+ from .exception import AlreadyExistsError, InvalidError, NotFoundError
23
23
 
24
24
  ENV_DICT_WRONG_TYPE_ERR = "the env_dict argument to Secret has to be a dict[str, Union[str, None]]"
25
25
 
@@ -39,6 +39,62 @@ class SecretInfo:
39
39
  class _SecretManager:
40
40
  """Namespace with methods for managing named Secret objects."""
41
41
 
42
+ @staticmethod
43
+ async def create(
44
+ name: str, # Name to use for the new Secret
45
+ env_dict: dict[str, str], # Key-value pairs to set in the Secret
46
+ *,
47
+ allow_existing: bool = False, # If True, no-op when the Secret already exists
48
+ environment_name: Optional[str] = None, # Uses active environment if not specified
49
+ client: Optional[_Client] = None, # Optional client with Modal credentials
50
+ ) -> None:
51
+ """Create a new Secret object.
52
+
53
+ **Examples:**
54
+
55
+ ```python notest
56
+ contents = {"MY_KEY": "my-value", "MY_OTHER_KEY": "my-other-value"}
57
+ modal.Secret.objects.create("my-secret", contents)
58
+ ```
59
+
60
+ Secrets will be created in the active environment, or another one can be specified:
61
+
62
+ ```python notest
63
+ modal.Secret.objects.create("my-secret", contents, environment_name="dev")
64
+ ```
65
+
66
+ By default, an error will be raised if the Secret already exists, but passing
67
+ `allow_existing=True` will make the creation attempt a no-op in this case.
68
+ If the `env_dict` data differs from the existing Secret, it will be ignored.
69
+
70
+ ```python notest
71
+ modal.Secret.objects.create("my-secret", contents, allow_existing=True)
72
+ ```
73
+
74
+ Note that this method does not return a local instance of the Secret. You can use
75
+ `modal.Secret.from_name` to perform a lookup after creation.
76
+
77
+ """
78
+ client = await _Client.from_env() if client is None else client
79
+ object_creation_type = (
80
+ api_pb2.OBJECT_CREATION_TYPE_CREATE_IF_MISSING
81
+ if allow_existing
82
+ else api_pb2.OBJECT_CREATION_TYPE_CREATE_FAIL_IF_EXISTS
83
+ )
84
+ req = api_pb2.SecretGetOrCreateRequest(
85
+ deployment_name=name,
86
+ environment_name=_get_environment_name(environment_name),
87
+ object_creation_type=object_creation_type,
88
+ env_dict=env_dict,
89
+ )
90
+ try:
91
+ await retry_transient_errors(client.stub.SecretGetOrCreate, req)
92
+ except GRPCError as exc:
93
+ if exc.status == Status.ALREADY_EXISTS and not allow_existing:
94
+ raise AlreadyExistsError(exc.message)
95
+ else:
96
+ raise
97
+
42
98
  @staticmethod
43
99
  async def list(
44
100
  *,
@@ -79,7 +135,9 @@ class _SecretManager:
79
135
  async def retrieve_page(created_before: float) -> bool:
80
136
  max_page_size = 100 if max_objects is None else min(100, max_objects - len(items))
81
137
  pagination = api_pb2.ListPagination(max_objects=max_page_size, created_before=created_before)
82
- req = api_pb2.SecretListRequest(environment_name=environment_name, pagination=pagination)
138
+ req = api_pb2.SecretListRequest(
139
+ environment_name=_get_environment_name(environment_name), pagination=pagination
140
+ )
83
141
  resp = await retry_transient_errors(client.stub.SecretList, req)
84
142
  items.extend(resp.items)
85
143
  finished = (len(resp.items) < max_page_size) or (max_objects is not None and len(items) >= max_objects)
@@ -31,6 +31,43 @@ class SecretInfo:
31
31
 
32
32
  class _SecretManager:
33
33
  """Namespace with methods for managing named Secret objects."""
34
+ @staticmethod
35
+ async def create(
36
+ name: str,
37
+ env_dict: dict[str, str],
38
+ *,
39
+ allow_existing: bool = False,
40
+ environment_name: typing.Optional[str] = None,
41
+ client: typing.Optional[modal.client._Client] = None,
42
+ ) -> None:
43
+ """Create a new Secret object.
44
+
45
+ **Examples:**
46
+
47
+ ```python notest
48
+ contents = {"MY_KEY": "my-value", "MY_OTHER_KEY": "my-other-value"}
49
+ modal.Secret.objects.create("my-secret", contents)
50
+ ```
51
+
52
+ Secrets will be created in the active environment, or another one can be specified:
53
+
54
+ ```python notest
55
+ modal.Secret.objects.create("my-secret", contents, environment_name="dev")
56
+ ```
57
+
58
+ By default, an error will be raised if the Secret already exists, but passing
59
+ `allow_existing=True` will make the creation attempt a no-op in this case.
60
+ If the `env_dict` data differs from the existing Secret, it will be ignored.
61
+
62
+ ```python notest
63
+ modal.Secret.objects.create("my-secret", contents, allow_existing=True)
64
+ ```
65
+
66
+ Note that this method does not return a local instance of the Secret. You can use
67
+ `modal.Secret.from_name` to perform a lookup after creation.
68
+ """
69
+ ...
70
+
34
71
  @staticmethod
35
72
  async def list(
36
73
  *,
@@ -95,6 +132,85 @@ class SecretManager:
95
132
  """Initialize self. See help(type(self)) for accurate signature."""
96
133
  ...
97
134
 
135
+ class __create_spec(typing_extensions.Protocol):
136
+ def __call__(
137
+ self,
138
+ /,
139
+ name: str,
140
+ env_dict: dict[str, str],
141
+ *,
142
+ allow_existing: bool = False,
143
+ environment_name: typing.Optional[str] = None,
144
+ client: typing.Optional[modal.client.Client] = None,
145
+ ) -> None:
146
+ """Create a new Secret object.
147
+
148
+ **Examples:**
149
+
150
+ ```python notest
151
+ contents = {"MY_KEY": "my-value", "MY_OTHER_KEY": "my-other-value"}
152
+ modal.Secret.objects.create("my-secret", contents)
153
+ ```
154
+
155
+ Secrets will be created in the active environment, or another one can be specified:
156
+
157
+ ```python notest
158
+ modal.Secret.objects.create("my-secret", contents, environment_name="dev")
159
+ ```
160
+
161
+ By default, an error will be raised if the Secret already exists, but passing
162
+ `allow_existing=True` will make the creation attempt a no-op in this case.
163
+ If the `env_dict` data differs from the existing Secret, it will be ignored.
164
+
165
+ ```python notest
166
+ modal.Secret.objects.create("my-secret", contents, allow_existing=True)
167
+ ```
168
+
169
+ Note that this method does not return a local instance of the Secret. You can use
170
+ `modal.Secret.from_name` to perform a lookup after creation.
171
+ """
172
+ ...
173
+
174
+ async def aio(
175
+ self,
176
+ /,
177
+ name: str,
178
+ env_dict: dict[str, str],
179
+ *,
180
+ allow_existing: bool = False,
181
+ environment_name: typing.Optional[str] = None,
182
+ client: typing.Optional[modal.client.Client] = None,
183
+ ) -> None:
184
+ """Create a new Secret object.
185
+
186
+ **Examples:**
187
+
188
+ ```python notest
189
+ contents = {"MY_KEY": "my-value", "MY_OTHER_KEY": "my-other-value"}
190
+ modal.Secret.objects.create("my-secret", contents)
191
+ ```
192
+
193
+ Secrets will be created in the active environment, or another one can be specified:
194
+
195
+ ```python notest
196
+ modal.Secret.objects.create("my-secret", contents, environment_name="dev")
197
+ ```
198
+
199
+ By default, an error will be raised if the Secret already exists, but passing
200
+ `allow_existing=True` will make the creation attempt a no-op in this case.
201
+ If the `env_dict` data differs from the existing Secret, it will be ignored.
202
+
203
+ ```python notest
204
+ modal.Secret.objects.create("my-secret", contents, allow_existing=True)
205
+ ```
206
+
207
+ Note that this method does not return a local instance of the Secret. You can use
208
+ `modal.Secret.from_name` to perform a lookup after creation.
209
+ """
210
+ ...
211
+
212
+ create: __create_spec
213
+
98
214
  class __list_spec(typing_extensions.Protocol):
99
215
  def __call__(
100
216
  self,