modAL 1.0.4__tar.gz → 1.0.4.dev2__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.4 → modal-1.0.4.dev2}/PKG-INFO +2 -2
  2. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_partial_function.py +4 -4
  3. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/async_utils.py +16 -45
  4. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/network_file_system.py +0 -3
  5. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/run.py +0 -7
  6. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/volume.py +0 -2
  7. {modal-1.0.4 → modal-1.0.4.dev2}/modal/client.pyi +10 -2
  8. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cls.py +9 -50
  9. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cls.pyi +0 -1
  10. {modal-1.0.4 → modal-1.0.4.dev2}/modal/file_io.py +7 -9
  11. {modal-1.0.4 → modal-1.0.4.dev2}/modal/file_io.pyi +8 -5
  12. {modal-1.0.4 → modal-1.0.4.dev2}/modal/sandbox.py +0 -7
  13. {modal-1.0.4 → modal-1.0.4.dev2}/modal/sandbox.pyi +0 -8
  14. {modal-1.0.4 → modal-1.0.4.dev2}/modal/volume.py +0 -5
  15. {modal-1.0.4 → modal-1.0.4.dev2}/modal.egg-info/PKG-INFO +2 -2
  16. {modal-1.0.4 → modal-1.0.4.dev2}/modal.egg-info/requires.txt +1 -1
  17. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/api.proto +0 -4
  18. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/api_pb2.py +300 -300
  19. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/api_pb2.pyi +2 -9
  20. {modal-1.0.4 → modal-1.0.4.dev2}/modal_version/__init__.py +1 -1
  21. {modal-1.0.4 → modal-1.0.4.dev2}/pyproject.toml +1 -1
  22. {modal-1.0.4 → modal-1.0.4.dev2}/LICENSE +0 -0
  23. {modal-1.0.4 → modal-1.0.4.dev2}/README.md +0 -0
  24. {modal-1.0.4 → modal-1.0.4.dev2}/modal/__init__.py +0 -0
  25. {modal-1.0.4 → modal-1.0.4.dev2}/modal/__main__.py +0 -0
  26. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_clustered_functions.py +0 -0
  27. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_clustered_functions.pyi +0 -0
  28. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_container_entrypoint.py +0 -0
  29. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_functions.py +0 -0
  30. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_ipython.py +0 -0
  31. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_location.py +0 -0
  32. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_object.py +0 -0
  33. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_output.py +0 -0
  34. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_pty.py +0 -0
  35. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_resolver.py +0 -0
  36. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_resources.py +0 -0
  37. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_runtime/__init__.py +0 -0
  38. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_runtime/asgi.py +0 -0
  39. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_runtime/container_io_manager.py +0 -0
  40. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_runtime/container_io_manager.pyi +0 -0
  41. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_runtime/execution_context.py +0 -0
  42. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_runtime/execution_context.pyi +0 -0
  43. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  44. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_runtime/telemetry.py +0 -0
  45. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_runtime/user_code_imports.py +0 -0
  46. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_serialization.py +0 -0
  47. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_traceback.py +0 -0
  48. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_tunnel.py +0 -0
  49. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_tunnel.pyi +0 -0
  50. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_type_manager.py +0 -0
  51. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/__init__.py +0 -0
  52. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/app_utils.py +0 -0
  53. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/blob_utils.py +0 -0
  54. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/bytes_io_segment_payload.py +0 -0
  55. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/deprecation.py +0 -0
  56. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/docker_utils.py +0 -0
  57. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/function_utils.py +0 -0
  58. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/git_utils.py +0 -0
  59. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/grpc_testing.py +0 -0
  60. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/grpc_utils.py +0 -0
  61. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/hash_utils.py +0 -0
  62. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/http_utils.py +0 -0
  63. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/jwt_utils.py +0 -0
  64. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/logger.py +0 -0
  65. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/mount_utils.py +0 -0
  66. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/name_utils.py +0 -0
  67. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/package_utils.py +0 -0
  68. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/pattern_utils.py +0 -0
  69. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/rand_pb_testing.py +0 -0
  70. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/shell_utils.py +0 -0
  71. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_utils/time_utils.py +0 -0
  72. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_vendor/__init__.py +0 -0
  73. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  74. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_vendor/cloudpickle.py +0 -0
  75. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_vendor/tblib.py +0 -0
  76. {modal-1.0.4 → modal-1.0.4.dev2}/modal/_watcher.py +0 -0
  77. {modal-1.0.4 → modal-1.0.4.dev2}/modal/app.py +0 -0
  78. {modal-1.0.4 → modal-1.0.4.dev2}/modal/app.pyi +0 -0
  79. {modal-1.0.4 → modal-1.0.4.dev2}/modal/call_graph.py +0 -0
  80. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/__init__.py +0 -0
  81. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/_download.py +0 -0
  82. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/_traceback.py +0 -0
  83. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/app.py +0 -0
  84. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/cluster.py +0 -0
  85. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/config.py +0 -0
  86. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/container.py +0 -0
  87. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/dict.py +0 -0
  88. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/entry_point.py +0 -0
  89. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/environment.py +0 -0
  90. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/import_refs.py +0 -0
  91. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/launch.py +0 -0
  92. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/profile.py +0 -0
  93. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/programs/__init__.py +0 -0
  94. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/programs/run_jupyter.py +0 -0
  95. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/programs/vscode.py +0 -0
  96. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/queues.py +0 -0
  97. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/secret.py +0 -0
  98. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/token.py +0 -0
  99. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cli/utils.py +0 -0
  100. {modal-1.0.4 → modal-1.0.4.dev2}/modal/client.py +0 -0
  101. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cloud_bucket_mount.py +0 -0
  102. {modal-1.0.4 → modal-1.0.4.dev2}/modal/cloud_bucket_mount.pyi +0 -0
  103. {modal-1.0.4 → modal-1.0.4.dev2}/modal/config.py +0 -0
  104. {modal-1.0.4 → modal-1.0.4.dev2}/modal/container_process.py +0 -0
  105. {modal-1.0.4 → modal-1.0.4.dev2}/modal/container_process.pyi +0 -0
  106. {modal-1.0.4 → modal-1.0.4.dev2}/modal/dict.py +0 -0
  107. {modal-1.0.4 → modal-1.0.4.dev2}/modal/dict.pyi +0 -0
  108. {modal-1.0.4 → modal-1.0.4.dev2}/modal/environments.py +0 -0
  109. {modal-1.0.4 → modal-1.0.4.dev2}/modal/environments.pyi +0 -0
  110. {modal-1.0.4 → modal-1.0.4.dev2}/modal/exception.py +0 -0
  111. {modal-1.0.4 → modal-1.0.4.dev2}/modal/experimental/__init__.py +0 -0
  112. {modal-1.0.4 → modal-1.0.4.dev2}/modal/experimental/ipython.py +0 -0
  113. {modal-1.0.4 → modal-1.0.4.dev2}/modal/file_pattern_matcher.py +0 -0
  114. {modal-1.0.4 → modal-1.0.4.dev2}/modal/functions.py +0 -0
  115. {modal-1.0.4 → modal-1.0.4.dev2}/modal/functions.pyi +0 -0
  116. {modal-1.0.4 → modal-1.0.4.dev2}/modal/gpu.py +0 -0
  117. {modal-1.0.4 → modal-1.0.4.dev2}/modal/image.py +0 -0
  118. {modal-1.0.4 → modal-1.0.4.dev2}/modal/image.pyi +0 -0
  119. {modal-1.0.4 → modal-1.0.4.dev2}/modal/io_streams.py +0 -0
  120. {modal-1.0.4 → modal-1.0.4.dev2}/modal/io_streams.pyi +0 -0
  121. {modal-1.0.4 → modal-1.0.4.dev2}/modal/mount.py +0 -0
  122. {modal-1.0.4 → modal-1.0.4.dev2}/modal/mount.pyi +0 -0
  123. {modal-1.0.4 → modal-1.0.4.dev2}/modal/network_file_system.py +0 -0
  124. {modal-1.0.4 → modal-1.0.4.dev2}/modal/network_file_system.pyi +0 -0
  125. {modal-1.0.4 → modal-1.0.4.dev2}/modal/object.py +0 -0
  126. {modal-1.0.4 → modal-1.0.4.dev2}/modal/object.pyi +0 -0
  127. {modal-1.0.4 → modal-1.0.4.dev2}/modal/output.py +0 -0
  128. {modal-1.0.4 → modal-1.0.4.dev2}/modal/parallel_map.py +0 -0
  129. {modal-1.0.4 → modal-1.0.4.dev2}/modal/parallel_map.pyi +0 -0
  130. {modal-1.0.4 → modal-1.0.4.dev2}/modal/partial_function.py +0 -0
  131. {modal-1.0.4 → modal-1.0.4.dev2}/modal/partial_function.pyi +0 -0
  132. {modal-1.0.4 → modal-1.0.4.dev2}/modal/proxy.py +0 -0
  133. {modal-1.0.4 → modal-1.0.4.dev2}/modal/proxy.pyi +0 -0
  134. {modal-1.0.4 → modal-1.0.4.dev2}/modal/py.typed +0 -0
  135. {modal-1.0.4 → modal-1.0.4.dev2}/modal/queue.py +0 -0
  136. {modal-1.0.4 → modal-1.0.4.dev2}/modal/queue.pyi +0 -0
  137. {modal-1.0.4 → modal-1.0.4.dev2}/modal/requirements/2023.12.312.txt +0 -0
  138. {modal-1.0.4 → modal-1.0.4.dev2}/modal/requirements/2023.12.txt +0 -0
  139. {modal-1.0.4 → modal-1.0.4.dev2}/modal/requirements/2024.04.txt +0 -0
  140. {modal-1.0.4 → modal-1.0.4.dev2}/modal/requirements/2024.10.txt +0 -0
  141. {modal-1.0.4 → modal-1.0.4.dev2}/modal/requirements/PREVIEW.txt +0 -0
  142. {modal-1.0.4 → modal-1.0.4.dev2}/modal/requirements/README.md +0 -0
  143. {modal-1.0.4 → modal-1.0.4.dev2}/modal/requirements/base-images.json +0 -0
  144. {modal-1.0.4 → modal-1.0.4.dev2}/modal/retries.py +0 -0
  145. {modal-1.0.4 → modal-1.0.4.dev2}/modal/runner.py +0 -0
  146. {modal-1.0.4 → modal-1.0.4.dev2}/modal/runner.pyi +0 -0
  147. {modal-1.0.4 → modal-1.0.4.dev2}/modal/running_app.py +0 -0
  148. {modal-1.0.4 → modal-1.0.4.dev2}/modal/schedule.py +0 -0
  149. {modal-1.0.4 → modal-1.0.4.dev2}/modal/scheduler_placement.py +0 -0
  150. {modal-1.0.4 → modal-1.0.4.dev2}/modal/secret.py +0 -0
  151. {modal-1.0.4 → modal-1.0.4.dev2}/modal/secret.pyi +0 -0
  152. {modal-1.0.4 → modal-1.0.4.dev2}/modal/serving.py +0 -0
  153. {modal-1.0.4 → modal-1.0.4.dev2}/modal/serving.pyi +0 -0
  154. {modal-1.0.4 → modal-1.0.4.dev2}/modal/snapshot.py +0 -0
  155. {modal-1.0.4 → modal-1.0.4.dev2}/modal/snapshot.pyi +0 -0
  156. {modal-1.0.4 → modal-1.0.4.dev2}/modal/stream_type.py +0 -0
  157. {modal-1.0.4 → modal-1.0.4.dev2}/modal/token_flow.py +0 -0
  158. {modal-1.0.4 → modal-1.0.4.dev2}/modal/token_flow.pyi +0 -0
  159. {modal-1.0.4 → modal-1.0.4.dev2}/modal/volume.pyi +0 -0
  160. {modal-1.0.4 → modal-1.0.4.dev2}/modal.egg-info/SOURCES.txt +0 -0
  161. {modal-1.0.4 → modal-1.0.4.dev2}/modal.egg-info/dependency_links.txt +0 -0
  162. {modal-1.0.4 → modal-1.0.4.dev2}/modal.egg-info/entry_points.txt +0 -0
  163. {modal-1.0.4 → modal-1.0.4.dev2}/modal.egg-info/top_level.txt +0 -0
  164. {modal-1.0.4 → modal-1.0.4.dev2}/modal_docs/__init__.py +0 -0
  165. {modal-1.0.4 → modal-1.0.4.dev2}/modal_docs/gen_cli_docs.py +0 -0
  166. {modal-1.0.4 → modal-1.0.4.dev2}/modal_docs/gen_reference_docs.py +0 -0
  167. {modal-1.0.4 → modal-1.0.4.dev2}/modal_docs/mdmd/__init__.py +0 -0
  168. {modal-1.0.4 → modal-1.0.4.dev2}/modal_docs/mdmd/mdmd.py +0 -0
  169. {modal-1.0.4 → modal-1.0.4.dev2}/modal_docs/mdmd/signatures.py +0 -0
  170. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/__init__.py +0 -0
  171. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/api_grpc.py +0 -0
  172. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/api_pb2_grpc.py +0 -0
  173. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/api_pb2_grpc.pyi +0 -0
  174. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/modal_api_grpc.py +0 -0
  175. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/modal_options_grpc.py +0 -0
  176. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/options.proto +0 -0
  177. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/options_grpc.py +0 -0
  178. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/options_pb2.py +0 -0
  179. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/options_pb2.pyi +0 -0
  180. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/options_pb2_grpc.py +0 -0
  181. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/options_pb2_grpc.pyi +0 -0
  182. {modal-1.0.4 → modal-1.0.4.dev2}/modal_proto/py.typed +0 -0
  183. {modal-1.0.4 → modal-1.0.4.dev2}/modal_version/__main__.py +0 -0
  184. {modal-1.0.4 → modal-1.0.4.dev2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.4
3
+ Version: 1.0.4.dev2
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -22,7 +22,7 @@ Requires-Dist: click~=8.1.0
22
22
  Requires-Dist: grpclib==0.4.7
23
23
  Requires-Dist: protobuf!=4.24.0,<7.0,>=3.19
24
24
  Requires-Dist: rich>=12.0.0
25
- Requires-Dist: synchronicity~=0.9.15
25
+ Requires-Dist: synchronicity~=0.9.13
26
26
  Requires-Dist: toml
27
27
  Requires-Dist: typer>=0.9
28
28
  Requires-Dist: types-certifi
@@ -789,12 +789,12 @@ def _batched(
789
789
  )
790
790
  if max_batch_size < 1:
791
791
  raise InvalidError("max_batch_size must be a positive integer.")
792
- if max_batch_size > MAX_MAX_BATCH_SIZE:
793
- raise InvalidError(f"max_batch_size cannot be greater than {MAX_MAX_BATCH_SIZE}.")
792
+ if max_batch_size >= MAX_MAX_BATCH_SIZE:
793
+ raise InvalidError(f"max_batch_size must be less than {MAX_MAX_BATCH_SIZE}.")
794
794
  if wait_ms < 0:
795
795
  raise InvalidError("wait_ms must be a non-negative integer.")
796
- if wait_ms > MAX_BATCH_WAIT_MS:
797
- raise InvalidError(f"wait_ms cannot be greater than {MAX_BATCH_WAIT_MS}.")
796
+ if wait_ms >= MAX_BATCH_WAIT_MS:
797
+ raise InvalidError(f"wait_ms must be less than {MAX_BATCH_WAIT_MS}.")
798
798
 
799
799
  flags = _PartialFunctionFlags.CALLABLE_INTERFACE | _PartialFunctionFlags.BATCHED
800
800
  params = _PartialFunctionParams(batch_max_size=max_batch_size, batch_wait_ms=wait_ms)
@@ -647,9 +647,7 @@ class StopSentinelType: ...
647
647
  STOP_SENTINEL = StopSentinelType()
648
648
 
649
649
 
650
- async def async_merge(
651
- *generators: AsyncGenerator[T, None], cancellation_timeout: float = 10.0
652
- ) -> AsyncGenerator[T, None]:
650
+ async def async_merge(*generators: AsyncGenerator[T, None]) -> AsyncGenerator[T, None]:
653
651
  """
654
652
  Asynchronously merges multiple async generators into a single async generator.
655
653
 
@@ -694,9 +692,8 @@ async def async_merge(
694
692
 
695
693
  async def producer(generator: AsyncGenerator[T, None]):
696
694
  try:
697
- async with aclosing(generator) as stream:
698
- async for item in stream:
699
- await queue.put(ValueWrapper(item))
695
+ async for item in generator:
696
+ await queue.put(ValueWrapper(item))
700
697
  except Exception as e:
701
698
  await queue.put(ExceptionWrapper(e))
702
699
 
@@ -738,20 +735,15 @@ async def async_merge(
738
735
  new_output_task = asyncio.create_task(queue.get())
739
736
 
740
737
  finally:
741
- unfinished_tasks = [t for t in tasks | {new_output_task} if not t.done()]
742
- for t in unfinished_tasks:
743
- t.cancel()
744
- try:
745
- await asyncio.wait_for(
746
- asyncio.shield(
747
- # we need to `shield` the `gather` to ensure cooperation with the timeout
748
- # all underlying tasks have been marked as cancelled at this point anyway
749
- asyncio.gather(*unfinished_tasks, return_exceptions=True)
750
- ),
751
- timeout=cancellation_timeout,
752
- )
753
- except asyncio.TimeoutError:
754
- logger.debug("Timed out while cleaning up async_merge")
738
+ if not new_output_task.done():
739
+ new_output_task.cancel()
740
+ for task in tasks:
741
+ if not task.done():
742
+ try:
743
+ task.cancel()
744
+ await task
745
+ except asyncio.CancelledError:
746
+ pass
755
747
 
756
748
 
757
749
  async def callable_to_agen(awaitable: Callable[[], Awaitable[T]]) -> AsyncGenerator[T, None]:
@@ -769,34 +761,16 @@ async def gather_cancel_on_exc(*coros_or_futures):
769
761
  raise
770
762
 
771
763
 
772
- async def prevent_cancellation_abortion(coro):
773
- # if this is cancelled, it will wait for coro cancellation handling
774
- # and then unconditionally re-raises a CancelledError, even if the underlying coro
775
- # doesn't re-raise the cancellation itself
776
- t = asyncio.create_task(coro)
777
- try:
778
- return await asyncio.shield(t)
779
- except asyncio.CancelledError:
780
- if t.cancelled():
781
- # coro cancelled itself - reraise
782
- raise
783
- t.cancel() # cancel task
784
- await t # this *normally* reraises
785
- raise # if the above somehow resolved, by swallowing cancellation - we still raise
786
-
787
-
788
764
  async def async_map(
789
765
  input_generator: AsyncGenerator[T, None],
790
766
  async_mapper_func: Callable[[T], Awaitable[V]],
791
767
  concurrency: int,
792
- cancellation_timeout: float = 10.0,
793
768
  ) -> AsyncGenerator[V, None]:
794
769
  queue: asyncio.Queue[Union[ValueWrapper[T], StopSentinelType]] = asyncio.Queue(maxsize=concurrency * 2)
795
770
 
796
771
  async def producer() -> AsyncGenerator[V, None]:
797
- async with aclosing(input_generator) as stream:
798
- async for item in stream:
799
- await queue.put(ValueWrapper(item))
772
+ async for item in input_generator:
773
+ await queue.put(ValueWrapper(item))
800
774
 
801
775
  for _ in range(concurrency):
802
776
  await queue.put(STOP_SENTINEL)
@@ -810,17 +784,14 @@ async def async_map(
810
784
  while True:
811
785
  item = await queue.get()
812
786
  if isinstance(item, ValueWrapper):
813
- res = await prevent_cancellation_abortion(async_mapper_func(item.value))
814
- yield res
787
+ yield await async_mapper_func(item.value)
815
788
  elif isinstance(item, ExceptionWrapper):
816
789
  raise item.value
817
790
  else:
818
791
  assert_type(item, StopSentinelType)
819
792
  break
820
793
 
821
- async with aclosing(
822
- async_merge(*[worker() for i in range(concurrency)], producer(), cancellation_timeout=cancellation_timeout)
823
- ) as stream:
794
+ async with aclosing(async_merge(*[worker() for _ in range(concurrency)], producer())) as stream:
824
795
  async for item in stream:
825
796
  yield item
826
797
 
@@ -203,11 +203,8 @@ async def rm(
203
203
  ):
204
204
  ensure_env(env)
205
205
  volume = _NetworkFileSystem.from_name(volume_name)
206
- console = Console()
207
206
  try:
208
207
  await volume.remove_file(remote_path, recursive=recursive)
209
- console.print(OutputManager.step_completed(f"{remote_path} was deleted successfully!"))
210
-
211
208
  except GRPCError as exc:
212
209
  if exc.status in (Status.NOT_FOUND, Status.INVALID_ARGUMENT):
213
210
  raise UsageError(exc.message)
@@ -27,7 +27,6 @@ from ..functions import Function
27
27
  from ..image import Image
28
28
  from ..output import enable_output
29
29
  from ..runner import deploy_app, interactive_shell, run_app
30
- from ..secret import Secret
31
30
  from ..serving import serve_app
32
31
  from ..volume import Volume
33
32
  from .import_refs import (
@@ -532,10 +531,6 @@ def shell(
532
531
  " Can be used multiple times."
533
532
  ),
534
533
  ),
535
- secret: Optional[list[str]] = typer.Option(
536
- default=None,
537
- help=("Name of a `modal.Secret` to mount inside the shell (if not using REF). Can be used multiple times."),
538
- ),
539
534
  cpu: Optional[int] = typer.Option(default=None, help="Number of CPUs to allocate to the shell (if not using REF)."),
540
535
  memory: Optional[int] = typer.Option(
541
536
  default=None, help="Memory to allocate for the shell, in MiB (if not using REF)."
@@ -665,7 +660,6 @@ def shell(
665
660
  else:
666
661
  modal_image = Image.from_registry(image, add_python=add_python) if image else None
667
662
  volumes = {} if volume is None else {f"/mnt/{vol}": Volume.from_name(vol) for vol in volume}
668
- secrets = [] if secret is None else [Secret.from_name(s) for s in secret]
669
663
  start_shell = partial(
670
664
  interactive_shell,
671
665
  image=modal_image,
@@ -674,7 +668,6 @@ def shell(
674
668
  gpu=gpu,
675
669
  cloud=cloud,
676
670
  volumes=volumes,
677
- secrets=secrets,
678
671
  region=region.split(",") if region else [],
679
672
  pty=pty,
680
673
  )
@@ -245,10 +245,8 @@ async def rm(
245
245
  ):
246
246
  ensure_env(env)
247
247
  volume = _Volume.from_name(volume_name, environment_name=env)
248
- console = Console()
249
248
  try:
250
249
  await volume.remove_file(remote_path, recursive=recursive)
251
- console.print(OutputManager.step_completed(f"{remote_path} was deleted successfully!"))
252
250
  except GRPCError as exc:
253
251
  if exc.status in (Status.NOT_FOUND, Status.INVALID_ARGUMENT):
254
252
  raise UsageError(exc.message)
@@ -27,7 +27,11 @@ class _Client:
27
27
  _snapshotted: bool
28
28
 
29
29
  def __init__(
30
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "1.0.4"
30
+ self,
31
+ server_url: str,
32
+ client_type: int,
33
+ credentials: typing.Optional[tuple[str, str]],
34
+ version: str = "1.0.4.dev2",
31
35
  ): ...
32
36
  def is_closed(self) -> bool: ...
33
37
  @property
@@ -86,7 +90,11 @@ class Client:
86
90
  _snapshotted: bool
87
91
 
88
92
  def __init__(
89
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "1.0.4"
93
+ self,
94
+ server_url: str,
95
+ client_type: int,
96
+ credentials: typing.Optional[tuple[str, str]],
97
+ version: str = "1.0.4.dev2",
90
98
  ): ...
91
99
  def is_closed(self) -> bool: ...
92
100
  @property
@@ -75,7 +75,6 @@ def _get_class_constructor_signature(user_cls: type) -> inspect.Signature:
75
75
 
76
76
  @dataclasses.dataclass()
77
77
  class _ServiceOptions:
78
- # Note that default values should always be "untruthy" so we can detect when they are not set
79
78
  secrets: typing.Collection[_Secret] = ()
80
79
  validated_volumes: typing.Sequence[tuple[str, _Volume]] = ()
81
80
  resources: Optional[api_pb2.Resources] = None
@@ -89,25 +88,6 @@ class _ServiceOptions:
89
88
  batch_max_size: Optional[int] = None
90
89
  batch_wait_ms: Optional[int] = None
91
90
 
92
- def merge_options(self, new_options: "_ServiceOptions") -> "_ServiceOptions":
93
- """Implement protobuf-like MergeFrom semantics for this dataclass.
94
-
95
- This mostly exists to support "stacking" of `.with_options()` calls.
96
- """
97
- new_options_dict = dataclasses.asdict(new_options)
98
-
99
- # Resources needs special merge handling because individual fields are parameters in the public API
100
- merged_resources = api_pb2.Resources()
101
- if self.resources:
102
- merged_resources.MergeFrom(self.resources)
103
- if new_resources := new_options_dict.pop("resources"):
104
- merged_resources.MergeFrom(new_resources)
105
- self.resources = merged_resources
106
-
107
- for key, value in new_options_dict.items():
108
- if value: # Only overwrite data when the value was set in the new options
109
- setattr(self, key, value)
110
-
111
91
 
112
92
  def _bind_instance_method(cls: "_Cls", service_function: _Function, method_name: str):
113
93
  """Binds an "instance service function" to a specific method using metadata for that method
@@ -684,32 +664,15 @@ More information on class parameterization can be found here: https://modal.com/
684
664
  container_idle_timeout: Optional[int] = None, # Now called `scaledown_window`
685
665
  allow_concurrent_inputs: Optional[int] = None, # See `.with_concurrency`
686
666
  ) -> "_Cls":
687
- """Override the static Function configuration at runtime.
688
-
689
- This method will return a new instance of the cls that will autoscale independently of the
690
- original instance. Note that options cannot be "unset" with this method (i.e., if a GPU
691
- is configured in the `@app.cls()` decorator, passing `gpu=None` here will not create a
692
- CPU-only instance).
667
+ """Create an instance of the Cls with configuration options overridden with new values.
693
668
 
694
669
  **Usage:**
695
670
 
696
- You can use this method after looking up the Cls from a deployed App or if you have a
697
- direct reference to a Cls from another Function or local entrypoint on its App:
698
-
699
671
  ```python notest
700
672
  Model = modal.Cls.from_name("my_app", "Model")
701
673
  ModelUsingGPU = Model.with_options(gpu="A100")
702
- ModelUsingGPU().generate.remote(input_prompt) # Run with an A100 GPU
674
+ ModelUsingGPU().generate.remote(42) # will run with an A100 GPU
703
675
  ```
704
-
705
- The method can be called multiple times to "stack" updates:
706
-
707
- ```python notest
708
- Model.with_options(gpu="A100").with_options(scaledown_window=300) # Use an A100 with slow scaledown
709
- ```
710
-
711
- Note that container arguments (i.e. `volumes` and `secrets`) passed in subsequent calls
712
- will not be merged.
713
676
  """
714
677
  retry_policy = _parse_retries(retries, f"Class {self.__name__}" if self._user_cls else "")
715
678
  if gpu or cpu or memory:
@@ -742,23 +705,21 @@ More information on class parameterization can be found here: https://modal.com/
742
705
 
743
706
  cls = _Cls._from_loader(_load_from_base, rep=f"{self._name}.with_options(...)", is_another_app=True, deps=_deps)
744
707
  cls._initialize_from_other(self)
745
-
746
- new_options = _ServiceOptions(
708
+ cls._options = dataclasses.replace(
709
+ cls._options,
747
710
  secrets=secrets,
748
- validated_volumes=validate_volumes(volumes),
749
711
  resources=resources,
750
712
  retry_policy=retry_policy,
751
713
  max_containers=max_containers,
752
714
  buffer_containers=buffer_containers,
753
715
  scaledown_window=scaledown_window,
754
716
  timeout_secs=timeout,
717
+ validated_volumes=validate_volumes(volumes),
755
718
  # Note: set both for backwards / forwards compatibility
756
719
  # But going forward `.with_concurrency` is the preferred method with distinct parameterization
757
720
  max_concurrent_inputs=allow_concurrent_inputs,
758
721
  target_concurrent_inputs=allow_concurrent_inputs,
759
722
  )
760
-
761
- cls._options.merge_options(new_options)
762
723
  return cls
763
724
 
764
725
  def with_concurrency(self: "_Cls", *, max_inputs: int, target_inputs: Optional[int] = None) -> "_Cls":
@@ -785,9 +746,9 @@ More information on class parameterization can be found here: https://modal.com/
785
746
  _load_from_base, rep=f"{self._name}.with_concurrency(...)", is_another_app=True, deps=_deps
786
747
  )
787
748
  cls._initialize_from_other(self)
788
-
789
- concurrency_options = _ServiceOptions(max_concurrent_inputs=max_inputs, target_concurrent_inputs=target_inputs)
790
- cls._options.merge_options(concurrency_options)
749
+ cls._options = dataclasses.replace(
750
+ cls._options, max_concurrent_inputs=max_inputs, target_concurrent_inputs=target_inputs
751
+ )
791
752
  return cls
792
753
 
793
754
  def with_batching(self: "_Cls", *, max_batch_size: int, wait_ms: int) -> "_Cls":
@@ -814,9 +775,7 @@ More information on class parameterization can be found here: https://modal.com/
814
775
  _load_from_base, rep=f"{self._name}.with_concurrency(...)", is_another_app=True, deps=_deps
815
776
  )
816
777
  cls._initialize_from_other(self)
817
-
818
- batching_options = _ServiceOptions(batch_max_size=max_batch_size, batch_wait_ms=wait_ms)
819
- cls._options.merge_options(batching_options)
778
+ cls._options = dataclasses.replace(cls._options, batch_max_size=max_batch_size, batch_wait_ms=wait_ms)
820
779
  return cls
821
780
 
822
781
  @staticmethod
@@ -37,7 +37,6 @@ class _ServiceOptions:
37
37
  batch_max_size: typing.Optional[int]
38
38
  batch_wait_ms: typing.Optional[int]
39
39
 
40
- def merge_options(self, new_options: _ServiceOptions) -> _ServiceOptions: ...
41
40
  def __init__(
42
41
  self,
43
42
  secrets: typing.Collection[modal.secret._Secret] = (),
@@ -144,12 +144,11 @@ class _FileIO(Generic[T]):
144
144
  _task_id: str = ""
145
145
  _file_descriptor: str = ""
146
146
  _client: _Client
147
- _watch_output_buffer: list[Union[Optional[bytes],Exception]] = []
147
+ _watch_output_buffer: list[Optional[bytes]] = []
148
148
 
149
149
  def __init__(self, client: _Client, task_id: str) -> None:
150
150
  self._client = client
151
151
  self._task_id = task_id
152
- self._watch_output_buffer = []
153
152
 
154
153
  def _validate_mode(self, mode: str) -> None:
155
154
  if not any(char in mode for char in "rwax"):
@@ -174,7 +173,11 @@ class _FileIO(Generic[T]):
174
173
  raise ValueError(f"Invalid file mode: {mode}")
175
174
  seen_chars.add(char)
176
175
 
177
- async def _consume_output(self, exec_id: str) -> AsyncIterator[Union[Optional[bytes], Exception]]:
176
+ def _handle_error(self, error: api_pb2.SystemErrorMessage) -> None:
177
+ error_class = ERROR_MAPPING.get(error.error_code, FilesystemExecutionError)
178
+ raise error_class(error.error_message)
179
+
180
+ async def _consume_output(self, exec_id: str) -> AsyncIterator[Optional[bytes]]:
178
181
  req = api_pb2.ContainerFilesystemExecGetOutputRequest(
179
182
  exec_id=exec_id,
180
183
  timeout=55,
@@ -184,8 +187,7 @@ class _FileIO(Generic[T]):
184
187
  yield None
185
188
  break
186
189
  if batch.HasField("error"):
187
- error_class = ERROR_MAPPING.get(batch.error.error_code, FilesystemExecutionError)
188
- yield error_class(batch.error.error_message)
190
+ self._handle_error(batch.error)
189
191
  for message in batch.output:
190
192
  yield message
191
193
 
@@ -234,8 +236,6 @@ class _FileIO(Generic[T]):
234
236
  if data is None:
235
237
  completed = True
236
238
  break
237
- if isinstance(data, Exception):
238
- raise data
239
239
  output += data
240
240
  except (GRPCError, StreamTerminatedError) as exc:
241
241
  if retries_remaining > 0:
@@ -475,8 +475,6 @@ class _FileIO(Generic[T]):
475
475
  item = self._watch_output_buffer.pop(0)
476
476
  if item is None:
477
477
  break
478
- if isinstance(item, Exception):
479
- raise item
480
478
  buffer += item
481
479
  # a single event may be split across multiple messages
482
480
  # the end of an event is marked by two newlines
@@ -1,6 +1,7 @@
1
1
  import _typeshed
2
2
  import enum
3
3
  import modal.client
4
+ import modal_proto.api_pb2
4
5
  import typing
5
6
  import typing_extensions
6
7
 
@@ -32,11 +33,12 @@ class _FileIO(typing.Generic[T]):
32
33
  _task_id: str
33
34
  _file_descriptor: str
34
35
  _client: modal.client._Client
35
- _watch_output_buffer: list[typing.Union[bytes, None, Exception]]
36
+ _watch_output_buffer: list[typing.Optional[bytes]]
36
37
 
37
38
  def __init__(self, client: modal.client._Client, task_id: str) -> None: ...
38
39
  def _validate_mode(self, mode: str) -> None: ...
39
- def _consume_output(self, exec_id: str) -> typing.AsyncIterator[typing.Union[bytes, None, Exception]]: ...
40
+ def _handle_error(self, error: modal_proto.api_pb2.SystemErrorMessage) -> None: ...
41
+ def _consume_output(self, exec_id: str) -> typing.AsyncIterator[typing.Optional[bytes]]: ...
40
42
  async def _consume_watch_output(self, exec_id: str) -> None: ...
41
43
  async def _parse_watch_output(self, event: bytes) -> typing.Optional[FileWatchEvent]: ...
42
44
  async def _wait(self, exec_id: str) -> bytes: ...
@@ -110,14 +112,15 @@ class FileIO(typing.Generic[T]):
110
112
  _task_id: str
111
113
  _file_descriptor: str
112
114
  _client: modal.client.Client
113
- _watch_output_buffer: list[typing.Union[bytes, None, Exception]]
115
+ _watch_output_buffer: list[typing.Optional[bytes]]
114
116
 
115
117
  def __init__(self, client: modal.client.Client, task_id: str) -> None: ...
116
118
  def _validate_mode(self, mode: str) -> None: ...
119
+ def _handle_error(self, error: modal_proto.api_pb2.SystemErrorMessage) -> None: ...
117
120
 
118
121
  class ___consume_output_spec(typing_extensions.Protocol[SUPERSELF]):
119
- def __call__(self, /, exec_id: str) -> typing.Iterator[typing.Union[bytes, None, Exception]]: ...
120
- def aio(self, /, exec_id: str) -> typing.AsyncIterator[typing.Union[bytes, None, Exception]]: ...
122
+ def __call__(self, /, exec_id: str) -> typing.Iterator[typing.Optional[bytes]]: ...
123
+ def aio(self, /, exec_id: str) -> typing.AsyncIterator[typing.Optional[bytes]]: ...
121
124
 
122
125
  _consume_output: ___consume_output_spec[typing_extensions.Self]
123
126
 
@@ -105,7 +105,6 @@ class _Sandbox(_Object, type_prefix="sb"):
105
105
  proxy: Optional[_Proxy] = None,
106
106
  _experimental_scheduler_placement: Optional[SchedulerPlacement] = None,
107
107
  enable_snapshot: bool = False,
108
- verbose: bool = False,
109
108
  ) -> "_Sandbox":
110
109
  """mdmd:hidden"""
111
110
 
@@ -206,7 +205,6 @@ class _Sandbox(_Object, type_prefix="sb"):
206
205
  network_access=network_access,
207
206
  proxy_id=(proxy.object_id if proxy else None),
208
207
  enable_snapshot=enable_snapshot,
209
- verbose=verbose,
210
208
  )
211
209
 
212
210
  # Note - `resolver.app_id` will be `None` for app-less sandboxes
@@ -255,8 +253,6 @@ class _Sandbox(_Object, type_prefix="sb"):
255
253
  unencrypted_ports: Sequence[int] = [],
256
254
  # Reference to a Modal Proxy to use in front of this Sandbox.
257
255
  proxy: Optional[_Proxy] = None,
258
- # Enable verbose logging for sandbox operations.
259
- verbose: bool = False,
260
256
  # Enable memory snapshots.
261
257
  _experimental_enable_snapshot: bool = False,
262
258
  _experimental_scheduler_placement: Optional[
@@ -302,7 +298,6 @@ class _Sandbox(_Object, type_prefix="sb"):
302
298
  _experimental_enable_snapshot=_experimental_enable_snapshot,
303
299
  _experimental_scheduler_placement=_experimental_scheduler_placement,
304
300
  client=client,
305
- verbose=verbose,
306
301
  )
307
302
 
308
303
  @staticmethod
@@ -347,7 +342,6 @@ class _Sandbox(_Object, type_prefix="sb"):
347
342
  SchedulerPlacement
348
343
  ] = None, # Experimental controls over fine-grained scheduling (alpha).
349
344
  client: Optional[_Client] = None,
350
- verbose: bool = False,
351
345
  ):
352
346
  # This method exposes some internal arguments (currently `mounts`) which are not in the public API
353
347
  # `mounts` is currently only used by modal shell (cli) to provide a function's mounts to the
@@ -382,7 +376,6 @@ class _Sandbox(_Object, type_prefix="sb"):
382
376
  proxy=proxy,
383
377
  _experimental_scheduler_placement=_experimental_scheduler_placement,
384
378
  enable_snapshot=_experimental_enable_snapshot,
385
- verbose=verbose,
386
379
  )
387
380
  obj._enable_snapshot = _experimental_enable_snapshot
388
381
 
@@ -63,7 +63,6 @@ class _Sandbox(modal._object._Object):
63
63
  proxy: typing.Optional[modal.proxy._Proxy] = None,
64
64
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
65
65
  enable_snapshot: bool = False,
66
- verbose: bool = False,
67
66
  ) -> _Sandbox: ...
68
67
  @staticmethod
69
68
  async def create(
@@ -91,7 +90,6 @@ class _Sandbox(modal._object._Object):
91
90
  h2_ports: collections.abc.Sequence[int] = [],
92
91
  unencrypted_ports: collections.abc.Sequence[int] = [],
93
92
  proxy: typing.Optional[modal.proxy._Proxy] = None,
94
- verbose: bool = False,
95
93
  _experimental_enable_snapshot: bool = False,
96
94
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
97
95
  client: typing.Optional[modal.client._Client] = None,
@@ -126,7 +124,6 @@ class _Sandbox(modal._object._Object):
126
124
  _experimental_enable_snapshot: bool = False,
127
125
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
128
126
  client: typing.Optional[modal.client._Client] = None,
129
- verbose: bool = False,
130
127
  ): ...
131
128
  def _hydrate_metadata(self, handle_metadata: typing.Optional[google.protobuf.message.Message]): ...
132
129
  @staticmethod
@@ -239,7 +236,6 @@ class Sandbox(modal.object.Object):
239
236
  proxy: typing.Optional[modal.proxy.Proxy] = None,
240
237
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
241
238
  enable_snapshot: bool = False,
242
- verbose: bool = False,
243
239
  ) -> Sandbox: ...
244
240
 
245
241
  class __create_spec(typing_extensions.Protocol):
@@ -272,7 +268,6 @@ class Sandbox(modal.object.Object):
272
268
  h2_ports: collections.abc.Sequence[int] = [],
273
269
  unencrypted_ports: collections.abc.Sequence[int] = [],
274
270
  proxy: typing.Optional[modal.proxy.Proxy] = None,
275
- verbose: bool = False,
276
271
  _experimental_enable_snapshot: bool = False,
277
272
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
278
273
  client: typing.Optional[modal.client.Client] = None,
@@ -306,7 +301,6 @@ class Sandbox(modal.object.Object):
306
301
  h2_ports: collections.abc.Sequence[int] = [],
307
302
  unencrypted_ports: collections.abc.Sequence[int] = [],
308
303
  proxy: typing.Optional[modal.proxy.Proxy] = None,
309
- verbose: bool = False,
310
304
  _experimental_enable_snapshot: bool = False,
311
305
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
312
306
  client: typing.Optional[modal.client.Client] = None,
@@ -348,7 +342,6 @@ class Sandbox(modal.object.Object):
348
342
  _experimental_enable_snapshot: bool = False,
349
343
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
350
344
  client: typing.Optional[modal.client.Client] = None,
351
- verbose: bool = False,
352
345
  ): ...
353
346
  async def aio(
354
347
  self,
@@ -383,7 +376,6 @@ class Sandbox(modal.object.Object):
383
376
  _experimental_enable_snapshot: bool = False,
384
377
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
385
378
  client: typing.Optional[modal.client.Client] = None,
386
- verbose: bool = False,
387
379
  ): ...
388
380
 
389
381
  _create: ___create_spec
@@ -403,10 +403,6 @@ class _Volume(_Object, type_prefix="vo"):
403
403
  """
404
404
  Read a file from the modal.Volume.
405
405
 
406
- Note - this function is primarily intended to be used outside of a Modal App.
407
- For more information on downloading files from a Modal Volume, see
408
- [the guide](/docs/guide/volumes).
409
-
410
406
  **Example:**
411
407
 
412
408
  ```python notest
@@ -447,7 +443,6 @@ class _Volume(_Object, type_prefix="vo"):
447
443
  Read volume file into file-like IO object.
448
444
  """
449
445
  if progress_cb is None:
450
-
451
446
  def progress_cb(*_, **__):
452
447
  pass
453
448
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.4
3
+ Version: 1.0.4.dev2
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -22,7 +22,7 @@ Requires-Dist: click~=8.1.0
22
22
  Requires-Dist: grpclib==0.4.7
23
23
  Requires-Dist: protobuf!=4.24.0,<7.0,>=3.19
24
24
  Requires-Dist: rich>=12.0.0
25
- Requires-Dist: synchronicity~=0.9.15
25
+ Requires-Dist: synchronicity~=0.9.13
26
26
  Requires-Dist: toml
27
27
  Requires-Dist: typer>=0.9
28
28
  Requires-Dist: types-certifi
@@ -4,7 +4,7 @@ click~=8.1.0
4
4
  grpclib==0.4.7
5
5
  protobuf!=4.24.0,<7.0,>=3.19
6
6
  rich>=12.0.0
7
- synchronicity~=0.9.15
7
+ synchronicity~=0.9.13
8
8
  toml
9
9
  typer>=0.9
10
10
  types-certifi
@@ -2440,9 +2440,6 @@ message Sandbox {
2440
2440
 
2441
2441
  // If set, overrides the runtime used by the function, either "runc" or "gvisor".
2442
2442
  optional string runtime = 28;
2443
-
2444
- // If set, the sandbox will be created with verbose logging enabled.
2445
- bool verbose = 29;
2446
2443
  }
2447
2444
 
2448
2445
  message SandboxCreateRequest {
@@ -2796,7 +2793,6 @@ message TaskInfo {
2796
2793
  modal.client.GenericResult result = 4;
2797
2794
  double enqueued_at = 5;
2798
2795
  string gpu_type = 6;
2799
- string sandbox_id = 7;
2800
2796
  }
2801
2797
 
2802
2798
  message TaskListRequest {