modal 1.4.4.dev17__tar.gz → 1.4.4.dev19__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/PKG-INFO +1 -1
  2. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_container_entrypoint.py +10 -12
  3. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_function_variants.py +43 -1
  4. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_functions.py +10 -0
  5. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_image.py +102 -0
  6. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_runtime/user_code_imports.py +2 -4
  7. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/sandbox_fs_utils.py +47 -0
  8. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/billing.py +5 -1
  9. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/client.pyi +2 -2
  10. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/file_io.py +4 -19
  11. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/file_io.pyi +9 -34
  12. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/functions.pyi +6 -6
  13. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/image.pyi +71 -0
  14. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/sandbox.py +15 -8
  15. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/sandbox.pyi +21 -15
  16. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/sandbox_fs.py +141 -1
  17. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/sandbox_fs.pyi +196 -0
  18. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal.egg-info/PKG-INFO +1 -1
  19. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/api_grpc.py +32 -0
  20. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/api_pb2.py +621 -581
  21. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/api_pb2.pyi +74 -0
  22. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/api_pb2_grpc.py +66 -0
  23. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/api_pb2_grpc.pyi +20 -0
  24. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/modal_api_grpc.py +2 -0
  25. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_version/__init__.py +1 -1
  26. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/LICENSE +0 -0
  27. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/README.md +0 -0
  28. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/__init__.py +0 -0
  29. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/__main__.py +0 -0
  30. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_billing.py +0 -0
  31. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_clustered_functions.py +0 -0
  32. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_clustered_functions.pyi +0 -0
  33. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_environments.py +0 -0
  34. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_grpc_client.py +0 -0
  35. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_ipython.py +0 -0
  36. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_load_context.py +0 -0
  37. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_location.py +0 -0
  38. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_logs.py +0 -0
  39. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_object.py +0 -0
  40. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_output/__init__.py +0 -0
  41. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_output/manager.py +0 -0
  42. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_output/pty.py +0 -0
  43. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_output/rich.py +0 -0
  44. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_output/status.py +0 -0
  45. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_partial_function.py +0 -0
  46. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_resolver.py +0 -0
  47. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_resources.py +0 -0
  48. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_runtime/__init__.py +0 -0
  49. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_runtime/asgi.py +0 -0
  50. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_runtime/container_io_manager.py +0 -0
  51. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_runtime/container_io_manager.pyi +0 -0
  52. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_runtime/execution_context.py +0 -0
  53. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_runtime/execution_context.pyi +0 -0
  54. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  55. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_runtime/task_lifecycle_manager.py +0 -0
  56. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
  57. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_runtime/telemetry.py +0 -0
  58. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_runtime/user_code_event_loop.py +0 -0
  59. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_serialization.py +0 -0
  60. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_server.py +0 -0
  61. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_traceback.py +0 -0
  62. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_tunnel.py +0 -0
  63. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_tunnel.pyi +0 -0
  64. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_type_manager.py +0 -0
  65. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/__init__.py +0 -0
  66. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/app_utils.py +0 -0
  67. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/async_utils.py +0 -0
  68. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/auth_token_manager.py +0 -0
  69. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/blob_utils.py +0 -0
  70. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/browser_utils.py +0 -0
  71. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/bytes_io_segment_payload.py +0 -0
  72. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/deprecation.py +0 -0
  73. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/docker_utils.py +0 -0
  74. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/function_utils.py +0 -0
  75. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/git_utils.py +0 -0
  76. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/grpc_testing.py +0 -0
  77. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/grpc_utils.py +0 -0
  78. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/hash_utils.py +0 -0
  79. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/http_utils.py +0 -0
  80. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/jwt_utils.py +0 -0
  81. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/logger.py +0 -0
  82. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/mount_utils.py +0 -0
  83. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/name_utils.py +0 -0
  84. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/package_utils.py +0 -0
  85. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/pattern_utils.py +0 -0
  86. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/rand_pb_testing.py +0 -0
  87. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/shell_utils.py +0 -0
  88. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/task_command_router_client.py +0 -0
  89. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_utils/time_utils.py +0 -0
  90. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_vendor/__init__.py +0 -0
  91. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  92. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_vendor/cloudpickle.py +0 -0
  93. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_vendor/tblib.py +0 -0
  94. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_vendor/version.py +0 -0
  95. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_watcher.py +0 -0
  96. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/_workspace.py +0 -0
  97. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/app.py +0 -0
  98. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/app.pyi +0 -0
  99. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/builder/2023.12.312.txt +0 -0
  100. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/builder/2023.12.txt +0 -0
  101. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/builder/2024.04.txt +0 -0
  102. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/builder/2024.10.txt +0 -0
  103. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/builder/2025.06.txt +0 -0
  104. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/builder/PREVIEW.txt +0 -0
  105. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/builder/README.md +0 -0
  106. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/builder/base-images.json +0 -0
  107. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/call_graph.py +0 -0
  108. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/__init__.py +0 -0
  109. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/_download.py +0 -0
  110. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/_help.py +0 -0
  111. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/_traceback.py +0 -0
  112. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/app.py +0 -0
  113. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/billing.py +0 -0
  114. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/bootstrap.py +0 -0
  115. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/changelog.py +0 -0
  116. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/cluster.py +0 -0
  117. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/config.py +0 -0
  118. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/container.py +0 -0
  119. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/dashboard.py +0 -0
  120. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/dict.py +0 -0
  121. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/entry_point.py +0 -0
  122. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/environment.py +0 -0
  123. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/import_refs.py +0 -0
  124. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/launch.py +0 -0
  125. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/logo.py +0 -0
  126. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/network_file_system.py +0 -0
  127. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/profile.py +0 -0
  128. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/programs/__init__.py +0 -0
  129. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/programs/run_jupyter.py +0 -0
  130. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/programs/vscode.py +0 -0
  131. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/queues.py +0 -0
  132. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/run.py +0 -0
  133. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/secret.py +0 -0
  134. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/selector.py +0 -0
  135. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/shell.py +0 -0
  136. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/skills.py +0 -0
  137. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/token.py +0 -0
  138. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/utils.py +0 -0
  139. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cli/volume.py +0 -0
  140. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/client.py +0 -0
  141. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cloud_bucket_mount.py +0 -0
  142. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cloud_bucket_mount.pyi +0 -0
  143. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cls.py +0 -0
  144. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/cls.pyi +0 -0
  145. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/config.py +0 -0
  146. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/container_process.py +0 -0
  147. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/container_process.pyi +0 -0
  148. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/dict.py +0 -0
  149. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/dict.pyi +0 -0
  150. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/environments.py +0 -0
  151. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/environments.pyi +0 -0
  152. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/exception.py +0 -0
  153. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/experimental/__init__.py +0 -0
  154. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/experimental/flash.py +0 -0
  155. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/experimental/flash.pyi +0 -0
  156. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/experimental/ipython.py +0 -0
  157. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/file_pattern_matcher.py +0 -0
  158. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/functions.py +0 -0
  159. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/image.py +0 -0
  160. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/io_streams.py +0 -0
  161. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/io_streams.pyi +0 -0
  162. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/mount.py +0 -0
  163. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/mount.pyi +0 -0
  164. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/network_file_system.py +0 -0
  165. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/network_file_system.pyi +0 -0
  166. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/object.py +0 -0
  167. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/object.pyi +0 -0
  168. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/output.py +0 -0
  169. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/parallel_map.py +0 -0
  170. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/parallel_map.pyi +0 -0
  171. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/partial_function.py +0 -0
  172. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/partial_function.pyi +0 -0
  173. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/proxy.py +0 -0
  174. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/proxy.pyi +0 -0
  175. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/py.typed +0 -0
  176. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/queue.py +0 -0
  177. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/queue.pyi +0 -0
  178. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/retries.py +0 -0
  179. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/runner.py +0 -0
  180. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/runner.pyi +0 -0
  181. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/running_app.py +0 -0
  182. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/schedule.py +0 -0
  183. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/scheduler_placement.py +0 -0
  184. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/secret.py +0 -0
  185. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/secret.pyi +0 -0
  186. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/server.py +0 -0
  187. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/server.pyi +0 -0
  188. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/serving.py +0 -0
  189. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/serving.pyi +0 -0
  190. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/skills/modal/SKILL.md +0 -0
  191. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/snapshot.py +0 -0
  192. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/snapshot.pyi +0 -0
  193. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/stream_type.py +0 -0
  194. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/token_flow.py +0 -0
  195. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/token_flow.pyi +0 -0
  196. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/volume.py +0 -0
  197. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/volume.pyi +0 -0
  198. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/workspace.py +0 -0
  199. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal/workspace.pyi +0 -0
  200. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal.egg-info/SOURCES.txt +0 -0
  201. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal.egg-info/dependency_links.txt +0 -0
  202. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal.egg-info/entry_points.txt +0 -0
  203. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal.egg-info/requires.txt +0 -0
  204. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal.egg-info/top_level.txt +0 -0
  205. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_docs/__init__.py +0 -0
  206. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_docs/gen_cli_docs.py +0 -0
  207. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_docs/gen_cli_docs_main.py +0 -0
  208. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_docs/gen_reference_docs.py +0 -0
  209. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_docs/gen_reference_docs_main.py +0 -0
  210. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_docs/mdmd/__init__.py +0 -0
  211. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_docs/mdmd/mdmd.py +0 -0
  212. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_docs/mdmd/signatures.py +0 -0
  213. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_docs/mdmd/types.py +0 -0
  214. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/__init__.py +0 -0
  215. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/py.typed +0 -0
  216. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/task_command_router_grpc.py +0 -0
  217. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/task_command_router_pb2.py +0 -0
  218. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/task_command_router_pb2.pyi +0 -0
  219. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  220. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  221. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/modal_version/__main__.py +0 -0
  222. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/pyproject.toml +0 -0
  223. {modal-1.4.4.dev17 → modal-1.4.4.dev19}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.4.4.dev17
3
+ Version: 1.4.4.dev19
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -28,7 +28,7 @@ from modal._clustered_functions import initialize_clustered_function
28
28
  from modal._runtime.user_code_event_loop import UserCodeEventLoop
29
29
  from modal._serialization import deserialize, deserialize_params
30
30
  from modal._utils.async_utils import TaskContext, aclosing, synchronizer
31
- from modal.app import App, _App
31
+ from modal.app import _App
32
32
  from modal.client import Client, _Client
33
33
  from modal.config import logger
34
34
  from modal.exception import ExecutionError, InputCancellation
@@ -288,7 +288,7 @@ def get_serialized_user_class_and_function(
288
288
 
289
289
 
290
290
  def get_server_service(
291
- container_args: api_pb2.ContainerArguments, function_def: api_pb2.Function, _client: _Client, client: Client
291
+ container_args: api_pb2.ContainerArguments, function_def: api_pb2.Function, _client: _Client
292
292
  ) -> Service:
293
293
  ser_usr_cls, ser_fun = get_serialized_user_class_and_function(function_def, _client)
294
294
  service_base_function_id = container_args.app_layout.function_ids[function_def.function_name]
@@ -298,14 +298,14 @@ def get_server_service(
298
298
  service = import_server_service(
299
299
  function_def,
300
300
  service_function_hydration_data,
301
- client,
301
+ _client,
302
302
  ser_usr_cls,
303
303
  )
304
304
  return service
305
305
 
306
306
 
307
307
  def get_class_service(
308
- container_args: api_pb2.ContainerArguments, function_def: api_pb2.Function, _client: _Client, client: Client
308
+ container_args: api_pb2.ContainerArguments, function_def: api_pb2.Function, _client: _Client
309
309
  ) -> Service:
310
310
  ser_usr_cls, ser_fun = get_serialized_user_class_and_function(function_def, _client)
311
311
  if container_args.serialized_params:
@@ -326,7 +326,7 @@ def get_class_service(
326
326
  function_def,
327
327
  service_function_hydration_data,
328
328
  class_id,
329
- client,
329
+ _client,
330
330
  ser_usr_cls,
331
331
  param_args,
332
332
  param_kwargs,
@@ -349,16 +349,15 @@ def hydrate_function(
349
349
  task_lifecycle_manager: TaskLifecycleManager,
350
350
  function_def: api_pb2.Function,
351
351
  _client: _Client,
352
- client: Client,
353
352
  ) -> Service:
354
353
  active_app: _App
355
354
  service: Service
356
355
  with task_lifecycle_manager.handle_task_lifecycle_exception():
357
356
  with execution_context._import_context():
358
357
  if function_def.is_server:
359
- service = get_server_service(container_args, function_def, _client, client)
358
+ service = get_server_service(container_args, function_def, _client)
360
359
  elif function_def.is_class:
361
- service = get_class_service(container_args, function_def, _client, client)
360
+ service = get_class_service(container_args, function_def, _client)
362
361
  else:
363
362
  service = get_function_service(function_def, _client)
364
363
 
@@ -369,8 +368,7 @@ def hydrate_function(
369
368
 
370
369
  # Initialize objects on the app.
371
370
  # This is basically only functions and classes - anything else is deprecated and will be unsupported soon
372
- app: App = cast(App, synchronizer._translate_out(active_app))
373
- app._init_container(client, container_app)
371
+ active_app._init_container(_client, container_app)
374
372
 
375
373
  # Hydrate all function dependencies.
376
374
  # TODO(erikbern): we an remove this once we
@@ -406,7 +404,7 @@ def run_server(container_args: api_pb2.ContainerArguments, client: Client):
406
404
  client,
407
405
  )
408
406
 
409
- service: Service = hydrate_function(container_args, task_lifecycle_manager, function_def, _client, client)
407
+ service: Service = hydrate_function(container_args, task_lifecycle_manager, function_def, _client)
410
408
  # Initialize clustered functions.
411
409
  if function_def._experimental_group_size > 0:
412
410
  initialize_clustered_function(
@@ -442,7 +440,7 @@ def run_function(container_args: api_pb2.ContainerArguments, client: Client):
442
440
  with container_io_manager.heartbeats(is_snapshotting_function), UserCodeEventLoop() as event_loop:
443
441
  # Initialize the function, importing user code.
444
442
  service: Service = hydrate_function(
445
- container_args, container_io_manager.get_task_lifecycle_manager(), function_def, _client, client
443
+ container_args, container_io_manager.get_task_lifecycle_manager(), function_def, _client
446
444
  )
447
445
  if function_def.pty_info.pty_type == api_pb2.PTYInfo.PTY_TYPE_SHELL:
448
446
  # Concurrency and batching doesn't apply for `modal shell`.
@@ -185,6 +185,48 @@ class _FunctionOptions:
185
185
  )
186
186
 
187
187
 
188
+ async def _function_bind_params_cached(
189
+ base_function: "_Function",
190
+ req: api_pb2.FunctionBindParamsRequest,
191
+ ) -> api_pb2.FunctionBindParamsResponse:
192
+ """Cache layer for FunctionBindParams RPCs, scoped to a base Function handle.
193
+
194
+ We have this because users probably do not realize that Function invocations structured as
195
+
196
+ res = f.with_options(...).remote(...)
197
+
198
+ would always need to do two sequential RPCs (bind params / call function variant).
199
+
200
+ The bound Function ID from FunctionBindParams is deterministic with respect to the full request,
201
+ so we can avoid the unnecessary call and hydrate the new instance from a cached response.
202
+
203
+ The cache is stored on the base Function handle so that the variant cache behaves similarly to
204
+ the local reference to the base Function metadata.
205
+
206
+ """
207
+ cache = base_function._bind_params_cache
208
+ cache_key = req.SerializeToString(deterministic=True)
209
+
210
+ cached_response = cache.get(cache_key)
211
+ if cached_response is not None:
212
+ cache.move_to_end(cache_key)
213
+ response = api_pb2.FunctionBindParamsResponse()
214
+ response.ParseFromString(cached_response)
215
+ return response
216
+
217
+ assert base_function._client and base_function._client.stub
218
+ response = await base_function._client.stub.FunctionBindParams(req)
219
+
220
+ cache[cache_key] = response.SerializeToString(deterministic=True)
221
+ cache.move_to_end(cache_key)
222
+
223
+ max_cache_size = 32
224
+ while len(cache) > max_cache_size:
225
+ cache.popitem(last=False)
226
+
227
+ return response
228
+
229
+
188
230
  def _make_function_variant(
189
231
  base_function: "_Function",
190
232
  options: _FunctionOptions | None,
@@ -229,7 +271,7 @@ def _make_function_variant(
229
271
  or "", # TODO: investigate shouldn't environment name always be specified here?
230
272
  )
231
273
 
232
- response = await base_function._client.stub.FunctionBindParams(req)
274
+ response = await _function_bind_params_cached(base_function, req)
233
275
  function_variant._hydrate(response.bound_function_id, base_function._client, response.handle_metadata)
234
276
 
235
277
  def _deps():
@@ -5,6 +5,7 @@ import inspect
5
5
  import time
6
6
  import typing
7
7
  import warnings
8
+ from collections import OrderedDict
8
9
  from collections.abc import AsyncGenerator, AsyncIterator, Callable, Collection, Sequence
9
10
  from dataclasses import dataclass
10
11
  from pathlib import PurePosixPath
@@ -1354,6 +1355,11 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1354
1355
  self._options = _FunctionOptions()
1355
1356
  self._base_function = None
1356
1357
 
1358
+ # An OrderedDict[bytes, bytes] LRU of FunctionBindParams responses for
1359
+ # variants derived from this base Function. Omitted from class-level annotations because
1360
+ # Synchronicity doesn't understand OrderedDict as a type hint.
1361
+ self._bind_params_cache = OrderedDict()
1362
+
1357
1363
  def _hydrate_metadata(self, metadata: Message | None):
1358
1364
  # Overridden concrete implementation of base class method
1359
1365
  assert metadata and isinstance(metadata, api_pb2.FunctionHandleMetadata), (
@@ -1382,6 +1388,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1382
1388
  )
1383
1389
  self._experimental_flash_urls = metadata._experimental_flash_urls
1384
1390
 
1391
+ # Invalidate the Function variant cache when we load new metadata, since the base Function handle
1392
+ # is now in sync with the server but any previously-cached variants may be stale.
1393
+ self._bind_params_cache.clear()
1394
+
1385
1395
  def _get_metadata(self):
1386
1396
  # Overridden concrete implementation of base class method
1387
1397
  assert self._function_name, f"Function name must be set before metadata can be retrieved for {self}"
@@ -40,6 +40,7 @@ from ._utils.docker_utils import (
40
40
  )
41
41
  from ._utils.function_utils import FunctionInfo, parse_gpu_config
42
42
  from ._utils.mount_utils import validate_only_modal_volumes, validate_volumes_by_object_id
43
+ from ._utils.name_utils import check_object_name
43
44
  from .client import _Client
44
45
  from .cloud_bucket_mount import _CloudBucketMount
45
46
  from .config import config, logger, user_config_path
@@ -103,6 +104,27 @@ See https://modal.com/docs/guide/modal-1-0-migration for more details.
103
104
  P = typing_extensions.ParamSpec("P")
104
105
 
105
106
 
107
+ def _validate_image_name(name: str) -> None:
108
+ check_object_name(name, "Image")
109
+ # Reserve the "im-" prefix for image IDs so CLI args can be parsed
110
+ # unambiguously as either an image ID or an image name.
111
+ if name.startswith("im-"):
112
+ raise InvalidError("Image name cannot start with 'im-' (reserved for image IDs).")
113
+
114
+
115
+ def _validate_image_tag(tag: str) -> None:
116
+ check_object_name(tag, "Image tag")
117
+
118
+
119
+ def _parse_named_image_ref(name: str) -> str:
120
+ image_name, sep, tag = name.partition(":")
121
+ if not sep:
122
+ tag = "latest"
123
+ _validate_image_name(image_name)
124
+ _validate_image_tag(tag)
125
+ return f"{image_name}:{tag}"
126
+
127
+
106
128
  def _validate_python_version(
107
129
  python_version: str | None,
108
130
  builder_version: ImageBuilderVersion,
@@ -2844,6 +2866,86 @@ class _Image(_Object, type_prefix="im"):
2844
2866
  if task_log.data:
2845
2867
  yield task_log.data
2846
2868
 
2869
+ @staticmethod
2870
+ def from_name(
2871
+ name: str,
2872
+ *,
2873
+ environment_name: str | None = None,
2874
+ client: _Client | None = None,
2875
+ ) -> "_Image":
2876
+ """Reference a named Image that was previously published with `.publish()`.
2877
+
2878
+ Names can contain an optional `:tag` part - if no tag part is included `":latest"` is used,
2879
+ matching Docker conventions.
2880
+
2881
+ ```python notest
2882
+ image = modal.Image.from_name("my-image") # references my-image:latest
2883
+ image_v1 = modal.Image.from_name("my-image:v1")
2884
+
2885
+ @app.function(image=image)
2886
+ def run():
2887
+ ...
2888
+ ```
2889
+ """
2890
+ tag = _parse_named_image_ref(name)
2891
+
2892
+ async def _load(self: _Image, resolver: Resolver, load_context: LoadContext, existing_object_id: str | None):
2893
+ req = api_pb2.ImageGetByTagRequest(
2894
+ tag=tag,
2895
+ environment_name=load_context.environment_name,
2896
+ )
2897
+ response = await load_context.client.stub.ImageGetByTag(req)
2898
+ self._hydrate(response.image_id, load_context.client, None)
2899
+
2900
+ rep = _Image._repr(tag, environment_name)
2901
+ return _Image._from_loader(
2902
+ _load,
2903
+ rep,
2904
+ hydrate_lazily=True,
2905
+ skip_reload=True,
2906
+ load_context_overrides=LoadContext(environment_name=environment_name, client=client),
2907
+ )
2908
+
2909
+ async def publish(
2910
+ self,
2911
+ name: str,
2912
+ *,
2913
+ environment_name: str | None = None,
2914
+ client: _Client | None = None,
2915
+ ) -> None:
2916
+ """Publish this image under the given name
2917
+
2918
+ The Image must already be created (typically by calling `image.build()` or `sandbox.snapshot_filesystem()`).
2919
+
2920
+ Image names can contain an explicit tag designation (using the `name:tag`). If no tag is included in the name,
2921
+ `":latest"` is used, matching Docker conventions. To publish multiple tags, call `.publish()` once per tag.
2922
+
2923
+ ```python notest
2924
+ image = modal.Image.debian_slim().pip_install("numpy")
2925
+ image.build(app)
2926
+ image.publish("my-image-with-numpy") # my-image-with-numpy:latest
2927
+ image.publish("my-image-with-numpy:v1")
2928
+ ```
2929
+ """
2930
+ tag = _parse_named_image_ref(name)
2931
+
2932
+ if not self.is_hydrated:
2933
+ raise InvalidError("Cannot publish an image that has not been created yet. Call `.build()` first.")
2934
+
2935
+ _client = client or self._client
2936
+ assert _client is not None
2937
+
2938
+ resolved_env = environment_name or config.get("environment") or ""
2939
+
2940
+ await _client.stub.ImagePublish(
2941
+ api_pb2.ImagePublishRequest(
2942
+ image_id=self.object_id,
2943
+ environment_name=resolved_env,
2944
+ is_public=False,
2945
+ tag=tag,
2946
+ )
2947
+ )
2948
+
2847
2949
  async def hydrate(self, client: _Client | None = None) -> Self:
2848
2950
  """mdmd:hidden"""
2849
2951
  # Image inherits hydrate() from Object but can't be hydrated on demand
@@ -571,7 +571,7 @@ def import_class_service(
571
571
  function_def: api_pb2.Function,
572
572
  service_function_hydration_data: api_pb2.Object,
573
573
  class_id: str,
574
- client: "modal.client.Client",
574
+ _client: "modal.client._Client",
575
575
  ser_user_cls: type | None,
576
576
  cls_args,
577
577
  cls_kwargs,
@@ -599,7 +599,6 @@ def import_class_service(
599
599
  # Undecorated user class (serialized or local scope-decoration).
600
600
  service_deps = None # we can't infer service deps for now
601
601
  active_app = get_active_app_fallback(function_def)
602
- _client = typing.cast("modal.client._Client", synchronizer._translate_in(client))
603
602
  _service_function: modal._functions._Function[Any, Any, Any] = modal._functions._Function._new_hydrated(
604
603
  service_function_hydration_data.object_id,
605
604
  _client,
@@ -627,7 +626,7 @@ def import_class_service(
627
626
  def import_server_service(
628
627
  function_def: api_pb2.Function,
629
628
  service_function_hydration_data: api_pb2.Object,
630
- client: "modal.client.Client",
629
+ _client: "modal.client._Client",
631
630
  ser_user_cls: type | None,
632
631
  ) -> Service:
633
632
  """
@@ -654,7 +653,6 @@ def import_server_service(
654
653
  # Undecorated user class (serialized or local scope-decoration).
655
654
  service_deps = None # we can't infer service deps for now
656
655
  active_app = get_active_app_fallback(function_def)
657
- _client = typing.cast("modal.client._Client", synchronizer._translate_in(client))
658
656
  _service_function: modal._functions._Function[Any, Any, Any] = modal._functions._Function._new_hydrated(
659
657
  service_function_hydration_data.object_id,
660
658
  _client,
@@ -285,6 +285,53 @@ def make_stat_command(remote_path: str) -> str:
285
285
  return json.dumps({"Stat": {"path": remote_path}})
286
286
 
287
287
 
288
+ def raise_watch_error(returncode: int, stderr: str | bytes, remote_path: str) -> NoReturn:
289
+ if payload := try_parse_error_payload(stderr):
290
+ logger.debug(
291
+ f"sandbox-fs-tools watch error: path={remote_path}, "
292
+ f"error_kind={payload.error_kind}, message={payload.message}, detail={payload.detail}"
293
+ )
294
+ if payload.error_kind == "NotFound":
295
+ raise SandboxFilesystemNotFoundError(f"{payload.message}: {remote_path}")
296
+ if payload.error_kind == "PermissionDenied":
297
+ raise SandboxFilesystemPermissionError(f"{payload.message}: {remote_path}")
298
+ if payload.error_kind == "NotSupported":
299
+ raise InvalidError(
300
+ f"{payload.message}: {remote_path} - this operation is not supported for CloudBucketMounts"
301
+ )
302
+ raise SandboxFilesystemError(payload.message)
303
+
304
+ if stderr_text := _stderr_to_text(stderr):
305
+ logger.debug(f"Unstructured modal-sandbox-fs-tools stderr: {stderr_text}")
306
+ raise SandboxFilesystemError(f"Operation on '{remote_path}' failed with exit code {returncode}")
307
+
308
+
309
+ def make_watch_command(
310
+ remote_path: str,
311
+ *,
312
+ recursive: bool,
313
+ filter: list[str] | None,
314
+ timeout: int | None,
315
+ ) -> str:
316
+ """Build the JSON command string for a Watch operation.
317
+
318
+ The returned JSON must match the `Command` enum in the modal-sandbox-fs-tools
319
+ Rust crate (crates/modal-sandbox-fs-tools/src/lib.rs). Treat changes to
320
+ this schema like protobuf changes: fields must not be removed or renamed,
321
+ only added with backwards-compatible defaults.
322
+ """
323
+ return json.dumps(
324
+ {
325
+ "Watch": {
326
+ "path": remote_path,
327
+ "recursive": recursive,
328
+ "filter": filter,
329
+ "timeout_secs": timeout,
330
+ }
331
+ }
332
+ )
333
+
334
+
288
335
  def validate_absolute_remote_path(remote_path: str, operation: str) -> None:
289
336
  if not PurePosixPath(remote_path).is_absolute():
290
337
  raise InvalidError(f"Sandbox.filesystem.{operation}() currently only supports absolute remote_path values")
@@ -3,4 +3,8 @@ from ._billing import WorkspaceBillingReportItem, _workspace_billing_report
3
3
  from ._utils.async_utils import synchronize_api
4
4
 
5
5
  workspace_billing_report = synchronize_api(_workspace_billing_report)
6
- assert WorkspaceBillingReportItem
6
+
7
+ __all__ = [
8
+ "workspace_billing_report",
9
+ "WorkspaceBillingReportItem",
10
+ ]
@@ -35,7 +35,7 @@ class _Client:
35
35
  server_url: str,
36
36
  client_type: int,
37
37
  credentials: typing.Optional[tuple[str, str]],
38
- version: str = "1.4.4.dev17",
38
+ version: str = "1.4.4.dev19",
39
39
  ):
40
40
  """mdmd:hidden
41
41
  The Modal client object is not intended to be instantiated directly by users.
@@ -205,7 +205,7 @@ class Client:
205
205
  server_url: str,
206
206
  client_type: int,
207
207
  credentials: typing.Optional[tuple[str, str]],
208
- version: str = "1.4.4.dev17",
208
+ version: str = "1.4.4.dev19",
209
209
  ):
210
210
  """mdmd:hidden
211
211
  The Modal client object is not intended to be instantiated directly by users.
@@ -1,10 +1,8 @@
1
1
  # Copyright Modal Labs 2024
2
2
  import asyncio
3
- import enum
4
3
  import io
5
4
  from collections.abc import AsyncIterator, Sequence
6
- from dataclasses import dataclass
7
- from typing import TYPE_CHECKING, Generic, TypeVar, Union, cast
5
+ from typing import TYPE_CHECKING, Generic, Optional, TypeVar, Union, cast
8
6
 
9
7
  if TYPE_CHECKING:
10
8
  import _typeshed
@@ -15,6 +13,7 @@ from grpclib.exceptions import StreamTerminatedError
15
13
 
16
14
  from modal._utils.async_utils import TaskContext
17
15
  from modal.exception import ClientClosed
16
+ from modal.sandbox_fs import FileWatchEvent, FileWatchEventType
18
17
  from modal_proto import api_pb2
19
18
 
20
19
  from ._utils.async_utils import synchronize_api
@@ -60,21 +59,7 @@ async def _replace_bytes(file: "_FileIO", data: bytes, start: int | None = None,
60
59
  deprecation_error((2025, 12, 3), "replace_bytes has been removed.")
61
60
 
62
61
 
63
- class FileWatchEventType(enum.Enum):
64
- Unknown = "Unknown"
65
- Access = "Access"
66
- Create = "Create"
67
- Modify = "Modify"
68
- Remove = "Remove"
69
-
70
-
71
- @dataclass
72
- class FileWatchEvent:
73
- paths: list[str]
74
- type: FileWatchEventType
75
-
76
-
77
- async def _consume_output(client: _Client, exec_id: str) -> AsyncIterator[bytes | None | Exception]:
62
+ async def _consume_output(client: _Client, exec_id: str) -> AsyncIterator[Optional[bytes] | Exception]:
78
63
  req = api_pb2.ContainerFilesystemExecGetOutputRequest(
79
64
  exec_id=exec_id,
80
65
  timeout=55,
@@ -424,7 +409,7 @@ class _FileIO(Generic[T]):
424
409
  ) -> AsyncIterator[FileWatchEvent]:
425
410
  deprecation_warning(
426
411
  (2026, 3, 9),
427
- "`FileIO.watch()` is deprecated. Use `Sandbox.watch()` instead.",
412
+ "`FileIO.watch()` is deprecated. Use `Sandbox.filesystem.watch()` instead.",
428
413
  )
429
414
  async for event in watch(path, client, task_id, filter, recursive, timeout):
430
415
  yield event
@@ -1,8 +1,8 @@
1
1
  import _io
2
2
  import _typeshed
3
3
  import collections.abc
4
- import enum
5
4
  import modal.client
5
+ import modal.sandbox_fs
6
6
  import typing
7
7
  import typing_extensions
8
8
 
@@ -22,31 +22,6 @@ async def _replace_bytes(
22
22
  """
23
23
  ...
24
24
 
25
- class FileWatchEventType(enum.Enum):
26
- Unknown = "Unknown"
27
- Access = "Access"
28
- Create = "Create"
29
- Modify = "Modify"
30
- Remove = "Remove"
31
-
32
- class FileWatchEvent:
33
- """FileWatchEvent(paths: list[str], type: modal.file_io.FileWatchEventType)"""
34
-
35
- paths: list[str]
36
- type: FileWatchEventType
37
-
38
- def __init__(self, paths: list[str], type: FileWatchEventType) -> None:
39
- """Initialize self. See help(type(self)) for accurate signature."""
40
- ...
41
-
42
- def __repr__(self):
43
- """Return repr(self)."""
44
- ...
45
-
46
- def __eq__(self, other):
47
- """Return self==value."""
48
- ...
49
-
50
25
  def _consume_output(
51
26
  client: modal.client._Client, exec_id: str
52
27
  ) -> collections.abc.AsyncIterator[typing.Union[bytes, None, Exception]]: ...
@@ -157,10 +132,10 @@ class _FileIO(typing.Generic[T]):
157
132
  path: str,
158
133
  client: modal.client._Client,
159
134
  task_id: str,
160
- filter: typing.Optional[list[FileWatchEventType]] = None,
135
+ filter: typing.Optional[list[modal.sandbox_fs.FileWatchEventType]] = None,
161
136
  recursive: bool = False,
162
137
  timeout: typing.Optional[int] = None,
163
- ) -> collections.abc.AsyncIterator[FileWatchEvent]: ...
138
+ ) -> collections.abc.AsyncIterator[modal.sandbox_fs.FileWatchEvent]: ...
164
139
  async def _close(self) -> None: ...
165
140
  async def close(self) -> None:
166
141
  """Flush the buffer and close the file."""
@@ -190,10 +165,10 @@ def watch(
190
165
  path: str,
191
166
  client: modal.client._Client,
192
167
  task_id: str,
193
- filter: typing.Optional[list[FileWatchEventType]] = None,
168
+ filter: typing.Optional[list[modal.sandbox_fs.FileWatchEventType]] = None,
194
169
  recursive: bool = False,
195
170
  timeout: typing.Optional[int] = None,
196
- ) -> collections.abc.AsyncIterator[FileWatchEvent]:
171
+ ) -> collections.abc.AsyncIterator[modal.sandbox_fs.FileWatchEvent]:
197
172
  """Watch a file or directory for changes."""
198
173
  ...
199
174
 
@@ -428,20 +403,20 @@ class FileIO(typing.Generic[T]):
428
403
  path: str,
429
404
  client: modal.client.Client,
430
405
  task_id: str,
431
- filter: typing.Optional[list[FileWatchEventType]] = None,
406
+ filter: typing.Optional[list[modal.sandbox_fs.FileWatchEventType]] = None,
432
407
  recursive: bool = False,
433
408
  timeout: typing.Optional[int] = None,
434
- ) -> typing.Iterator[FileWatchEvent]: ...
409
+ ) -> typing.Iterator[modal.sandbox_fs.FileWatchEvent]: ...
435
410
  def aio(
436
411
  self,
437
412
  /,
438
413
  path: str,
439
414
  client: modal.client.Client,
440
415
  task_id: str,
441
- filter: typing.Optional[list[FileWatchEventType]] = None,
416
+ filter: typing.Optional[list[modal.sandbox_fs.FileWatchEventType]] = None,
442
417
  recursive: bool = False,
443
418
  timeout: typing.Optional[int] = None,
444
- ) -> collections.abc.AsyncIterator[FileWatchEvent]: ...
419
+ ) -> collections.abc.AsyncIterator[modal.sandbox_fs.FileWatchEvent]: ...
445
420
 
446
421
  watch: typing.ClassVar[__watch_spec]
447
422
 
@@ -465,7 +465,7 @@ class Function(
465
465
 
466
466
  _call_generator: ___call_generator_spec
467
467
 
468
- class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
468
+ class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
469
469
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
470
470
  """Calls the function remotely, executing it with the given arguments and returning the execution's result.
471
471
 
@@ -490,7 +490,7 @@ class Function(
490
490
  """
491
491
  ...
492
492
 
493
- remote: __remote_spec[modal._functions.P, modal._functions.ReturnType]
493
+ remote: __remote_spec[modal._functions.ReturnType, modal._functions.P]
494
494
 
495
495
  class __remote_gen_spec(typing_extensions.Protocol):
496
496
  def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
@@ -540,7 +540,7 @@ class Function(
540
540
  """
541
541
  ...
542
542
 
543
- class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
543
+ class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
544
544
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
545
545
  """[Experimental] Calls the function with the given arguments, without waiting for the results.
546
546
 
@@ -573,7 +573,7 @@ class Function(
573
573
  """
574
574
  ...
575
575
 
576
- _experimental_spawn: ___experimental_spawn_spec[modal._functions.P, modal._functions.ReturnType]
576
+ _experimental_spawn: ___experimental_spawn_spec[modal._functions.ReturnType, modal._functions.P]
577
577
 
578
578
  class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
579
579
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
@@ -581,7 +581,7 @@ class Function(
581
581
 
582
582
  _spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
583
583
 
584
- class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
584
+ class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
585
585
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
586
586
  """Calls the function with the given arguments, without waiting for the results.
587
587
 
@@ -614,7 +614,7 @@ class Function(
614
614
  """
615
615
  ...
616
616
 
617
- spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType]
617
+ spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P]
618
618
 
619
619
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
620
620
  """Return the inner Python object wrapped by this Modal Function.