modal 1.0.5.dev30__tar.gz → 1.0.5.dev32__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 (184) hide show
  1. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/PKG-INFO +1 -1
  2. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_functions.py +2 -0
  3. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/client.pyi +2 -2
  4. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/sandbox.py +1 -0
  5. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/volume.py +37 -0
  6. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/volume.pyi +44 -0
  7. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal.egg-info/PKG-INFO +1 -1
  8. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_version/__init__.py +1 -1
  9. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/LICENSE +0 -0
  10. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/README.md +0 -0
  11. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/__init__.py +0 -0
  12. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/__main__.py +0 -0
  13. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_clustered_functions.py +0 -0
  14. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_clustered_functions.pyi +0 -0
  15. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_container_entrypoint.py +0 -0
  16. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_ipython.py +0 -0
  17. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_location.py +0 -0
  18. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_object.py +0 -0
  19. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_output.py +0 -0
  20. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_partial_function.py +0 -0
  21. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_pty.py +0 -0
  22. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_resolver.py +0 -0
  23. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_resources.py +0 -0
  24. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_runtime/__init__.py +0 -0
  25. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_runtime/asgi.py +0 -0
  26. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_runtime/container_io_manager.py +0 -0
  27. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_runtime/container_io_manager.pyi +0 -0
  28. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_runtime/execution_context.py +0 -0
  29. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_runtime/execution_context.pyi +0 -0
  30. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  31. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_runtime/telemetry.py +0 -0
  32. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_runtime/user_code_imports.py +0 -0
  33. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_serialization.py +0 -0
  34. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_traceback.py +0 -0
  35. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_tunnel.py +0 -0
  36. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_tunnel.pyi +0 -0
  37. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_type_manager.py +0 -0
  38. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/__init__.py +0 -0
  39. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/app_utils.py +0 -0
  40. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/async_utils.py +0 -0
  41. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/blob_utils.py +0 -0
  42. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/bytes_io_segment_payload.py +0 -0
  43. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/deprecation.py +0 -0
  44. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/docker_utils.py +0 -0
  45. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/function_utils.py +0 -0
  46. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/git_utils.py +0 -0
  47. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/grpc_testing.py +0 -0
  48. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/grpc_utils.py +0 -0
  49. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/hash_utils.py +0 -0
  50. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/http_utils.py +0 -0
  51. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/jwt_utils.py +0 -0
  52. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/logger.py +0 -0
  53. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/mount_utils.py +0 -0
  54. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/name_utils.py +0 -0
  55. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/package_utils.py +0 -0
  56. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/pattern_utils.py +0 -0
  57. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/rand_pb_testing.py +0 -0
  58. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/shell_utils.py +0 -0
  59. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_utils/time_utils.py +0 -0
  60. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_vendor/__init__.py +0 -0
  61. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  62. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_vendor/cloudpickle.py +0 -0
  63. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_vendor/tblib.py +0 -0
  64. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/_watcher.py +0 -0
  65. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/app.py +0 -0
  66. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/app.pyi +0 -0
  67. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/call_graph.py +0 -0
  68. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/__init__.py +0 -0
  69. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/_download.py +0 -0
  70. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/_traceback.py +0 -0
  71. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/app.py +0 -0
  72. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/cluster.py +0 -0
  73. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/config.py +0 -0
  74. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/container.py +0 -0
  75. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/dict.py +0 -0
  76. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/entry_point.py +0 -0
  77. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/environment.py +0 -0
  78. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/import_refs.py +0 -0
  79. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/launch.py +0 -0
  80. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/network_file_system.py +0 -0
  81. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/profile.py +0 -0
  82. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/programs/__init__.py +0 -0
  83. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/programs/run_jupyter.py +0 -0
  84. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/programs/vscode.py +0 -0
  85. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/queues.py +0 -0
  86. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/run.py +0 -0
  87. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/secret.py +0 -0
  88. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/token.py +0 -0
  89. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/utils.py +0 -0
  90. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cli/volume.py +0 -0
  91. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/client.py +0 -0
  92. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cloud_bucket_mount.py +0 -0
  93. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cloud_bucket_mount.pyi +0 -0
  94. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cls.py +0 -0
  95. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/cls.pyi +0 -0
  96. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/config.py +0 -0
  97. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/container_process.py +0 -0
  98. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/container_process.pyi +0 -0
  99. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/dict.py +0 -0
  100. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/dict.pyi +0 -0
  101. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/environments.py +0 -0
  102. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/environments.pyi +0 -0
  103. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/exception.py +0 -0
  104. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/experimental/__init__.py +0 -0
  105. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/experimental/ipython.py +0 -0
  106. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/file_io.py +0 -0
  107. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/file_io.pyi +0 -0
  108. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/file_pattern_matcher.py +0 -0
  109. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/functions.py +0 -0
  110. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/functions.pyi +0 -0
  111. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/gpu.py +0 -0
  112. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/image.py +0 -0
  113. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/image.pyi +0 -0
  114. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/io_streams.py +0 -0
  115. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/io_streams.pyi +0 -0
  116. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/mount.py +0 -0
  117. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/mount.pyi +0 -0
  118. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/network_file_system.py +0 -0
  119. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/network_file_system.pyi +0 -0
  120. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/object.py +0 -0
  121. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/object.pyi +0 -0
  122. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/output.py +0 -0
  123. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/parallel_map.py +0 -0
  124. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/parallel_map.pyi +0 -0
  125. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/partial_function.py +0 -0
  126. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/partial_function.pyi +0 -0
  127. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/proxy.py +0 -0
  128. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/proxy.pyi +0 -0
  129. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/py.typed +0 -0
  130. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/queue.py +0 -0
  131. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/queue.pyi +0 -0
  132. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/requirements/2023.12.312.txt +0 -0
  133. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/requirements/2023.12.txt +0 -0
  134. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/requirements/2024.04.txt +0 -0
  135. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/requirements/2024.10.txt +0 -0
  136. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/requirements/PREVIEW.txt +0 -0
  137. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/requirements/README.md +0 -0
  138. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/requirements/base-images.json +0 -0
  139. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/retries.py +0 -0
  140. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/runner.py +0 -0
  141. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/runner.pyi +0 -0
  142. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/running_app.py +0 -0
  143. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/sandbox.pyi +0 -0
  144. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/schedule.py +0 -0
  145. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/scheduler_placement.py +0 -0
  146. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/secret.py +0 -0
  147. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/secret.pyi +0 -0
  148. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/serving.py +0 -0
  149. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/serving.pyi +0 -0
  150. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/snapshot.py +0 -0
  151. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/snapshot.pyi +0 -0
  152. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/stream_type.py +0 -0
  153. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/token_flow.py +0 -0
  154. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal/token_flow.pyi +0 -0
  155. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal.egg-info/SOURCES.txt +0 -0
  156. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal.egg-info/dependency_links.txt +0 -0
  157. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal.egg-info/entry_points.txt +0 -0
  158. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal.egg-info/requires.txt +0 -0
  159. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal.egg-info/top_level.txt +0 -0
  160. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_docs/__init__.py +0 -0
  161. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_docs/gen_cli_docs.py +0 -0
  162. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_docs/gen_reference_docs.py +0 -0
  163. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_docs/mdmd/__init__.py +0 -0
  164. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_docs/mdmd/mdmd.py +0 -0
  165. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_docs/mdmd/signatures.py +0 -0
  166. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/__init__.py +0 -0
  167. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/api.proto +0 -0
  168. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/api_grpc.py +0 -0
  169. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/api_pb2.py +0 -0
  170. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/api_pb2.pyi +0 -0
  171. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/api_pb2_grpc.py +0 -0
  172. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/api_pb2_grpc.pyi +0 -0
  173. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/modal_api_grpc.py +0 -0
  174. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/modal_options_grpc.py +0 -0
  175. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/options.proto +0 -0
  176. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/options_grpc.py +0 -0
  177. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/options_pb2.py +0 -0
  178. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/options_pb2.pyi +0 -0
  179. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/options_pb2_grpc.py +0 -0
  180. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/options_pb2_grpc.pyi +0 -0
  181. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_proto/py.typed +0 -0
  182. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/modal_version/__main__.py +0 -0
  183. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/pyproject.toml +0 -0
  184. {modal-1.0.5.dev30 → modal-1.0.5.dev32}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.5.dev30
3
+ Version: 1.0.5.dev32
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -854,6 +854,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
854
854
  mount_path=path,
855
855
  volume_id=volume.object_id,
856
856
  allow_background_commits=True,
857
+ read_only=volume._read_only,
857
858
  )
858
859
  for path, volume in validated_volumes_no_cloud_buckets
859
860
  ]
@@ -1107,6 +1108,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1107
1108
  mount_path=path,
1108
1109
  volume_id=volume.object_id,
1109
1110
  allow_background_commits=True,
1111
+ read_only=volume._read_only,
1110
1112
  )
1111
1113
  for path, volume in options.validated_volumes
1112
1114
  ]
@@ -31,7 +31,7 @@ class _Client:
31
31
  server_url: str,
32
32
  client_type: int,
33
33
  credentials: typing.Optional[tuple[str, str]],
34
- version: str = "1.0.5.dev30",
34
+ version: str = "1.0.5.dev32",
35
35
  ):
36
36
  """mdmd:hidden
37
37
  The Modal client object is not intended to be instantiated directly by users.
@@ -160,7 +160,7 @@ class Client:
160
160
  server_url: str,
161
161
  client_type: int,
162
162
  credentials: typing.Optional[tuple[str, str]],
163
- version: str = "1.0.5.dev30",
163
+ version: str = "1.0.5.dev32",
164
164
  ):
165
165
  """mdmd:hidden
166
166
  The Modal client object is not intended to be instantiated directly by users.
@@ -151,6 +151,7 @@ class _Sandbox(_Object, type_prefix="sb"):
151
151
  mount_path=path,
152
152
  volume_id=volume.object_id,
153
153
  allow_background_commits=True,
154
+ read_only=volume._read_only,
154
155
  )
155
156
  for path, volume in validated_volumes
156
157
  ]
@@ -135,6 +135,34 @@ class _Volume(_Object, type_prefix="vo"):
135
135
 
136
136
  _lock: Optional[asyncio.Lock] = None
137
137
  _metadata: "typing.Optional[api_pb2.VolumeMetadata]"
138
+ _read_only: bool = False
139
+
140
+ def read_only(self) -> "_Volume":
141
+ """Configure Volume to mount as read-only.
142
+
143
+ **Example**
144
+
145
+ ```python
146
+ import modal
147
+
148
+ volume = modal.Volume.from_name("my-volume", create_if_missing=True)
149
+
150
+ @app.function(volumes={"/mnt/items": volume.read_only()})
151
+ def f():
152
+ with open("/mnt/items/my-file.txt") as f:
153
+ return f.read()
154
+ ```
155
+
156
+ The Volume is mounted as a read-only volume in a function. Any file system write operation into the
157
+ mounted volume will result in an error.
158
+ """
159
+
160
+ async def _load(new_volume: _Volume, resolver: Resolver, existing_object_id: Optional[str]):
161
+ new_volume._initialize_from_other(self)
162
+ new_volume._read_only = True
163
+
164
+ obj = _Volume._from_loader(_load, "Volume()", hydrate_lazily=True, deps=lambda: [self])
165
+ return obj
138
166
 
139
167
  async def _get_lock(self):
140
168
  # To (mostly*) prevent multiple concurrent operations on the same volume, which can cause problems under
@@ -495,6 +523,9 @@ class _Volume(_Object, type_prefix="vo"):
495
523
  @live_method
496
524
  async def remove_file(self, path: str, recursive: bool = False) -> None:
497
525
  """Remove a file or directory from a volume."""
526
+ if self._read_only:
527
+ raise InvalidError("Read-only Volume can not be written to")
528
+
498
529
  if self._is_v1:
499
530
  req = api_pb2.VolumeRemoveFileRequest(volume_id=self.object_id, path=path, recursive=recursive)
500
531
  await retry_transient_errors(self._client.stub.VolumeRemoveFile, req)
@@ -527,6 +558,9 @@ class _Volume(_Object, type_prefix="vo"):
527
558
  like `os.rename()` and then `commit()` the volume. The `copy_files()` method is useful when you don't have
528
559
  the volume mounted as a filesystem, e.g. when running a script on your local computer.
529
560
  """
561
+ if self._read_only:
562
+ raise InvalidError("Read-only Volume can not be written to")
563
+
530
564
  if self._is_v1:
531
565
  if recursive:
532
566
  raise ValueError("`recursive` is not supported for V1 volumes")
@@ -560,6 +594,9 @@ class _Volume(_Object, type_prefix="vo"):
560
594
  batch.put_file(io.BytesIO(b"some data"), "/foobar")
561
595
  ```
562
596
  """
597
+ if self._read_only:
598
+ raise InvalidError("Read-only Volume can not be written to")
599
+
563
600
  return _AbstractVolumeUploadContextManager.resolve(
564
601
  self._metadata.version, self.object_id, self._client, force=force
565
602
  )
@@ -101,6 +101,28 @@ class _Volume(modal._object._Object):
101
101
 
102
102
  _lock: typing.Optional[asyncio.locks.Lock]
103
103
  _metadata: typing.Optional[modal_proto.api_pb2.VolumeMetadata]
104
+ _read_only: bool
105
+
106
+ def read_only(self) -> _Volume:
107
+ """Configure Volume to mount as read-only.
108
+
109
+ **Example**
110
+
111
+ ```python
112
+ import modal
113
+
114
+ volume = modal.Volume.from_name("my-volume", create_if_missing=True)
115
+
116
+ @app.function(volumes={"/mnt/items": volume.read_only()})
117
+ def f():
118
+ with open("/mnt/items/my-file.txt") as f:
119
+ return f.read()
120
+ ```
121
+
122
+ The Volume is mounted as a read-only volume in a function. Any file system write operation into the
123
+ mounted volume will result in an error.
124
+ """
125
+ ...
104
126
 
105
127
  async def _get_lock(self): ...
106
128
  @staticmethod
@@ -371,11 +393,33 @@ class Volume(modal.object.Object):
371
393
 
372
394
  _lock: typing.Optional[asyncio.locks.Lock]
373
395
  _metadata: typing.Optional[modal_proto.api_pb2.VolumeMetadata]
396
+ _read_only: bool
374
397
 
375
398
  def __init__(self, *args, **kwargs):
376
399
  """mdmd:hidden"""
377
400
  ...
378
401
 
402
+ def read_only(self) -> Volume:
403
+ """Configure Volume to mount as read-only.
404
+
405
+ **Example**
406
+
407
+ ```python
408
+ import modal
409
+
410
+ volume = modal.Volume.from_name("my-volume", create_if_missing=True)
411
+
412
+ @app.function(volumes={"/mnt/items": volume.read_only()})
413
+ def f():
414
+ with open("/mnt/items/my-file.txt") as f:
415
+ return f.read()
416
+ ```
417
+
418
+ The Volume is mounted as a read-only volume in a function. Any file system write operation into the
419
+ mounted volume will result in an error.
420
+ """
421
+ ...
422
+
379
423
  class ___get_lock_spec(typing_extensions.Protocol[SUPERSELF]):
380
424
  def __call__(self, /): ...
381
425
  async def aio(self, /): ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.5.dev30
3
+ Version: 1.0.5.dev32
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.0.5.dev30"
4
+ __version__ = "1.0.5.dev32"
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