modal 1.5.5.dev15__tar.gz → 1.5.5.dev17__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 (236) hide show
  1. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/PKG-INFO +1 -1
  2. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_environments.py +2 -2
  3. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_function_variants.py +2 -2
  4. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_functions.py +35 -4
  5. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_image.py +4 -4
  6. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_object.py +30 -3
  7. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_resolver.py +5 -5
  8. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_runtime/user_code_imports.py +5 -5
  9. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_serialization.py +3 -1
  10. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/deprecation.py +29 -0
  11. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/mount_utils.py +1 -1
  12. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_workspace.py +6 -6
  13. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/app.py +43 -17
  14. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/config.py +5 -1
  15. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/import_refs.py +9 -4
  16. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/launch.py +1 -1
  17. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/run.py +7 -7
  18. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/shell.py +2 -2
  19. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/client.py +137 -20
  20. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/client.pyi +124 -3
  21. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cls.py +22 -15
  22. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/config.py +15 -7
  23. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/exception.py +13 -2
  24. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/object.pyi +7 -1
  25. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/runner.py +6 -6
  26. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/sandbox.py +62 -11
  27. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/sandbox.pyi +12 -12
  28. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal.egg-info/PKG-INFO +1 -1
  29. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/api_grpc.py +16 -0
  30. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/api_pb2.py +838 -808
  31. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/api_pb2.pyi +138 -5
  32. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/api_pb2_grpc.py +33 -0
  33. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/api_pb2_grpc.pyi +10 -0
  34. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/modal_api_grpc.py +1 -0
  35. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/task_command_router_pb2.py +34 -34
  36. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/task_command_router_pb2.pyi +15 -3
  37. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_version/__init__.py +1 -1
  38. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/pyproject.toml +1 -1
  39. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/LICENSE +0 -0
  40. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/README.md +0 -0
  41. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/__init__.py +0 -0
  42. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/__main__.py +0 -0
  43. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_billing.py +0 -0
  44. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_clustered_functions.py +0 -0
  45. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_clustered_functions.pyi +0 -0
  46. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_container_entrypoint.py +0 -0
  47. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_grpc_client.py +0 -0
  48. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_ipython.py +0 -0
  49. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_load_context.py +0 -0
  50. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_location.py +0 -0
  51. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_logs.py +0 -0
  52. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_logs_manager.py +0 -0
  53. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_logs_manager.pyi +0 -0
  54. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_output/__init__.py +0 -0
  55. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_output/manager.py +0 -0
  56. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_output/pty.py +0 -0
  57. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_output/rich.py +0 -0
  58. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_output/status.py +0 -0
  59. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_partial_function.py +0 -0
  60. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_resources.py +0 -0
  61. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_runtime/__init__.py +0 -0
  62. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_runtime/asgi.py +0 -0
  63. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_runtime/container_io_manager.py +0 -0
  64. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_runtime/container_io_manager.pyi +0 -0
  65. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_runtime/execution_context.py +0 -0
  66. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_runtime/execution_context.pyi +0 -0
  67. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  68. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_runtime/task_lifecycle_manager.py +0 -0
  69. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
  70. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_runtime/telemetry.py +0 -0
  71. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_runtime/user_code_event_loop.py +0 -0
  72. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_server.py +0 -0
  73. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_supports_logs.py +0 -0
  74. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_traceback.py +0 -0
  75. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_tunnel.py +0 -0
  76. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_tunnel.pyi +0 -0
  77. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_type_manager.py +0 -0
  78. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/__init__.py +0 -0
  79. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/app_utils.py +0 -0
  80. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/async_utils.py +0 -0
  81. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/auth_token_manager.py +0 -0
  82. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/blob_utils.py +0 -0
  83. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/browser_utils.py +0 -0
  84. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/bytes_io_segment_payload.py +0 -0
  85. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/curl_utils.py +0 -0
  86. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/display_utils.py +0 -0
  87. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/docker_utils.py +0 -0
  88. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/function_utils.py +0 -0
  89. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/git_utils.py +0 -0
  90. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/grpc_testing.py +0 -0
  91. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/grpc_utils.py +0 -0
  92. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/hash_utils.py +0 -0
  93. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/http_utils.py +0 -0
  94. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/jwt_utils.py +0 -0
  95. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/logger.py +0 -0
  96. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/name_utils.py +0 -0
  97. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/package_utils.py +0 -0
  98. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/pattern_utils.py +0 -0
  99. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/proxy_support.py +0 -0
  100. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/rand_pb_testing.py +0 -0
  101. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/sandbox_fs_utils.py +0 -0
  102. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/shell_utils.py +0 -0
  103. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/task_command_router_client.py +0 -0
  104. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_utils/time_utils.py +0 -0
  105. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_vendor/__init__.py +0 -0
  106. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  107. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_vendor/cloudpickle.py +0 -0
  108. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_vendor/tblib.py +0 -0
  109. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_vendor/version.py +0 -0
  110. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/_watcher.py +0 -0
  111. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/app.pyi +0 -0
  112. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/billing.py +0 -0
  113. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/billing.pyi +0 -0
  114. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/builder/2023.12.312.txt +0 -0
  115. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/builder/2023.12.txt +0 -0
  116. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/builder/2024.04.txt +0 -0
  117. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/builder/2024.10.txt +0 -0
  118. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/builder/2025.06.txt +0 -0
  119. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/builder/PREVIEW.txt +0 -0
  120. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/builder/README.md +0 -0
  121. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/builder/base-images.json +0 -0
  122. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/call_graph.py +0 -0
  123. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/__init__.py +0 -0
  124. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/_download.py +0 -0
  125. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/_help.py +0 -0
  126. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/_traceback.py +0 -0
  127. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/app.py +0 -0
  128. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/billing.py +0 -0
  129. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/bootstrap.py +0 -0
  130. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/changelog.py +0 -0
  131. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/cluster.py +0 -0
  132. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/container.py +0 -0
  133. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/curl.py +0 -0
  134. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/dashboard.py +0 -0
  135. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/dict.py +0 -0
  136. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/endpoint.py +0 -0
  137. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/entry_point.py +0 -0
  138. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/environment.py +0 -0
  139. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/image.py +0 -0
  140. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/logo.py +0 -0
  141. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/network_file_system.py +0 -0
  142. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/profile.py +0 -0
  143. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/programs/__init__.py +0 -0
  144. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/programs/run_jupyter.py +0 -0
  145. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/programs/vscode.py +0 -0
  146. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/queues.py +0 -0
  147. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/secret.py +0 -0
  148. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/selector.py +0 -0
  149. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/skills.py +0 -0
  150. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/token.py +0 -0
  151. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/utils.py +0 -0
  152. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/volume.py +0 -0
  153. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cli/workspace.py +0 -0
  154. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cloud_bucket_mount.py +0 -0
  155. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cloud_bucket_mount.pyi +0 -0
  156. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/cls.pyi +0 -0
  157. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/container_process.py +0 -0
  158. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/container_process.pyi +0 -0
  159. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/dict.py +0 -0
  160. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/dict.pyi +0 -0
  161. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/environments.py +0 -0
  162. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/environments.pyi +0 -0
  163. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/experimental/__init__.py +0 -0
  164. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/experimental/flash.py +0 -0
  165. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/experimental/flash.pyi +0 -0
  166. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/experimental/ipython.py +0 -0
  167. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/file_io.py +0 -0
  168. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/file_io.pyi +0 -0
  169. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/file_pattern_matcher.py +0 -0
  170. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/functions.py +0 -0
  171. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/functions.pyi +0 -0
  172. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/image.py +0 -0
  173. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/image.pyi +0 -0
  174. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/io_streams.py +0 -0
  175. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/io_streams.pyi +0 -0
  176. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/mount.py +0 -0
  177. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/mount.pyi +0 -0
  178. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/network_file_system.py +0 -0
  179. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/network_file_system.pyi +0 -0
  180. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/object.py +0 -0
  181. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/output.py +0 -0
  182. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/parallel_map.py +0 -0
  183. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/parallel_map.pyi +0 -0
  184. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/partial_function.py +0 -0
  185. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/partial_function.pyi +0 -0
  186. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/proxy.py +0 -0
  187. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/proxy.pyi +0 -0
  188. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/py.typed +0 -0
  189. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/queue.py +0 -0
  190. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/queue.pyi +0 -0
  191. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/retries.py +0 -0
  192. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/runner.pyi +0 -0
  193. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/running_app.py +0 -0
  194. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/sandbox_fs.py +0 -0
  195. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/sandbox_fs.pyi +0 -0
  196. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/schedule.py +0 -0
  197. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/scheduler_placement.py +0 -0
  198. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/secret.py +0 -0
  199. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/secret.pyi +0 -0
  200. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/server.py +0 -0
  201. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/server.pyi +0 -0
  202. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/serving.py +0 -0
  203. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/serving.pyi +0 -0
  204. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/skills/modal/SKILL.md +0 -0
  205. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/snapshot.py +0 -0
  206. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/snapshot.pyi +0 -0
  207. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/stream_type.py +0 -0
  208. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/token_flow.py +0 -0
  209. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/token_flow.pyi +0 -0
  210. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/types.py +0 -0
  211. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/volume.py +0 -0
  212. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/volume.pyi +0 -0
  213. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/workspace.py +0 -0
  214. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal/workspace.pyi +0 -0
  215. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal.egg-info/SOURCES.txt +0 -0
  216. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal.egg-info/dependency_links.txt +0 -0
  217. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal.egg-info/entry_points.txt +0 -0
  218. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal.egg-info/requires.txt +0 -0
  219. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal.egg-info/top_level.txt +0 -0
  220. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_docs/__init__.py +0 -0
  221. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_docs/gen_cli_docs.py +0 -0
  222. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_docs/gen_cli_docs_main.py +0 -0
  223. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_docs/gen_reference_docs.py +0 -0
  224. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_docs/gen_reference_docs_main.py +0 -0
  225. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_docs/mdmd/__init__.py +0 -0
  226. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_docs/mdmd/mdmd.py +0 -0
  227. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_docs/mdmd/signatures.py +0 -0
  228. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_docs/mdmd/types.py +0 -0
  229. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_docs/reference_intro.md +0 -0
  230. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/__init__.py +0 -0
  231. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/py.typed +0 -0
  232. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/task_command_router_grpc.py +0 -0
  233. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  234. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  235. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/modal_version/__main__.py +0 -0
  236. {modal-1.5.5.dev15 → modal-1.5.5.dev17}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.5.5.dev15
3
+ Version: 1.5.5.dev17
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -478,7 +478,7 @@ class _EnvironmentBillingManager:
478
478
  elif end.tzinfo != timezone.utc:
479
479
  raise InvalidError("Timezone-aware 'end' parameter must be in UTC.")
480
480
 
481
- if not self._environment.is_hydrated:
481
+ if not self._environment._is_hydrated:
482
482
  await self._environment.hydrate()
483
483
 
484
484
  request = api_pb2.WorkspaceBillingReportRequest(
@@ -549,7 +549,7 @@ class _EnvironmentBillingManager:
549
549
  if cycle > datetime.now(timezone.utc):
550
550
  raise InvalidError("Provided 'cycle' parameter cannot be in the future.")
551
551
 
552
- if not self._environment.is_hydrated:
552
+ if not self._environment._is_hydrated:
553
553
  await self._environment.hydrate()
554
554
 
555
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
 
@@ -46,6 +46,7 @@ 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,
@@ -937,7 +938,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
937
938
  with FunctionCreationStatus(tag) as function_creation_status:
938
939
  timeout_secs = timeout
939
940
 
940
- if app and app.is_interactive and not is_builder_function:
941
+ if app and app._is_interactive_ and not is_builder_function:
941
942
  pty_info = get_pty_info(shell=False)
942
943
  else:
943
944
  pty_info = None
@@ -1194,7 +1195,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1194
1195
 
1195
1196
  return obj
1196
1197
 
1197
- from_local = _from_local
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)
1198
1202
  """mdmd:hidden"""
1199
1203
 
1200
1204
  async def _update_autoscaler(
@@ -1389,6 +1393,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1389
1393
  )
1390
1394
 
1391
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
+ )
1392
1400
  def tag(self) -> str:
1393
1401
  """mdmd:hidden"""
1394
1402
  return self._tag_
@@ -1407,12 +1415,20 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1407
1415
  return self._app
1408
1416
 
1409
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
+ )
1410
1422
  def stub(self) -> "modal.app._App":
1411
1423
  """mdmd:hidden"""
1412
1424
  # Deprecated soon, only for backwards compatibility
1413
1425
  return self.app
1414
1426
 
1415
1427
  @property
1428
+ @with_deprecation_warning(
1429
+ (2026, 8, 26),
1430
+ "`Function.info` is deprecated and will be removed in `modal` version 1.6.0",
1431
+ )
1416
1432
  def info(self) -> FunctionInfo:
1417
1433
  """mdmd:hidden"""
1418
1434
  return self._info_
@@ -1423,6 +1439,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1423
1439
  return self._info
1424
1440
 
1425
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
+ )
1426
1446
  def spec(self) -> _FunctionSpec:
1427
1447
  """mdmd:hidden"""
1428
1448
  return self._spec_
@@ -1443,7 +1463,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1443
1463
  assert hasattr(self, "_raw_f") and hasattr(self, "_build_args") and self._raw_f is not None
1444
1464
  return f"{inspect.getsource(self._raw_f)}\n{repr(self._build_args)}"
1445
1465
 
1446
- get_build_def = _get_build_def
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)
1447
1470
  """mdmd:hidden"""
1448
1471
 
1449
1472
  # Live handle methods
@@ -1693,6 +1716,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1693
1716
  return self._apply_dynamic_config(options, "with_batching")
1694
1717
 
1695
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
+ )
1696
1723
  async def is_generator(self) -> bool:
1697
1724
  """mdmd:hidden"""
1698
1725
  return await self._is_generator_
@@ -1934,7 +1961,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1934
1961
  # TODO: check if we end up here in a container for a serialized function?
1935
1962
  raise ExecutionError("Can't call .local on service function")
1936
1963
 
1937
- 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:
1938
1965
  warnings.warn(
1939
1966
  f"The {info.function_name} function is executing locally "
1940
1967
  + "and will not have access to the mounted Volume or NetworkFileSystem data"
@@ -2032,6 +2059,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
2032
2059
  fc._function_id = self.object_id
2033
2060
  return fc
2034
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
+ )
2035
2066
  def get_raw_f(self) -> Callable[..., Any]:
2036
2067
  """Return the inner Python object wrapped by this Modal Function.
2037
2068
 
@@ -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
  )
@@ -2756,7 +2756,7 @@ class _Image(_Object, type_prefix="im"):
2756
2756
 
2757
2757
  info = FunctionInfo(raw_f)
2758
2758
 
2759
- function = _Function.from_local(
2759
+ function = _Function._from_local(
2760
2760
  info,
2761
2761
  app=None,
2762
2762
  image=self,
@@ -2938,7 +2938,7 @@ class _Image(_Object, type_prefix="im"):
2938
2938
  try:
2939
2939
  yield
2940
2940
  except Exception as exc:
2941
- if not self.is_hydrated:
2941
+ if not self._is_hydrated:
2942
2942
  # Might be hydrated later (if it's the container's used image)
2943
2943
  self.inside_exceptions.append(exc)
2944
2944
  elif env_image_id == self.object_id:
@@ -3051,7 +3051,7 @@ class _Image(_Object, type_prefix="im"):
3051
3051
  """mdmd:hidden"""
3052
3052
  # Image inherits hydrate() from Object but can't be hydrated on demand
3053
3053
  # Overriding the method lets us hide it from the docs and raise a better error message
3054
- if not self.is_hydrated:
3054
+ if not self._is_hydrated:
3055
3055
  raise ExecutionError(
3056
3056
  "Images cannot currently be hydrated on demand; you can build an Image by running an App that uses it."
3057
3057
  )
@@ -9,11 +9,11 @@ from typing import ClassVar
9
9
  from google.protobuf.message import Message
10
10
  from typing_extensions import Self
11
11
 
12
- from modal._traceback import suppress_tb_frame
13
-
14
12
  from ._load_context import LoadContext
15
13
  from ._resolver import Resolver
14
+ from ._traceback import suppress_tb_frame
16
15
  from ._utils.async_utils import TaskContext, aclosing
16
+ from ._utils.deprecation import deprecation_warning
17
17
  from .client import _Client
18
18
  from .config import config, logger
19
19
  from .exception import ExecutionError, InvalidError
@@ -91,13 +91,21 @@ class _Object:
91
91
  # For hydrated objects
92
92
  _object_id: str | None
93
93
  _client: _Client | None
94
- _is_hydrated: bool
94
+ __is_hydrated: bool
95
95
  _is_rehydrated: bool
96
96
 
97
97
  # Not all object subclasses have a meaningful "name" concept
98
98
  # So whether they expose this is a matter of having a name property
99
99
  _name: str | None
100
100
 
101
+ @property
102
+ def _is_hydrated(self) -> bool:
103
+ return self.__is_hydrated
104
+
105
+ @_is_hydrated.setter
106
+ def _is_hydrated(self, value: bool):
107
+ self.__is_hydrated = value
108
+
101
109
  @classmethod
102
110
  def __init_subclass__(cls, type_prefix: str | None = None):
103
111
  super().__init_subclass__()
@@ -281,9 +289,18 @@ class _Object:
281
289
  def __repr__(self):
282
290
  return self._rep
283
291
 
292
+ @property
293
+ def _class_name(self):
294
+ return self.__class__.__name__.removeprefix("_")
295
+
284
296
  @property
285
297
  def local_uuid(self):
286
298
  """mdmd:hidden"""
299
+ deprecation_warning(
300
+ (2026, 8, 26),
301
+ f"`{self._class_name}.local_uuid` is deprecated and will be removed in `modal` version 1.6.0",
302
+ )
303
+
287
304
  return self._local_uuid
288
305
 
289
306
  @property
@@ -308,11 +325,21 @@ class _Object:
308
325
  @property
309
326
  def is_hydrated(self) -> bool:
310
327
  """mdmd:hidden"""
328
+ deprecation_warning(
329
+ (2026, 8, 26),
330
+ f"`{self._class_name}.is_hydrated` is deprecated and will be removed in `modal` version 1.6.0",
331
+ )
332
+
311
333
  return self._is_hydrated
312
334
 
313
335
  @property
314
336
  def deps(self) -> Callable[..., Sequence["_Object"]]:
315
337
  """mdmd:hidden"""
338
+ deprecation_warning(
339
+ (2026, 8, 26),
340
+ f"`{self._class_name}.deps` is deprecated and will be removed in `modal` version 1.6.0",
341
+ )
342
+
316
343
  return self._deps_
317
344
 
318
345
  @property
@@ -44,19 +44,19 @@ class Resolver:
44
44
  existing_object_id: str | None = None,
45
45
  ):
46
46
  if obj._is_hydrated and obj._skip_reload:
47
- if obj.local_uuid not in self._local_uuid_to_future:
47
+ if obj._local_uuid not in self._local_uuid_to_future:
48
48
  # a bit dumb - but we still need to store a reference to the object here
49
49
  # to be able to include all referenced objects when setting up the app
50
50
  fut: Future = Future()
51
51
  fut.set_result(obj)
52
- self._local_uuid_to_future[obj.local_uuid] = fut
52
+ self._local_uuid_to_future[obj._local_uuid] = fut
53
53
  return obj
54
54
 
55
55
  deduplication_key: Hashable | None = None
56
56
  if obj._deduplication_key:
57
57
  deduplication_key = await obj._deduplication_key()
58
58
 
59
- cached_future = self._local_uuid_to_future.get(obj.local_uuid)
59
+ cached_future = self._local_uuid_to_future.get(obj._local_uuid)
60
60
 
61
61
  if not cached_future and deduplication_key is not None:
62
62
  # deduplication cache makes sure duplicate mounts are resolved only
@@ -78,7 +78,7 @@ class Resolver:
78
78
  # Use asyncio.gather here (not TaskContext.gather) - the shared TaskContext
79
79
  # in load_context handles cancellation at the top level, preventing premature
80
80
  # cancellation of shared dependencies when sibling tasks fail.
81
- await asyncio.gather(*[self.load(dep, load_context) for dep in obj.deps()])
81
+ await asyncio.gather(*[self.load(dep, load_context) for dep in obj._deps_()])
82
82
 
83
83
  # Load the object itself
84
84
  if not obj._load:
@@ -102,7 +102,7 @@ class Resolver:
102
102
 
103
103
  # use task_context from load_context to make sure tasks are cleaned up eventually
104
104
  cached_future = parent_load_context.task_context.create_task(loader())
105
- self._local_uuid_to_future[obj.local_uuid] = cached_future
105
+ self._local_uuid_to_future[obj._local_uuid] = cached_future
106
106
  if deduplication_key is not None:
107
107
  self._deduplication_cache[deduplication_key] = cached_future
108
108
  with suppress_tb_frame():
@@ -522,8 +522,8 @@ def import_single_function_service(
522
522
  f = getattr(module, qual_name)
523
523
  if isinstance(f, Function):
524
524
  _function: modal._functions._Function[Any, Any, Any] = synchronizer._translate_in(f) # type: ignore
525
- service_deps = _function.deps(only_explicit_mounts=True)
526
- user_defined_callable = _function.get_raw_f()
525
+ service_deps = _function._deps_(only_explicit_mounts=True)
526
+ user_defined_callable = _function._raw_f_
527
527
  assert _function._app # app should always be set on a decorated function
528
528
  active_app = _function._app
529
529
  else:
@@ -594,7 +594,7 @@ def import_class_service(
594
594
  if isinstance(cls_or_user_cls, modal.cls.Cls):
595
595
  _cls = typing.cast(modal.cls._Cls, synchronizer._translate_in(cls_or_user_cls))
596
596
  class_service_function: _Function = _cls._get_class_service_function()
597
- service_deps = class_service_function.deps(only_explicit_mounts=True)
597
+ service_deps = class_service_function._deps_(only_explicit_mounts=True)
598
598
  active_app = class_service_function.app
599
599
  else:
600
600
  # Undecorated user class (serialized or local scope-decoration).
@@ -606,7 +606,7 @@ def import_class_service(
606
606
  service_function_hydration_data.function_handle_metadata,
607
607
  skip_reload=True, # this skips re-loading the function, which is required since it doesn't have a loader
608
608
  )
609
- _cls = modal.cls._Cls.from_local(cls_or_user_cls, active_app, _service_function)
609
+ _cls = modal.cls._Cls._from_local(cls_or_user_cls, active_app, _service_function)
610
610
  # hydration of the class itself - just sets the id and triggers some side effects
611
611
  # that transfers metadata from the service function to the class. TODO: cleanup!
612
612
  _cls._hydrate(class_id, _client, api_pb2.ClassHandleMetadata())
@@ -647,7 +647,7 @@ def import_server_service(
647
647
  if isinstance(cls_or_user_cls, modal.server.Server):
648
648
  _server = typing.cast(modal._server._Server, synchronizer._translate_in(cls_or_user_cls))
649
649
  server_service_function: _Function = _server._get_service_function()
650
- service_deps = server_service_function.deps(only_explicit_mounts=True)
650
+ service_deps = server_service_function._deps_(only_explicit_mounts=True)
651
651
  active_app = _server._get_app()
652
652
 
653
653
  else:
@@ -66,8 +66,10 @@ class Pickler(cloudpickle.Pickler):
66
66
  return ("sync", (impl_object.__class__, attributes))
67
67
  else:
68
68
  return
69
- if not obj.is_hydrated:
69
+
70
+ if not obj._is_hydrated:
70
71
  raise InvalidError(f"Can't serialize object {obj} which hasn't been hydrated.")
72
+
71
73
  return (obj.object_id, flag, obj._get_metadata())
72
74
 
73
75
 
@@ -118,3 +118,32 @@ def handle_deprecated_parameters(func: Callable[P, R]) -> Callable[P, R]:
118
118
  return func(*args, **kwargs)
119
119
 
120
120
  return wrapper
121
+
122
+
123
+ def with_deprecation_warning(
124
+ deprecated_on: tuple[int, int, int], msg: str, *, show_source: bool = True
125
+ ) -> Callable[[Callable[P, R]], Callable[P, R]]:
126
+ def decorator(method: Callable[P, R]) -> Callable[P, R]:
127
+ is_static = False
128
+ if isinstance(method, staticmethod):
129
+ is_static = True
130
+ method = method.__wrapped__
131
+
132
+ # Note: despite `wrapped` being synchronous, this also works with async functions, in that if
133
+ # a function returns a coroutine, then this function will also return a coroutine. So, when
134
+ # called from an async context, the return can be awaited without issues. However, code that
135
+ # introspects `wrapped` with, e.g. inspect.iscoroutinefunction(), will not pick up on the
136
+ # fact that it returns a coroutine unless it unwraps `wrapped` and tries to introspect `method`
137
+ # directly. Synchronicity already does this (https://github.com/modal-labs/synchronicity/blob/441085df7dfa953c86304d06da5e0e74cebbe858/src/synchronicity/async_wrap.py#L42-L57),
138
+ # but this is fixable on Python >= 3.12, which adds `inspect.markcoroutinefunction`.
139
+ @functools.wraps(method)
140
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> R:
141
+ deprecation_warning(deprecated_on, msg, show_source=show_source)
142
+ return method(*args, **kwargs)
143
+
144
+ if is_static:
145
+ return staticmethod(wrapped)
146
+
147
+ return wrapped
148
+
149
+ return decorator
@@ -108,7 +108,7 @@ def validate_volumes_by_object_id(validated_volumes: Sequence[tuple[str, _Volume
108
108
  """
109
109
  object_id_to_paths: dict[str, list[str]] = {}
110
110
  for path, volume in validated_volumes:
111
- if not volume.is_hydrated:
111
+ if not volume._is_hydrated:
112
112
  # This should never happen since this function is only called at load time
113
113
  raise RuntimeError(f"Internal error: Volume at '{path}' is not hydrated when validating mounts")
114
114
  object_id_to_paths.setdefault(volume.object_id, []).append(path)
@@ -321,7 +321,7 @@ class _WorkspaceBillingManager:
321
321
  A single mapping containing cost values. All values are reported as `decimal.Decimal`s.
322
322
  """
323
323
 
324
- if not self._workspace.is_hydrated:
324
+ if not self._workspace._is_hydrated:
325
325
  await self._workspace.hydrate()
326
326
 
327
327
  response = await self._workspace.client.stub.WorkspaceBillingRates(
@@ -386,7 +386,7 @@ class _WorkspaceBillingManager:
386
386
  elif end.tzinfo != timezone.utc:
387
387
  raise InvalidError("Timezone-aware 'end' parameter must be in UTC.")
388
388
 
389
- if not self._workspace.is_hydrated:
389
+ if not self._workspace._is_hydrated:
390
390
  await self._workspace.hydrate()
391
391
 
392
392
  request = api_pb2.WorkspaceBillingReportRequest(
@@ -457,7 +457,7 @@ class _WorkspaceBillingManager:
457
457
  if cycle > datetime.now(timezone.utc):
458
458
  raise InvalidError("Provided 'cycle' parameter cannot be in the future.")
459
459
 
460
- if not self._workspace.is_hydrated:
460
+ if not self._workspace._is_hydrated:
461
461
  await self._workspace.hydrate()
462
462
 
463
463
  request = api_pb2.WorkspaceBillingSummaryRequest()
@@ -483,7 +483,7 @@ class _WorkspaceSettingsManager:
483
483
  Returns:
484
484
  A `WorkspaceSettings` dataclass.
485
485
  """
486
- if not self._workspace.is_hydrated:
486
+ if not self._workspace._is_hydrated:
487
487
  await self._workspace.hydrate()
488
488
  resp = await self._workspace.client.stub.WorkspaceSettings(Empty())
489
489
  return WorkspaceSettings(
@@ -494,14 +494,14 @@ class _WorkspaceSettingsManager:
494
494
  """mdmd:hidden
495
495
  Set the image builder version for the Workspace.
496
496
  """
497
- if not self._workspace.is_hydrated:
497
+ if not self._workspace._is_hydrated:
498
498
  await self._workspace.hydrate()
499
499
  req = api_pb2.WorkspaceSetImageBuilderVersionRequest(new_image_builder_version=version)
500
500
  await self._workspace.client.stub.WorkspaceSetImageBuilderVersion(req)
501
501
 
502
502
  async def _set_default_environment(self, name: str) -> None:
503
503
  """Set the default environment for the Workspace."""
504
- if not self._workspace.is_hydrated:
504
+ if not self._workspace._is_hydrated:
505
505
  await self._workspace.hydrate()
506
506
  req = api_pb2.WorkspaceSetDefaultEnvironmentRequest(environment_name=name)
507
507
  await self._workspace.client.stub.WorkspaceSetDefaultEnvironment(req)
@@ -33,10 +33,7 @@ from ._partial_function import (
33
33
  from ._server import _Server, validate_http_server_config
34
34
  from ._supports_logs import _LogQueryData
35
35
  from ._utils.async_utils import synchronize_api
36
- from ._utils.deprecation import (
37
- deprecation_warning,
38
- handle_deprecated_parameters,
39
- )
36
+ from ._utils.deprecation import deprecation_warning, handle_deprecated_parameters, with_deprecation_warning
40
37
  from ._utils.function_utils import (
41
38
  FunctionInfo,
42
39
  is_flash_object,
@@ -274,6 +271,10 @@ class _App:
274
271
  return self._name
275
272
 
276
273
  @property
274
+ @with_deprecation_warning(
275
+ (2026, 8, 26),
276
+ "`App.is_interactive` is deprecated and will be removed in `modal` version 1.6.0",
277
+ )
277
278
  def is_interactive(self) -> bool:
278
279
  """mdmd:hidden"""
279
280
  return self._is_interactive_
@@ -383,6 +384,11 @@ class _App:
383
384
  raise InvalidError("App is not running")
384
385
  return f"https://modal.com/id/{self._app_id}"
385
386
 
387
+ @with_deprecation_warning(
388
+ (2026, 8, 26),
389
+ "`App.set_description` is deprecated and will be removed in `modal` version 1.6.0. "
390
+ "Set `App.description` directly instead",
391
+ )
386
392
  def set_description(self, description: str):
387
393
  """mdmd:hidden
388
394
  Set the description of the App before it starts running.
@@ -396,6 +402,10 @@ class _App:
396
402
  raise InvalidError(f"App attribute `{key}` with value {value!r} is not a valid Modal object")
397
403
 
398
404
  @property
405
+ @with_deprecation_warning(
406
+ (2026, 8, 26),
407
+ "`App.image` is deprecated and will be removed in `modal` version 1.6.0",
408
+ )
399
409
  def image(self) -> _Image:
400
410
  """mdmd:hidden
401
411
  Retrieve the Image that will be used as the default for any Functions registered to the App.
@@ -599,14 +609,14 @@ class _App:
599
609
  raise ExecutionError("`_get_watch_mounts` requires a running app.")
600
610
 
601
611
  all_mounts = []
602
- for function in self.registered_functions.values():
612
+ for function in self._local_state.functions.values():
603
613
  all_mounts.extend(function._serve_mounts)
604
614
 
605
615
  return [m for m in all_mounts if m.is_local()]
606
616
 
607
617
  def _add_function(self, function: _Function, is_web_endpoint: bool):
608
618
  local_state = self._local_state
609
- if old_function := local_state.functions.get(function.tag, None):
619
+ if old_function := local_state.functions.get(function._tag_, None):
610
620
  if old_function is function:
611
621
  return # already added the same exact instance, ignore
612
622
 
@@ -615,25 +625,25 @@ class _App:
615
625
  # and we don't want to warn about a collision in that case.
616
626
  if not is_interactive_ipython():
617
627
  logger.warning(
618
- f"Warning: function name '{function.tag}' collision!"
628
+ f"Warning: function name '{function._tag_}' collision!"
619
629
  " Overriding existing function "
620
630
  f"[{old_function._info.module_name}].{old_function._info.function_name}"
621
631
  f" with new function [{function._info.module_name}].{function._info.function_name}"
622
632
  )
623
- if function.tag in local_state.classes:
624
- logger.warning(f"Warning: tag {function.tag} exists but is overridden by function")
633
+ if function._tag_ in local_state.classes:
634
+ logger.warning(f"Warning: tag {function._tag_} exists but is overridden by function")
625
635
 
626
636
  if self._running_app:
627
637
  # If this is inside a container, then objects can be defined after app initialization.
628
638
  # So we may have to initialize objects once they get bound to the app.
629
- if function.tag in self._running_app.function_ids:
630
- object_id: str = self._running_app.function_ids[function.tag]
639
+ if function._tag_ in self._running_app.function_ids:
640
+ object_id: str = self._running_app.function_ids[function._tag_]
631
641
  metadata: Message = self._running_app.object_handle_metadata[object_id]
632
642
  function._hydrate(object_id, self._client, metadata)
633
643
 
634
- local_state.functions[function.tag] = function
644
+ local_state.functions[function._tag_] = function
635
645
  if is_web_endpoint:
636
- local_state.web_endpoints.append(function.tag)
646
+ local_state.web_endpoints.append(function._tag_)
637
647
 
638
648
  def _add_class(self, tag: str, cls: _Cls):
639
649
  if self._running_app:
@@ -668,6 +678,10 @@ class _App:
668
678
  obj._hydrate(object_id, client, handle_metadata)
669
679
 
670
680
  @property
681
+ @with_deprecation_warning(
682
+ (2026, 8, 26),
683
+ "`App.registered_functions` is deprecated and will be removed in `modal` version 1.6.0",
684
+ )
671
685
  def registered_functions(self) -> dict[str, _Function]:
672
686
  """mdmd:hidden
673
687
  All modal.Function objects registered on the app.
@@ -680,6 +694,10 @@ class _App:
680
694
  return self._local_state.functions
681
695
 
682
696
  @property
697
+ @with_deprecation_warning(
698
+ (2026, 8, 26),
699
+ "`App.registered_classes` is deprecated and will be removed in `modal` version 1.6.0",
700
+ )
683
701
  def registered_classes(self) -> dict[str, _Cls]:
684
702
  """mdmd:hidden
685
703
  All modal.Cls objects registered on the app.
@@ -692,6 +710,10 @@ class _App:
692
710
  return self._local_state.classes
693
711
 
694
712
  @property
713
+ @with_deprecation_warning(
714
+ (2026, 8, 26),
715
+ "`App.registered_entrypoints` is deprecated and will be removed in `modal` version 1.6.0",
716
+ )
695
717
  def registered_entrypoints(self) -> dict[str, _LocalEntrypoint]:
696
718
  """mdmd:hidden
697
719
  All local CLI entrypoints registered on the app.
@@ -703,6 +725,10 @@ class _App:
703
725
  return self._local_state.local_entrypoints
704
726
 
705
727
  @property
728
+ @with_deprecation_warning(
729
+ (2026, 8, 26),
730
+ "`App.registered_web_endpoints` is deprecated and will be removed in `modal` version 1.6.0",
731
+ )
706
732
  def registered_web_endpoints(self) -> list[str]:
707
733
  """mdmd:hidden
708
734
  Names of Web Functions registered on the app.
@@ -995,7 +1021,7 @@ class _App:
995
1021
  if is_generator is None:
996
1022
  is_generator = inspect.isgeneratorfunction(raw_f) or inspect.isasyncgenfunction(raw_f)
997
1023
 
998
- function = _Function.from_local(
1024
+ function = _Function._from_local(
999
1025
  info,
1000
1026
  app=self,
1001
1027
  image=image,
@@ -1231,7 +1257,7 @@ class _App:
1231
1257
  info = FunctionInfo(None, serialized=serialized, user_cls=user_cls)
1232
1258
 
1233
1259
  i6pn_enabled = i6pn or cluster_size is not None
1234
- cls_func = _Function.from_local(
1260
+ cls_func = _Function._from_local(
1235
1261
  info,
1236
1262
  app=self,
1237
1263
  image=image or self._get_default_image(),
@@ -1274,7 +1300,7 @@ class _App:
1274
1300
 
1275
1301
  self._add_function(cls_func, is_web_endpoint=False)
1276
1302
 
1277
- cls: _Cls = _Cls.from_local(user_cls, self, cls_func)
1303
+ cls: _Cls = _Cls._from_local(user_cls, self, cls_func)
1278
1304
 
1279
1305
  for method_name, partial_function in cls._method_partials.items():
1280
1306
  if partial_function.params.webhook_config is not None:
@@ -1442,7 +1468,7 @@ class _App:
1442
1468
  # Create the FunctionInfo for the server, note we treat FunctionInfo as a class for servers
1443
1469
  info = FunctionInfo(None, serialized=serialized, user_cls=user_cls, name_override=name or user_cls.__name__)
1444
1470
  # Create the service function
1445
- service_function = _Function.from_local(
1471
+ service_function = _Function._from_local(
1446
1472
  info,
1447
1473
  app=self,
1448
1474
  image=image or self._get_default_image(),
@@ -22,12 +22,16 @@ config_cli = ModalGroup(
22
22
 
23
23
 
24
24
  @config_cli.command("show", help="Show current configuration values (debugging command).")
25
- @click.option("--redact/--no-redact", default=True, help="Redact the `token_secret` value.")
25
+ @click.option("--redact/--no-redact", default=True, help="Redact secret credential values.")
26
26
  def show(redact: bool):
27
27
  # This is just a test command
28
28
  config_dict = config.to_dict()
29
29
  if redact and config_dict.get("token_secret"):
30
30
  config_dict["token_secret"] = "***"
31
+ if redact and config_dict.get("oauth_refresh_token"):
32
+ config_dict["oauth_refresh_token"] = "***"
33
+ if redact and config_dict.get("oauth_client_secret"):
34
+ config_dict["oauth_client_secret"] = "***"
31
35
 
32
36
  OutputManager.get().print_json(json.dumps(config_dict))
33
37