modal 1.5.4.dev22__tar.gz → 1.5.5__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 (238) hide show
  1. {modal-1.5.4.dev22 → modal-1.5.5}/PKG-INFO +1 -1
  2. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_container_entrypoint.py +4 -2
  3. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_environments.py +14 -5
  4. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_function_variants.py +3 -3
  5. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_functions.py +92 -22
  6. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_image.py +13 -10
  7. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_logs_manager.py +191 -9
  8. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_logs_manager.pyi +434 -1
  9. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_object.py +34 -4
  10. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_resolver.py +5 -5
  11. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_runtime/asgi.py +1 -1
  12. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_runtime/container_io_manager.py +53 -29
  13. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_runtime/container_io_manager.pyi +16 -10
  14. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_runtime/user_code_imports.py +5 -5
  15. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_serialization.py +3 -1
  16. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_supports_logs.py +1 -3
  17. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/deprecation.py +29 -0
  18. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/function_utils.py +9 -9
  19. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/grpc_utils.py +9 -0
  20. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/mount_utils.py +1 -1
  21. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_workspace.py +6 -6
  22. {modal-1.5.4.dev22 → modal-1.5.5}/modal/app.py +96 -56
  23. {modal-1.5.4.dev22 → modal-1.5.5}/modal/app.pyi +73 -32
  24. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/_help.py +143 -4
  25. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/app.py +51 -0
  26. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/changelog.py +1 -1
  27. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/config.py +8 -3
  28. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/entry_point.py +9 -4
  29. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/environment.py +29 -7
  30. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/import_refs.py +9 -4
  31. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/launch.py +1 -1
  32. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/profile.py +4 -4
  33. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/run.py +35 -8
  34. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/shell.py +2 -2
  35. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/token.py +3 -11
  36. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/volume.py +7 -7
  37. {modal-1.5.4.dev22 → modal-1.5.5}/modal/client.py +140 -15
  38. {modal-1.5.4.dev22 → modal-1.5.5}/modal/client.pyi +124 -3
  39. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cls.py +31 -18
  40. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cls.pyi +20 -0
  41. {modal-1.5.4.dev22 → modal-1.5.5}/modal/config.py +22 -7
  42. {modal-1.5.4.dev22 → modal-1.5.5}/modal/environments.pyi +14 -2
  43. {modal-1.5.4.dev22 → modal-1.5.5}/modal/exception.py +13 -2
  44. {modal-1.5.4.dev22 → modal-1.5.5}/modal/experimental/__init__.py +5 -3
  45. modal-1.5.5/modal/experimental/flash.py +389 -0
  46. modal-1.5.5/modal/experimental/flash.pyi +235 -0
  47. {modal-1.5.4.dev22 → modal-1.5.5}/modal/functions.pyi +86 -10
  48. {modal-1.5.4.dev22 → modal-1.5.5}/modal/object.pyi +18 -31
  49. {modal-1.5.4.dev22 → modal-1.5.5}/modal/runner.py +6 -6
  50. {modal-1.5.4.dev22 → modal-1.5.5}/modal/sandbox.py +126 -13
  51. {modal-1.5.4.dev22 → modal-1.5.5}/modal/sandbox.pyi +108 -27
  52. {modal-1.5.4.dev22 → modal-1.5.5}/modal/skills/modal/SKILL.md +2 -2
  53. {modal-1.5.4.dev22 → modal-1.5.5}/modal/types.py +4 -3
  54. {modal-1.5.4.dev22 → modal-1.5.5}/modal.egg-info/PKG-INFO +1 -1
  55. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/api_grpc.py +32 -0
  56. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/api_pb2.py +961 -924
  57. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/api_pb2.pyi +178 -10
  58. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/api_pb2_grpc.py +66 -0
  59. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/api_pb2_grpc.pyi +20 -0
  60. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/modal_api_grpc.py +2 -0
  61. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/task_command_router_pb2.py +34 -34
  62. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/task_command_router_pb2.pyi +20 -4
  63. {modal-1.5.4.dev22 → modal-1.5.5}/modal_version/__init__.py +1 -1
  64. {modal-1.5.4.dev22 → modal-1.5.5}/pyproject.toml +3 -3
  65. modal-1.5.4.dev22/modal/experimental/flash.py +0 -814
  66. modal-1.5.4.dev22/modal/experimental/flash.pyi +0 -481
  67. {modal-1.5.4.dev22 → modal-1.5.5}/LICENSE +0 -0
  68. {modal-1.5.4.dev22 → modal-1.5.5}/README.md +0 -0
  69. {modal-1.5.4.dev22 → modal-1.5.5}/modal/__init__.py +0 -0
  70. {modal-1.5.4.dev22 → modal-1.5.5}/modal/__main__.py +0 -0
  71. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_billing.py +0 -0
  72. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_clustered_functions.py +0 -0
  73. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_clustered_functions.pyi +0 -0
  74. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_grpc_client.py +0 -0
  75. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_ipython.py +0 -0
  76. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_load_context.py +0 -0
  77. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_location.py +0 -0
  78. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_logs.py +0 -0
  79. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_output/__init__.py +0 -0
  80. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_output/manager.py +0 -0
  81. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_output/pty.py +0 -0
  82. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_output/rich.py +0 -0
  83. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_output/status.py +0 -0
  84. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_partial_function.py +0 -0
  85. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_resources.py +0 -0
  86. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_runtime/__init__.py +0 -0
  87. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_runtime/execution_context.py +0 -0
  88. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_runtime/execution_context.pyi +0 -0
  89. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  90. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_runtime/task_lifecycle_manager.py +0 -0
  91. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
  92. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_runtime/telemetry.py +0 -0
  93. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_runtime/user_code_event_loop.py +0 -0
  94. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_server.py +0 -0
  95. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_traceback.py +0 -0
  96. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_tunnel.py +0 -0
  97. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_tunnel.pyi +0 -0
  98. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_type_manager.py +0 -0
  99. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/__init__.py +0 -0
  100. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/app_utils.py +0 -0
  101. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/async_utils.py +0 -0
  102. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/auth_token_manager.py +0 -0
  103. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/blob_utils.py +0 -0
  104. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/browser_utils.py +0 -0
  105. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/bytes_io_segment_payload.py +0 -0
  106. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/curl_utils.py +0 -0
  107. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/display_utils.py +0 -0
  108. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/docker_utils.py +0 -0
  109. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/git_utils.py +0 -0
  110. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/grpc_testing.py +0 -0
  111. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/hash_utils.py +0 -0
  112. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/http_utils.py +0 -0
  113. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/jwt_utils.py +0 -0
  114. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/logger.py +0 -0
  115. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/name_utils.py +0 -0
  116. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/package_utils.py +0 -0
  117. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/pattern_utils.py +0 -0
  118. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/proxy_support.py +0 -0
  119. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/rand_pb_testing.py +0 -0
  120. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/sandbox_fs_utils.py +0 -0
  121. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/shell_utils.py +0 -0
  122. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/task_command_router_client.py +0 -0
  123. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_utils/time_utils.py +0 -0
  124. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_vendor/__init__.py +0 -0
  125. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  126. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_vendor/cloudpickle.py +0 -0
  127. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_vendor/tblib.py +0 -0
  128. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_vendor/version.py +0 -0
  129. {modal-1.5.4.dev22 → modal-1.5.5}/modal/_watcher.py +0 -0
  130. {modal-1.5.4.dev22 → modal-1.5.5}/modal/billing.py +0 -0
  131. {modal-1.5.4.dev22 → modal-1.5.5}/modal/billing.pyi +0 -0
  132. {modal-1.5.4.dev22 → modal-1.5.5}/modal/builder/2023.12.312.txt +0 -0
  133. {modal-1.5.4.dev22 → modal-1.5.5}/modal/builder/2023.12.txt +0 -0
  134. {modal-1.5.4.dev22 → modal-1.5.5}/modal/builder/2024.04.txt +0 -0
  135. {modal-1.5.4.dev22 → modal-1.5.5}/modal/builder/2024.10.txt +0 -0
  136. {modal-1.5.4.dev22 → modal-1.5.5}/modal/builder/2025.06.txt +0 -0
  137. {modal-1.5.4.dev22 → modal-1.5.5}/modal/builder/PREVIEW.txt +0 -0
  138. {modal-1.5.4.dev22 → modal-1.5.5}/modal/builder/README.md +0 -0
  139. {modal-1.5.4.dev22 → modal-1.5.5}/modal/builder/base-images.json +0 -0
  140. {modal-1.5.4.dev22 → modal-1.5.5}/modal/call_graph.py +0 -0
  141. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/__init__.py +0 -0
  142. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/_download.py +0 -0
  143. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/_traceback.py +0 -0
  144. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/billing.py +0 -0
  145. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/bootstrap.py +0 -0
  146. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/cluster.py +0 -0
  147. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/container.py +0 -0
  148. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/curl.py +0 -0
  149. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/dashboard.py +0 -0
  150. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/dict.py +0 -0
  151. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/endpoint.py +0 -0
  152. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/image.py +0 -0
  153. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/logo.py +0 -0
  154. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/network_file_system.py +0 -0
  155. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/programs/__init__.py +0 -0
  156. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/programs/run_jupyter.py +0 -0
  157. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/programs/vscode.py +0 -0
  158. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/queues.py +0 -0
  159. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/secret.py +0 -0
  160. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/selector.py +0 -0
  161. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/skills.py +0 -0
  162. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/utils.py +0 -0
  163. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cli/workspace.py +0 -0
  164. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cloud_bucket_mount.py +0 -0
  165. {modal-1.5.4.dev22 → modal-1.5.5}/modal/cloud_bucket_mount.pyi +0 -0
  166. {modal-1.5.4.dev22 → modal-1.5.5}/modal/container_process.py +0 -0
  167. {modal-1.5.4.dev22 → modal-1.5.5}/modal/container_process.pyi +0 -0
  168. {modal-1.5.4.dev22 → modal-1.5.5}/modal/dict.py +0 -0
  169. {modal-1.5.4.dev22 → modal-1.5.5}/modal/dict.pyi +0 -0
  170. {modal-1.5.4.dev22 → modal-1.5.5}/modal/environments.py +0 -0
  171. {modal-1.5.4.dev22 → modal-1.5.5}/modal/experimental/ipython.py +0 -0
  172. {modal-1.5.4.dev22 → modal-1.5.5}/modal/file_io.py +0 -0
  173. {modal-1.5.4.dev22 → modal-1.5.5}/modal/file_io.pyi +0 -0
  174. {modal-1.5.4.dev22 → modal-1.5.5}/modal/file_pattern_matcher.py +0 -0
  175. {modal-1.5.4.dev22 → modal-1.5.5}/modal/functions.py +0 -0
  176. {modal-1.5.4.dev22 → modal-1.5.5}/modal/image.py +0 -0
  177. {modal-1.5.4.dev22 → modal-1.5.5}/modal/image.pyi +0 -0
  178. {modal-1.5.4.dev22 → modal-1.5.5}/modal/io_streams.py +0 -0
  179. {modal-1.5.4.dev22 → modal-1.5.5}/modal/io_streams.pyi +0 -0
  180. {modal-1.5.4.dev22 → modal-1.5.5}/modal/mount.py +0 -0
  181. {modal-1.5.4.dev22 → modal-1.5.5}/modal/mount.pyi +0 -0
  182. {modal-1.5.4.dev22 → modal-1.5.5}/modal/network_file_system.py +0 -0
  183. {modal-1.5.4.dev22 → modal-1.5.5}/modal/network_file_system.pyi +0 -0
  184. {modal-1.5.4.dev22 → modal-1.5.5}/modal/object.py +0 -0
  185. {modal-1.5.4.dev22 → modal-1.5.5}/modal/output.py +0 -0
  186. {modal-1.5.4.dev22 → modal-1.5.5}/modal/parallel_map.py +0 -0
  187. {modal-1.5.4.dev22 → modal-1.5.5}/modal/parallel_map.pyi +0 -0
  188. {modal-1.5.4.dev22 → modal-1.5.5}/modal/partial_function.py +0 -0
  189. {modal-1.5.4.dev22 → modal-1.5.5}/modal/partial_function.pyi +0 -0
  190. {modal-1.5.4.dev22 → modal-1.5.5}/modal/proxy.py +0 -0
  191. {modal-1.5.4.dev22 → modal-1.5.5}/modal/proxy.pyi +0 -0
  192. {modal-1.5.4.dev22 → modal-1.5.5}/modal/py.typed +0 -0
  193. {modal-1.5.4.dev22 → modal-1.5.5}/modal/queue.py +0 -0
  194. {modal-1.5.4.dev22 → modal-1.5.5}/modal/queue.pyi +0 -0
  195. {modal-1.5.4.dev22 → modal-1.5.5}/modal/retries.py +0 -0
  196. {modal-1.5.4.dev22 → modal-1.5.5}/modal/runner.pyi +0 -0
  197. {modal-1.5.4.dev22 → modal-1.5.5}/modal/running_app.py +0 -0
  198. {modal-1.5.4.dev22 → modal-1.5.5}/modal/sandbox_fs.py +0 -0
  199. {modal-1.5.4.dev22 → modal-1.5.5}/modal/sandbox_fs.pyi +0 -0
  200. {modal-1.5.4.dev22 → modal-1.5.5}/modal/schedule.py +0 -0
  201. {modal-1.5.4.dev22 → modal-1.5.5}/modal/scheduler_placement.py +0 -0
  202. {modal-1.5.4.dev22 → modal-1.5.5}/modal/secret.py +0 -0
  203. {modal-1.5.4.dev22 → modal-1.5.5}/modal/secret.pyi +0 -0
  204. {modal-1.5.4.dev22 → modal-1.5.5}/modal/server.py +0 -0
  205. {modal-1.5.4.dev22 → modal-1.5.5}/modal/server.pyi +0 -0
  206. {modal-1.5.4.dev22 → modal-1.5.5}/modal/serving.py +0 -0
  207. {modal-1.5.4.dev22 → modal-1.5.5}/modal/serving.pyi +0 -0
  208. {modal-1.5.4.dev22 → modal-1.5.5}/modal/snapshot.py +0 -0
  209. {modal-1.5.4.dev22 → modal-1.5.5}/modal/snapshot.pyi +0 -0
  210. {modal-1.5.4.dev22 → modal-1.5.5}/modal/stream_type.py +0 -0
  211. {modal-1.5.4.dev22 → modal-1.5.5}/modal/token_flow.py +0 -0
  212. {modal-1.5.4.dev22 → modal-1.5.5}/modal/token_flow.pyi +0 -0
  213. {modal-1.5.4.dev22 → modal-1.5.5}/modal/volume.py +0 -0
  214. {modal-1.5.4.dev22 → modal-1.5.5}/modal/volume.pyi +0 -0
  215. {modal-1.5.4.dev22 → modal-1.5.5}/modal/workspace.py +0 -0
  216. {modal-1.5.4.dev22 → modal-1.5.5}/modal/workspace.pyi +0 -0
  217. {modal-1.5.4.dev22 → modal-1.5.5}/modal.egg-info/SOURCES.txt +0 -0
  218. {modal-1.5.4.dev22 → modal-1.5.5}/modal.egg-info/dependency_links.txt +0 -0
  219. {modal-1.5.4.dev22 → modal-1.5.5}/modal.egg-info/entry_points.txt +0 -0
  220. {modal-1.5.4.dev22 → modal-1.5.5}/modal.egg-info/requires.txt +0 -0
  221. {modal-1.5.4.dev22 → modal-1.5.5}/modal.egg-info/top_level.txt +0 -0
  222. {modal-1.5.4.dev22 → modal-1.5.5}/modal_docs/__init__.py +0 -0
  223. {modal-1.5.4.dev22 → modal-1.5.5}/modal_docs/gen_cli_docs.py +0 -0
  224. {modal-1.5.4.dev22 → modal-1.5.5}/modal_docs/gen_cli_docs_main.py +0 -0
  225. {modal-1.5.4.dev22 → modal-1.5.5}/modal_docs/gen_reference_docs.py +0 -0
  226. {modal-1.5.4.dev22 → modal-1.5.5}/modal_docs/gen_reference_docs_main.py +0 -0
  227. {modal-1.5.4.dev22 → modal-1.5.5}/modal_docs/mdmd/__init__.py +0 -0
  228. {modal-1.5.4.dev22 → modal-1.5.5}/modal_docs/mdmd/mdmd.py +0 -0
  229. {modal-1.5.4.dev22 → modal-1.5.5}/modal_docs/mdmd/signatures.py +0 -0
  230. {modal-1.5.4.dev22 → modal-1.5.5}/modal_docs/mdmd/types.py +0 -0
  231. {modal-1.5.4.dev22 → modal-1.5.5}/modal_docs/reference_intro.md +0 -0
  232. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/__init__.py +0 -0
  233. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/py.typed +0 -0
  234. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/task_command_router_grpc.py +0 -0
  235. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  236. {modal-1.5.4.dev22 → modal-1.5.5}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  237. {modal-1.5.4.dev22 → modal-1.5.5}/modal_version/__main__.py +0 -0
  238. {modal-1.5.4.dev22 → modal-1.5.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.5.4.dev22
3
+ Version: 1.5.5
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -145,7 +145,7 @@ def call_function(
145
145
  item_count += 1
146
146
 
147
147
  await container_io_manager._send_outputs.aio(
148
- io_context.output_items_generator_done(started_at, item_count)
148
+ io_context, io_context.output_items_generator_done(started_at, item_count)
149
149
  )
150
150
  else:
151
151
  value = await io_context.call_function_async()
@@ -182,7 +182,9 @@ def call_function(
182
182
  container_io_manager._queue_put(generator_queue, value)
183
183
  item_count += 1
184
184
 
185
- container_io_manager._send_outputs(io_context.output_items_generator_done(started_at, item_count))
185
+ container_io_manager._send_outputs(
186
+ io_context, io_context.output_items_generator_done(started_at, item_count)
187
+ )
186
188
  else:
187
189
  values = io_context.call_function_sync()
188
190
  container_io_manager.push_outputs(io_context, started_at, values)
@@ -39,6 +39,7 @@ class _EnvironmentManager:
39
39
  name: str, # Name to use for the new Environment
40
40
  *,
41
41
  restricted: bool = False, # If True, enable RBAC restrictions on the Environment
42
+ default_role: str | None = None, # Default member Role for the Restricted Environment
42
43
  experimental_options: dict[str, Any] | None = None, # Experimental options for Environment creation
43
44
  client: _Client | None = None, # Optional client with Modal credentials
44
45
  ) -> None:
@@ -51,8 +52,11 @@ class _EnvironmentManager:
51
52
  ```
52
53
  """
53
54
  check_environment_name(name)
55
+
54
56
  client = await _Client.from_env() if client is None else client
55
57
  request = api_pb2.EnvironmentCreateRequest(name=name, is_managed=restricted)
58
+ if default_role:
59
+ request.default_member_role_str = default_role
56
60
  if (experimental_options or {}).get("is_public", False):
57
61
  request.environment_type = api_pb2.ENVIRONMENT_TYPE_PUBLIC
58
62
  await client.stub.EnvironmentCreate(request)
@@ -116,9 +120,12 @@ class _EnvironmentRolesManager:
116
120
  """mdmd:hidden"""
117
121
  self._environment = environment
118
122
 
119
- async def list(self) -> dict[Literal["users", "service_users"], dict[str, str]]:
123
+ async def list(self, *, exclude_default: bool = False) -> dict[Literal["users", "service_users"], dict[str, str]]:
120
124
  """Enumerate the Environment Role for each user and service user in the workspace.
121
125
 
126
+ Args:
127
+ exclude_default: If `True`, only include roles that are directly assigned.
128
+
122
129
  **Examples:**
123
130
 
124
131
  ```python notest
@@ -137,6 +144,8 @@ class _EnvironmentRolesManager:
137
144
  users: dict[str, str] = {}
138
145
  service_users: dict[str, str] = {}
139
146
  for principal in resp.principal_roles:
147
+ if exclude_default and not principal.has_role_assignment:
148
+ continue
140
149
  if principal.user_id:
141
150
  users[principal.user_name] = principal.role_str
142
151
  elif principal.service_user_id:
@@ -252,8 +261,8 @@ class _EnvironmentMembersManager:
252
261
  """Remove the Environment Role of users and service users, reverting them to the default."""
253
262
  deprecation_warning(
254
263
  (2026, 7, 23),
255
- "`Environment.members.remove()` is deprecated. Environment Roles are now explicit; "
256
- "set a role (e.g. 'no-access') with `Environment.roles.update()` instead.",
264
+ "`Environment.members.remove()` is deprecated; assign a role (e.g. 'no-access') with "
265
+ "`Environment.roles.update()` instead.",
257
266
  )
258
267
  await self._environment.hydrate()
259
268
  users = users or []
@@ -469,7 +478,7 @@ class _EnvironmentBillingManager:
469
478
  elif end.tzinfo != timezone.utc:
470
479
  raise InvalidError("Timezone-aware 'end' parameter must be in UTC.")
471
480
 
472
- if not self._environment.is_hydrated:
481
+ if not self._environment._is_hydrated:
473
482
  await self._environment.hydrate()
474
483
 
475
484
  request = api_pb2.WorkspaceBillingReportRequest(
@@ -540,7 +549,7 @@ class _EnvironmentBillingManager:
540
549
  if cycle > datetime.now(timezone.utc):
541
550
  raise InvalidError("Provided 'cycle' parameter cannot be in the future.")
542
551
 
543
- if not self._environment.is_hydrated:
552
+ if not self._environment._is_hydrated:
544
553
  await self._environment.hydrate()
545
554
 
546
555
  request = api_pb2.EnvironmentBillingSummaryRequest(environment_id=self._environment.object_id)
@@ -157,7 +157,7 @@ class _FunctionOptions:
157
157
  + list(self.secrets)
158
158
  + [mount.secret for _, mount in self.cloud_bucket_mounts if mount.secret]
159
159
  )
160
- return [dep for dep in all_deps if not dep.is_hydrated]
160
+ return [dep for dep in all_deps if not dep._is_hydrated]
161
161
 
162
162
  def to_proto(self) -> api_pb2.FunctionOptions:
163
163
  """Convert the dataclass to a FunctionOptions protobuf message."""
@@ -246,7 +246,7 @@ def _make_function_variant(
246
246
  load_context: "LoadContext",
247
247
  existing_object_id: str | None,
248
248
  ):
249
- if not base_function.is_hydrated:
249
+ if not base_function._is_hydrated:
250
250
  await base_function.hydrate(load_context.client)
251
251
  assert base_function._client and base_function._client.stub
252
252
 
@@ -290,6 +290,6 @@ def _make_function_variant(
290
290
  deps=_deps,
291
291
  load_context_overrides=base_function._load_context_overrides,
292
292
  )
293
- fun._info = base_function._info
293
+ fun._source_info = base_function._source_info
294
294
  fun._spec = base_function._spec # TODO (elias): fix - this is incorrect when using with_options
295
295
  return fun
@@ -46,10 +46,11 @@ from ._utils.async_utils import (
46
46
  warn_if_generator_is_not_consumed,
47
47
  )
48
48
  from ._utils.blob_utils import MAX_ASYNC_OBJECT_SIZE_BYTES, MAX_OBJECT_SIZE_BYTES
49
+ from ._utils.deprecation import with_deprecation_warning
49
50
  from ._utils.function_utils import (
50
51
  ATTEMPT_TIMEOUT_GRACE_PERIOD,
51
52
  OUTPUTS_TIMEOUT,
52
- FunctionInfo,
53
+ FunctionSourceInfo,
53
54
  _create_input,
54
55
  _parse_retries,
55
56
  _process_result,
@@ -603,7 +604,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
603
604
  """
604
605
 
605
606
  # TODO: more type annotations
606
- _info: FunctionInfo | None
607
+ _source_info: FunctionSourceInfo | None
607
608
  _serve_mounts: frozenset[_Mount] # set at load time, only by loader
608
609
  _app: "modal.app._App | None" = None
609
610
  # only set for InstanceServiceFunctions and bound instance methods
@@ -640,7 +641,12 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
640
641
  await self.hydrate()
641
642
  if not self._app_id:
642
643
  raise ExecutionError("app_id should have been set during function hydration")
643
- return _LogQueryData(self.client, self._app_id, LogsFilters(function_id=self.object_id))
644
+ return _LogQueryData(
645
+ self.client,
646
+ self._app_id,
647
+ LogsFilters(function_id=self.object_id),
648
+ source_object_id=self.object_id,
649
+ )
644
650
 
645
651
  @property
646
652
  def logs(self) -> _FunctionLogsManager:
@@ -658,8 +664,8 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
658
664
  return _FunctionLogsManager(self)
659
665
 
660
666
  @staticmethod
661
- def from_local(
662
- info: FunctionInfo,
667
+ def _from_local(
668
+ info: FunctionSourceInfo,
663
669
  app: "modal.app._App | None", # App here should only be None in case of Image.run_function
664
670
  image: _Image,
665
671
  env: dict[str, str | None] | None = None,
@@ -932,7 +938,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
932
938
  with FunctionCreationStatus(tag) as function_creation_status:
933
939
  timeout_secs = timeout
934
940
 
935
- if app and app.is_interactive and not is_builder_function:
941
+ if app and app._is_interactive_ and not is_builder_function:
936
942
  pty_info = get_pty_info(shell=False)
937
943
  else:
938
944
  pty_info = None
@@ -1105,6 +1111,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1105
1111
  http_config=http_config,
1106
1112
  is_server=function_definition.is_server,
1107
1113
  routing_region=function_definition.routing_region,
1114
+ is_sessioned=function_definition.is_sessioned,
1108
1115
  )
1109
1116
 
1110
1117
  ranked_functions = []
@@ -1158,10 +1165,12 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1158
1165
  # the only way to infer a LoadContext for an `@app.function`, and the App doesn't
1159
1166
  # get its client until *after* the Function is created.
1160
1167
  load_context = app._root_load_context if app else LoadContext.empty()
1161
- obj = _Function._from_loader(_load, rep, preload=_preload, deps=_deps, load_context_overrides=load_context)
1168
+ obj: _Function = _Function._from_loader(
1169
+ _load, rep, preload=_preload, deps=_deps, load_context_overrides=load_context
1170
+ )
1162
1171
 
1163
1172
  obj._raw_f = info.raw_f
1164
- obj._info = info
1173
+ obj._source_info = info
1165
1174
  obj._tag = tag
1166
1175
  obj._app = app # needed for CLI right now
1167
1176
  obj._obj = None
@@ -1186,6 +1195,12 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1186
1195
 
1187
1196
  return obj
1188
1197
 
1198
+ from_local = with_deprecation_warning(
1199
+ (2026, 8, 26),
1200
+ "`Function.from_local` is deprecated and will be removed in `modal` version 1.6.0",
1201
+ )(_from_local)
1202
+ """mdmd:hidden"""
1203
+
1189
1204
  async def _update_autoscaler(
1190
1205
  self,
1191
1206
  *,
@@ -1378,8 +1393,16 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1378
1393
  )
1379
1394
 
1380
1395
  @property
1396
+ @with_deprecation_warning(
1397
+ (2026, 8, 26),
1398
+ "`Function.tag` is deprecated and will be removed in `modal` version 1.6.0",
1399
+ )
1381
1400
  def tag(self) -> str:
1382
1401
  """mdmd:hidden"""
1402
+ return self._tag_
1403
+
1404
+ @property
1405
+ def _tag_(self) -> str:
1383
1406
  assert self._tag
1384
1407
  return self._tag
1385
1408
 
@@ -1392,20 +1415,40 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1392
1415
  return self._app
1393
1416
 
1394
1417
  @property
1418
+ @with_deprecation_warning(
1419
+ (2026, 8, 26),
1420
+ "`Function.stub` is deprecated and will be removed in `modal` version 1.6.0",
1421
+ )
1395
1422
  def stub(self) -> "modal.app._App":
1396
1423
  """mdmd:hidden"""
1397
1424
  # Deprecated soon, only for backwards compatibility
1398
1425
  return self.app
1399
1426
 
1400
1427
  @property
1401
- def info(self) -> FunctionInfo:
1428
+ @with_deprecation_warning(
1429
+ (2026, 8, 26),
1430
+ "`Function.info` is deprecated and will be removed in `modal` version 1.6.0",
1431
+ )
1432
+ def info(self) -> FunctionSourceInfo:
1402
1433
  """mdmd:hidden"""
1403
- assert self._info
1404
- return self._info
1434
+ return self._source_info_
1405
1435
 
1406
1436
  @property
1437
+ def _source_info_(self) -> FunctionSourceInfo:
1438
+ assert self._source_info
1439
+ return self._source_info
1440
+
1441
+ @property
1442
+ @with_deprecation_warning(
1443
+ (2026, 8, 26),
1444
+ "`Function.spec` is deprecated and will be removed in `modal` version 1.6.0",
1445
+ )
1407
1446
  def spec(self) -> _FunctionSpec:
1408
1447
  """mdmd:hidden"""
1448
+ return self._spec_
1449
+
1450
+ @property
1451
+ def _spec_(self) -> _FunctionSpec:
1409
1452
  assert self._spec
1410
1453
  return self._spec
1411
1454
 
@@ -1413,13 +1456,19 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1413
1456
  # only defined in definition scope/locally, and not for class methods at the moment
1414
1457
  return bool(self._webhook_config and self._webhook_config.type != api_pb2.WEBHOOK_TYPE_UNSPECIFIED)
1415
1458
 
1416
- def get_build_def(self) -> str:
1459
+ def _get_build_def(self) -> str:
1417
1460
  """mdmd:hidden"""
1418
1461
  # Plaintext source and arg definition for the function, so it's part of the image
1419
1462
  # hash. We can't use the cloudpickle hash because it's not very stable.
1420
1463
  assert hasattr(self, "_raw_f") and hasattr(self, "_build_args") and self._raw_f is not None
1421
1464
  return f"{inspect.getsource(self._raw_f)}\n{repr(self._build_args)}"
1422
1465
 
1466
+ get_build_def = with_deprecation_warning(
1467
+ (2026, 8, 26),
1468
+ "`Function.get_build_def` is deprecated and will be removed in `modal` version 1.6.0",
1469
+ )(_get_build_def)
1470
+ """mdmd:hidden"""
1471
+
1423
1472
  # Live handle methods
1424
1473
 
1425
1474
  def _initialize_from_empty(self):
@@ -1428,7 +1477,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1428
1477
  self._is_generator = None
1429
1478
  self._web_url = None
1430
1479
  self._function_name = None
1431
- self._info = None
1480
+ self._source_info = None
1432
1481
  self._serve_mounts = frozenset()
1433
1482
  self._metadata = None
1434
1483
  self._experimental_flash_urls = None
@@ -1560,7 +1609,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1560
1609
  new_function._webhook_config = self._webhook_config
1561
1610
 
1562
1611
  # Other fields not necessarily initialized
1563
- if self._info is not None:
1612
+ if self._source_info is not None:
1564
1613
  new_function._build_args = self._build_args
1565
1614
  new_function._is_method = self._is_method
1566
1615
  new_function._raw_f = self._raw_f
@@ -1667,8 +1716,16 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1667
1716
  return self._apply_dynamic_config(options, "with_batching")
1668
1717
 
1669
1718
  @property
1719
+ @with_deprecation_warning(
1720
+ (2026, 8, 26),
1721
+ "`Function.is_generator` is deprecated and will be removed in `modal` version 1.6.0",
1722
+ )
1670
1723
  async def is_generator(self) -> bool:
1671
1724
  """mdmd:hidden"""
1725
+ return await self._is_generator_
1726
+
1727
+ @property
1728
+ async def _is_generator_(self) -> bool:
1672
1729
  # hacky: kind of like @live_method, but not hydrating if we have the value already from local source
1673
1730
  # TODO(michael) use a common / lightweight method for handling unhydrated metadata properties
1674
1731
  if self._is_generator is not None:
@@ -1858,12 +1915,12 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1858
1915
  yield item
1859
1916
 
1860
1917
  def _is_local(self):
1861
- return self._info is not None
1918
+ return self._source_info is not None
1862
1919
 
1863
- def _get_info(self) -> FunctionInfo:
1864
- if not self._info:
1865
- raise ExecutionError("Can't get info for a function that isn't locally defined")
1866
- return self._info
1920
+ def _get_source_info(self) -> FunctionSourceInfo:
1921
+ if not self._source_info:
1922
+ raise ExecutionError("Can't get source info for a function that isn't locally defined")
1923
+ return self._source_info
1867
1924
 
1868
1925
  def _get_obj(self) -> "modal.cls._Obj | None":
1869
1926
  if not self._is_method:
@@ -1898,13 +1955,13 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1898
1955
  )
1899
1956
  raise ExecutionError(msg)
1900
1957
 
1901
- info = self._get_info()
1958
+ info = self._get_source_info()
1902
1959
  if not info.raw_f:
1903
1960
  # Here if calling .local on a service function itself which should never happen
1904
1961
  # TODO: check if we end up here in a container for a serialized function?
1905
1962
  raise ExecutionError("Can't call .local on service function")
1906
1963
 
1907
- if is_local() and self.spec.volumes or self.spec.network_file_systems:
1964
+ if is_local() and self._spec_.volumes or self._spec_.network_file_systems:
1908
1965
  warnings.warn(
1909
1966
  f"The {info.function_name} function is executing locally "
1910
1967
  + "and will not have access to the mounted Volume or NetworkFileSystem data"
@@ -2002,12 +2059,20 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
2002
2059
  fc._function_id = self.object_id
2003
2060
  return fc
2004
2061
 
2062
+ @with_deprecation_warning(
2063
+ (2026, 8, 26),
2064
+ "`Function.get_raw_f` is deprecated and will be removed in `modal` version 1.6.0",
2065
+ )
2005
2066
  def get_raw_f(self) -> Callable[..., Any]:
2006
2067
  """Return the inner Python object wrapped by this Modal Function.
2007
2068
 
2008
2069
  Returns:
2009
2070
  The original function object registered with Modal.
2010
2071
  """
2072
+ return self._raw_f_
2073
+
2074
+ @property
2075
+ def _raw_f_(self) -> Callable[..., Any]:
2011
2076
  assert self._raw_f is not None
2012
2077
  return self._raw_f
2013
2078
 
@@ -2077,7 +2142,12 @@ class _FunctionCall(typing.Generic[ReturnType], _Object, type_prefix="fc"):
2077
2142
  await self._hydrate_from_id_metadata()
2078
2143
  if not self._app_id:
2079
2144
  raise ExecutionError("app_id should have been set during function call hydration")
2080
- return _LogQueryData(self.client, self._app_id, LogsFilters(function_call_id=self.object_id))
2145
+ return _LogQueryData(
2146
+ self.client,
2147
+ self._app_id,
2148
+ LogsFilters(function_call_id=self.object_id),
2149
+ source_object_id=self.object_id,
2150
+ )
2081
2151
 
2082
2152
  @property
2083
2153
  def logs(self) -> _FunctionCallLogsManager:
@@ -41,7 +41,7 @@ from ._utils.docker_utils import (
41
41
  extract_copy_command_patterns,
42
42
  find_dockerignore_file,
43
43
  )
44
- from ._utils.function_utils import FunctionInfo, parse_gpu_config
44
+ from ._utils.function_utils import FunctionSourceInfo, parse_gpu_config
45
45
  from ._utils.mount_utils import validate_only_modal_volumes, validate_volumes_by_object_id
46
46
  from ._utils.name_utils import check_object_name
47
47
  from .client import _Client
@@ -681,8 +681,8 @@ class _Image(_Object, type_prefix="im"):
681
681
 
682
682
  if build_function:
683
683
  build_function_id = build_function.object_id
684
- globals = build_function._get_info().get_globals()
685
- attrs = build_function._get_info().get_cls_var_attrs()
684
+ globals = build_function._get_source_info().get_globals()
685
+ attrs = build_function._get_source_info().get_cls_var_attrs()
686
686
  globals = {**globals, **attrs}
687
687
  filtered_globals = {}
688
688
  for k, v in globals.items():
@@ -694,7 +694,7 @@ class _Image(_Object, type_prefix="im"):
694
694
  # Skip unserializable values for now.
695
695
  logger.warning(
696
696
  f"Skipping unserializable global variable {k} for "
697
- f"{build_function._get_info().function_name}. "
697
+ f"{build_function._get_source_info().function_name}. "
698
698
  "Changes to this variable won't invalidate the image."
699
699
  )
700
700
  continue
@@ -704,7 +704,7 @@ class _Image(_Object, type_prefix="im"):
704
704
  # TODO: better way to filter out types that don't have a stable hash?
705
705
  build_function_globals = serialize(filtered_globals) if filtered_globals else b""
706
706
  _build_function = api_pb2.BuildFunction(
707
- definition=build_function.get_build_def(),
707
+ definition=build_function._get_build_def(),
708
708
  globals=build_function_globals,
709
709
  input=build_function_input,
710
710
  )
@@ -764,7 +764,10 @@ class _Image(_Object, type_prefix="im"):
764
764
  if build_resp.HasField("metadata"):
765
765
  metadata = build_resp.metadata
766
766
 
767
- if result.status == api_pb2.GenericResult.GENERIC_STATUS_FAILURE:
767
+ if result.status in (
768
+ api_pb2.GenericResult.GENERIC_STATUS_FAILURE,
769
+ api_pb2.GenericResult.GENERIC_STATUS_MEMORY_MANAGER_EVICTION,
770
+ ):
768
771
  if result.exception:
769
772
  raise ImageBuildError(
770
773
  f"Image build for {image_id} failed with the exception:\n{result.exception}", image_id
@@ -2751,9 +2754,9 @@ class _Image(_Object, type_prefix="im"):
2751
2754
  # It may be possible to support lambdas eventually, but for now we don't handle them well, so reject quickly
2752
2755
  raise InvalidError("Image.run_function does not support lambda functions.")
2753
2756
 
2754
- info = FunctionInfo(raw_f)
2757
+ info = FunctionSourceInfo(raw_f)
2755
2758
 
2756
- function = _Function.from_local(
2759
+ function = _Function._from_local(
2757
2760
  info,
2758
2761
  app=None,
2759
2762
  image=self,
@@ -2935,7 +2938,7 @@ class _Image(_Object, type_prefix="im"):
2935
2938
  try:
2936
2939
  yield
2937
2940
  except Exception as exc:
2938
- if not self.is_hydrated:
2941
+ if not self._is_hydrated:
2939
2942
  # Might be hydrated later (if it's the container's used image)
2940
2943
  self.inside_exceptions.append(exc)
2941
2944
  elif env_image_id == self.object_id:
@@ -3048,7 +3051,7 @@ class _Image(_Object, type_prefix="im"):
3048
3051
  """mdmd:hidden"""
3049
3052
  # Image inherits hydrate() from Object but can't be hydrated on demand
3050
3053
  # Overriding the method lets us hide it from the docs and raise a better error message
3051
- if not self.is_hydrated:
3054
+ if not self._is_hydrated:
3052
3055
  raise ExecutionError(
3053
3056
  "Images cannot currently be hydrated on demand; you can build an Image by running an App that uses it."
3054
3057
  )