modal 1.5.5.dev14__tar.gz → 1.5.5.dev16__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.dev14 → modal-1.5.5.dev16}/PKG-INFO +1 -1
  2. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_environments.py +2 -2
  3. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_function_variants.py +2 -2
  4. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_functions.py +33 -5
  5. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_image.py +4 -4
  6. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_object.py +4 -1
  7. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_resolver.py +5 -5
  8. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_runtime/user_code_imports.py +5 -5
  9. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_serialization.py +7 -2
  10. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/mount_utils.py +1 -1
  11. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_workspace.py +6 -6
  12. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/app.py +24 -14
  13. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/app.pyi +20 -0
  14. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/config.py +5 -1
  15. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/import_refs.py +9 -4
  16. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/launch.py +6 -2
  17. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/run.py +10 -6
  18. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/client.py +137 -20
  19. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/client.pyi +124 -3
  20. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cls.py +21 -15
  21. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cls.pyi +20 -0
  22. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/config.py +15 -7
  23. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/functions.pyi +82 -6
  24. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/object.pyi +11 -30
  25. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/runner.py +5 -5
  26. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/sandbox.py +74 -8
  27. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/sandbox.pyi +42 -12
  28. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal.egg-info/PKG-INFO +1 -1
  29. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/api_grpc.py +16 -0
  30. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/api_pb2.py +799 -769
  31. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/api_pb2.pyi +124 -0
  32. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/api_pb2_grpc.py +33 -0
  33. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/api_pb2_grpc.pyi +10 -0
  34. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/modal_api_grpc.py +1 -0
  35. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_version/__init__.py +1 -1
  36. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/pyproject.toml +1 -1
  37. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/LICENSE +0 -0
  38. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/README.md +0 -0
  39. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/__init__.py +0 -0
  40. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/__main__.py +0 -0
  41. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_billing.py +0 -0
  42. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_clustered_functions.py +0 -0
  43. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_clustered_functions.pyi +0 -0
  44. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_container_entrypoint.py +0 -0
  45. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_grpc_client.py +0 -0
  46. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_ipython.py +0 -0
  47. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_load_context.py +0 -0
  48. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_location.py +0 -0
  49. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_logs.py +0 -0
  50. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_logs_manager.py +0 -0
  51. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_logs_manager.pyi +0 -0
  52. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_output/__init__.py +0 -0
  53. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_output/manager.py +0 -0
  54. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_output/pty.py +0 -0
  55. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_output/rich.py +0 -0
  56. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_output/status.py +0 -0
  57. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_partial_function.py +0 -0
  58. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_resources.py +0 -0
  59. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_runtime/__init__.py +0 -0
  60. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_runtime/asgi.py +0 -0
  61. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_runtime/container_io_manager.py +0 -0
  62. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_runtime/container_io_manager.pyi +0 -0
  63. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_runtime/execution_context.py +0 -0
  64. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_runtime/execution_context.pyi +0 -0
  65. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  66. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_runtime/task_lifecycle_manager.py +0 -0
  67. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
  68. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_runtime/telemetry.py +0 -0
  69. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_runtime/user_code_event_loop.py +0 -0
  70. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_server.py +0 -0
  71. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_supports_logs.py +0 -0
  72. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_traceback.py +0 -0
  73. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_tunnel.py +0 -0
  74. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_tunnel.pyi +0 -0
  75. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_type_manager.py +0 -0
  76. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/__init__.py +0 -0
  77. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/app_utils.py +0 -0
  78. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/async_utils.py +0 -0
  79. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/auth_token_manager.py +0 -0
  80. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/blob_utils.py +0 -0
  81. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/browser_utils.py +0 -0
  82. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/bytes_io_segment_payload.py +0 -0
  83. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/curl_utils.py +0 -0
  84. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/deprecation.py +0 -0
  85. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/display_utils.py +0 -0
  86. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/docker_utils.py +0 -0
  87. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/function_utils.py +0 -0
  88. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/git_utils.py +0 -0
  89. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/grpc_testing.py +0 -0
  90. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/grpc_utils.py +0 -0
  91. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/hash_utils.py +0 -0
  92. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/http_utils.py +0 -0
  93. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/jwt_utils.py +0 -0
  94. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/logger.py +0 -0
  95. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/name_utils.py +0 -0
  96. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/package_utils.py +0 -0
  97. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/pattern_utils.py +0 -0
  98. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/proxy_support.py +0 -0
  99. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/rand_pb_testing.py +0 -0
  100. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/sandbox_fs_utils.py +0 -0
  101. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/shell_utils.py +0 -0
  102. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/task_command_router_client.py +0 -0
  103. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_utils/time_utils.py +0 -0
  104. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_vendor/__init__.py +0 -0
  105. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  106. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_vendor/cloudpickle.py +0 -0
  107. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_vendor/tblib.py +0 -0
  108. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_vendor/version.py +0 -0
  109. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/_watcher.py +0 -0
  110. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/billing.py +0 -0
  111. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/billing.pyi +0 -0
  112. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/builder/2023.12.312.txt +0 -0
  113. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/builder/2023.12.txt +0 -0
  114. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/builder/2024.04.txt +0 -0
  115. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/builder/2024.10.txt +0 -0
  116. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/builder/2025.06.txt +0 -0
  117. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/builder/PREVIEW.txt +0 -0
  118. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/builder/README.md +0 -0
  119. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/builder/base-images.json +0 -0
  120. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/call_graph.py +0 -0
  121. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/__init__.py +0 -0
  122. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/_download.py +0 -0
  123. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/_help.py +0 -0
  124. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/_traceback.py +0 -0
  125. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/app.py +0 -0
  126. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/billing.py +0 -0
  127. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/bootstrap.py +0 -0
  128. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/changelog.py +0 -0
  129. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/cluster.py +0 -0
  130. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/container.py +0 -0
  131. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/curl.py +0 -0
  132. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/dashboard.py +0 -0
  133. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/dict.py +0 -0
  134. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/endpoint.py +0 -0
  135. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/entry_point.py +0 -0
  136. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/environment.py +0 -0
  137. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/image.py +0 -0
  138. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/logo.py +0 -0
  139. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/network_file_system.py +0 -0
  140. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/profile.py +0 -0
  141. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/programs/__init__.py +0 -0
  142. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/programs/run_jupyter.py +0 -0
  143. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/programs/vscode.py +0 -0
  144. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/queues.py +0 -0
  145. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/secret.py +0 -0
  146. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/selector.py +0 -0
  147. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/shell.py +0 -0
  148. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/skills.py +0 -0
  149. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/token.py +0 -0
  150. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/utils.py +0 -0
  151. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/volume.py +0 -0
  152. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cli/workspace.py +0 -0
  153. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cloud_bucket_mount.py +0 -0
  154. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/cloud_bucket_mount.pyi +0 -0
  155. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/container_process.py +0 -0
  156. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/container_process.pyi +0 -0
  157. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/dict.py +0 -0
  158. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/dict.pyi +0 -0
  159. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/environments.py +0 -0
  160. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/environments.pyi +0 -0
  161. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/exception.py +0 -0
  162. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/experimental/__init__.py +0 -0
  163. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/experimental/flash.py +0 -0
  164. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/experimental/flash.pyi +0 -0
  165. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/experimental/ipython.py +0 -0
  166. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/file_io.py +0 -0
  167. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/file_io.pyi +0 -0
  168. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/file_pattern_matcher.py +0 -0
  169. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/functions.py +0 -0
  170. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/image.py +0 -0
  171. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/image.pyi +0 -0
  172. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/io_streams.py +0 -0
  173. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/io_streams.pyi +0 -0
  174. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/mount.py +0 -0
  175. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/mount.pyi +0 -0
  176. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/network_file_system.py +0 -0
  177. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/network_file_system.pyi +0 -0
  178. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/object.py +0 -0
  179. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/output.py +0 -0
  180. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/parallel_map.py +0 -0
  181. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/parallel_map.pyi +0 -0
  182. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/partial_function.py +0 -0
  183. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/partial_function.pyi +0 -0
  184. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/proxy.py +0 -0
  185. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/proxy.pyi +0 -0
  186. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/py.typed +0 -0
  187. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/queue.py +0 -0
  188. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/queue.pyi +0 -0
  189. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/retries.py +0 -0
  190. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/runner.pyi +0 -0
  191. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/running_app.py +0 -0
  192. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/sandbox_fs.py +0 -0
  193. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/sandbox_fs.pyi +0 -0
  194. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/schedule.py +0 -0
  195. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/scheduler_placement.py +0 -0
  196. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/secret.py +0 -0
  197. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/secret.pyi +0 -0
  198. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/server.py +0 -0
  199. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/server.pyi +0 -0
  200. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/serving.py +0 -0
  201. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/serving.pyi +0 -0
  202. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/skills/modal/SKILL.md +0 -0
  203. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/snapshot.py +0 -0
  204. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/snapshot.pyi +0 -0
  205. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/stream_type.py +0 -0
  206. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/token_flow.py +0 -0
  207. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/token_flow.pyi +0 -0
  208. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/types.py +0 -0
  209. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/volume.py +0 -0
  210. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/volume.pyi +0 -0
  211. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/workspace.py +0 -0
  212. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal/workspace.pyi +0 -0
  213. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal.egg-info/SOURCES.txt +0 -0
  214. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal.egg-info/dependency_links.txt +0 -0
  215. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal.egg-info/entry_points.txt +0 -0
  216. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal.egg-info/requires.txt +0 -0
  217. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal.egg-info/top_level.txt +0 -0
  218. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_docs/__init__.py +0 -0
  219. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_docs/gen_cli_docs.py +0 -0
  220. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_docs/gen_cli_docs_main.py +0 -0
  221. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_docs/gen_reference_docs.py +0 -0
  222. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_docs/gen_reference_docs_main.py +0 -0
  223. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_docs/mdmd/__init__.py +0 -0
  224. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_docs/mdmd/mdmd.py +0 -0
  225. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_docs/mdmd/signatures.py +0 -0
  226. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_docs/mdmd/types.py +0 -0
  227. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_docs/reference_intro.md +0 -0
  228. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/__init__.py +0 -0
  229. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/py.typed +0 -0
  230. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/task_command_router_grpc.py +0 -0
  231. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/task_command_router_pb2.py +0 -0
  232. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/task_command_router_pb2.pyi +0 -0
  233. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  234. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  235. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/modal_version/__main__.py +0 -0
  236. {modal-1.5.5.dev14 → modal-1.5.5.dev16}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.5.5.dev14
3
+ Version: 1.5.5.dev16
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
 
@@ -663,7 +663,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
663
663
  return _FunctionLogsManager(self)
664
664
 
665
665
  @staticmethod
666
- def from_local(
666
+ def _from_local(
667
667
  info: FunctionInfo,
668
668
  app: "modal.app._App | None", # App here should only be None in case of Image.run_function
669
669
  image: _Image,
@@ -937,7 +937,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
937
937
  with FunctionCreationStatus(tag) as function_creation_status:
938
938
  timeout_secs = timeout
939
939
 
940
- if app and app.is_interactive and not is_builder_function:
940
+ if app and app._is_interactive_ and not is_builder_function:
941
941
  pty_info = get_pty_info(shell=False)
942
942
  else:
943
943
  pty_info = None
@@ -1164,7 +1164,9 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1164
1164
  # the only way to infer a LoadContext for an `@app.function`, and the App doesn't
1165
1165
  # get its client until *after* the Function is created.
1166
1166
  load_context = app._root_load_context if app else LoadContext.empty()
1167
- obj = _Function._from_loader(_load, rep, preload=_preload, deps=_deps, load_context_overrides=load_context)
1167
+ obj: _Function = _Function._from_loader(
1168
+ _load, rep, preload=_preload, deps=_deps, load_context_overrides=load_context
1169
+ )
1168
1170
 
1169
1171
  obj._raw_f = info.raw_f
1170
1172
  obj._info = info
@@ -1192,6 +1194,9 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1192
1194
 
1193
1195
  return obj
1194
1196
 
1197
+ from_local = _from_local
1198
+ """mdmd:hidden"""
1199
+
1195
1200
  async def _update_autoscaler(
1196
1201
  self,
1197
1202
  *,
@@ -1386,6 +1391,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1386
1391
  @property
1387
1392
  def tag(self) -> str:
1388
1393
  """mdmd:hidden"""
1394
+ return self._tag_
1395
+
1396
+ @property
1397
+ def _tag_(self) -> str:
1389
1398
  assert self._tag
1390
1399
  return self._tag
1391
1400
 
@@ -1406,12 +1415,20 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1406
1415
  @property
1407
1416
  def info(self) -> FunctionInfo:
1408
1417
  """mdmd:hidden"""
1418
+ return self._info_
1419
+
1420
+ @property
1421
+ def _info_(self) -> FunctionInfo:
1409
1422
  assert self._info
1410
1423
  return self._info
1411
1424
 
1412
1425
  @property
1413
1426
  def spec(self) -> _FunctionSpec:
1414
1427
  """mdmd:hidden"""
1428
+ return self._spec_
1429
+
1430
+ @property
1431
+ def _spec_(self) -> _FunctionSpec:
1415
1432
  assert self._spec
1416
1433
  return self._spec
1417
1434
 
@@ -1419,13 +1436,16 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1419
1436
  # only defined in definition scope/locally, and not for class methods at the moment
1420
1437
  return bool(self._webhook_config and self._webhook_config.type != api_pb2.WEBHOOK_TYPE_UNSPECIFIED)
1421
1438
 
1422
- def get_build_def(self) -> str:
1439
+ def _get_build_def(self) -> str:
1423
1440
  """mdmd:hidden"""
1424
1441
  # Plaintext source and arg definition for the function, so it's part of the image
1425
1442
  # hash. We can't use the cloudpickle hash because it's not very stable.
1426
1443
  assert hasattr(self, "_raw_f") and hasattr(self, "_build_args") and self._raw_f is not None
1427
1444
  return f"{inspect.getsource(self._raw_f)}\n{repr(self._build_args)}"
1428
1445
 
1446
+ get_build_def = _get_build_def
1447
+ """mdmd:hidden"""
1448
+
1429
1449
  # Live handle methods
1430
1450
 
1431
1451
  def _initialize_from_empty(self):
@@ -1675,6 +1695,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1675
1695
  @property
1676
1696
  async def is_generator(self) -> bool:
1677
1697
  """mdmd:hidden"""
1698
+ return await self._is_generator_
1699
+
1700
+ @property
1701
+ async def _is_generator_(self) -> bool:
1678
1702
  # hacky: kind of like @live_method, but not hydrating if we have the value already from local source
1679
1703
  # TODO(michael) use a common / lightweight method for handling unhydrated metadata properties
1680
1704
  if self._is_generator is not None:
@@ -1910,7 +1934,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1910
1934
  # TODO: check if we end up here in a container for a serialized function?
1911
1935
  raise ExecutionError("Can't call .local on service function")
1912
1936
 
1913
- if is_local() and self.spec.volumes or self.spec.network_file_systems:
1937
+ if is_local() and self._spec_.volumes or self._spec_.network_file_systems:
1914
1938
  warnings.warn(
1915
1939
  f"The {info.function_name} function is executing locally "
1916
1940
  + "and will not have access to the mounted Volume or NetworkFileSystem data"
@@ -2014,6 +2038,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
2014
2038
  Returns:
2015
2039
  The original function object registered with Modal.
2016
2040
  """
2041
+ return self._raw_f_
2042
+
2043
+ @property
2044
+ def _raw_f_(self) -> Callable[..., Any]:
2017
2045
  assert self._raw_f is not None
2018
2046
  return self._raw_f
2019
2047
 
@@ -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
  )
@@ -209,7 +209,7 @@ class _Object:
209
209
  name: str | None = None,
210
210
  *,
211
211
  load_context_overrides: LoadContext,
212
- ):
212
+ ) -> Self:
213
213
  # TODO(erikbern): flip the order of the two first arguments
214
214
  obj = _Object.__new__(cls)
215
215
  obj._init(
@@ -313,7 +313,10 @@ class _Object:
313
313
  @property
314
314
  def deps(self) -> Callable[..., Sequence["_Object"]]:
315
315
  """mdmd:hidden"""
316
+ return self._deps_
316
317
 
318
+ @property
319
+ def _deps_(self) -> Callable[..., Sequence["_Object"]]:
317
320
  def default_deps(*args, **kwargs) -> Sequence["_Object"]:
318
321
  return []
319
322
 
@@ -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:
@@ -4,7 +4,7 @@ import io
4
4
  import pickle
5
5
  import typing
6
6
  from inspect import Parameter
7
- from typing import Any
7
+ from typing import Any, cast
8
8
 
9
9
  from modal._traceback import extract_traceback
10
10
  from modal.config import config
@@ -43,8 +43,11 @@ class Pickler(cloudpickle.Pickler):
43
43
 
44
44
  if isinstance(obj, _Object):
45
45
  flag = "_o"
46
+ is_hydrated = obj._is_hydrated
46
47
  elif isinstance(obj, Object):
47
48
  flag = "o"
49
+ inner = cast(_Object, synchronizer._translate_in(obj))
50
+ is_hydrated = inner._is_hydrated
48
51
  elif isinstance(obj, PartialFunction):
49
52
  # Special case for PartialObject since it's a synchronicity wrapped object
50
53
  # that's set on serialized classes.
@@ -66,8 +69,10 @@ class Pickler(cloudpickle.Pickler):
66
69
  return ("sync", (impl_object.__class__, attributes))
67
70
  else:
68
71
  return
69
- if not obj.is_hydrated:
72
+
73
+ if not is_hydrated:
70
74
  raise InvalidError(f"Can't serialize object {obj} which hasn't been hydrated.")
75
+
71
76
  return (obj.object_id, flag, obj._get_metadata())
72
77
 
73
78
 
@@ -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)
@@ -275,6 +275,11 @@ class _App:
275
275
 
276
276
  @property
277
277
  def is_interactive(self) -> bool:
278
+ """mdmd:hidden"""
279
+ return self._is_interactive_
280
+
281
+ @property
282
+ def _is_interactive_(self) -> bool:
278
283
  """mdmd:hidden
279
284
  Whether the current app for the app is running in interactive mode.
280
285
 
@@ -305,6 +310,11 @@ class _App:
305
310
  """
306
311
  return self._description
307
312
 
313
+ @description.setter
314
+ def description(self, value):
315
+ """mdmd:hidden"""
316
+ self._description = value
317
+
308
318
  @staticmethod
309
319
  async def lookup(
310
320
  name: str,
@@ -379,7 +389,7 @@ class _App:
379
389
 
380
390
  Note: we don't recommend using the method and may deprecate it in the future.
381
391
  """
382
- self._description = description
392
+ self.description = description
383
393
 
384
394
  def _validate_blueprint_value(self, key: str, value: Any):
385
395
  if not isinstance(value, _Object):
@@ -589,14 +599,14 @@ class _App:
589
599
  raise ExecutionError("`_get_watch_mounts` requires a running app.")
590
600
 
591
601
  all_mounts = []
592
- for function in self.registered_functions.values():
602
+ for function in self._local_state.functions.values():
593
603
  all_mounts.extend(function._serve_mounts)
594
604
 
595
605
  return [m for m in all_mounts if m.is_local()]
596
606
 
597
607
  def _add_function(self, function: _Function, is_web_endpoint: bool):
598
608
  local_state = self._local_state
599
- if old_function := local_state.functions.get(function.tag, None):
609
+ if old_function := local_state.functions.get(function._tag_, None):
600
610
  if old_function is function:
601
611
  return # already added the same exact instance, ignore
602
612
 
@@ -605,25 +615,25 @@ class _App:
605
615
  # and we don't want to warn about a collision in that case.
606
616
  if not is_interactive_ipython():
607
617
  logger.warning(
608
- f"Warning: function name '{function.tag}' collision!"
618
+ f"Warning: function name '{function._tag_}' collision!"
609
619
  " Overriding existing function "
610
620
  f"[{old_function._info.module_name}].{old_function._info.function_name}"
611
621
  f" with new function [{function._info.module_name}].{function._info.function_name}"
612
622
  )
613
- if function.tag in local_state.classes:
614
- logger.warning(f"Warning: tag {function.tag} exists but is overridden by function")
623
+ if function._tag_ in local_state.classes:
624
+ logger.warning(f"Warning: tag {function._tag_} exists but is overridden by function")
615
625
 
616
626
  if self._running_app:
617
627
  # If this is inside a container, then objects can be defined after app initialization.
618
628
  # So we may have to initialize objects once they get bound to the app.
619
- if function.tag in self._running_app.function_ids:
620
- object_id: str = self._running_app.function_ids[function.tag]
629
+ if function._tag_ in self._running_app.function_ids:
630
+ object_id: str = self._running_app.function_ids[function._tag_]
621
631
  metadata: Message = self._running_app.object_handle_metadata[object_id]
622
632
  function._hydrate(object_id, self._client, metadata)
623
633
 
624
- local_state.functions[function.tag] = function
634
+ local_state.functions[function._tag_] = function
625
635
  if is_web_endpoint:
626
- local_state.web_endpoints.append(function.tag)
636
+ local_state.web_endpoints.append(function._tag_)
627
637
 
628
638
  def _add_class(self, tag: str, cls: _Cls):
629
639
  if self._running_app:
@@ -985,7 +995,7 @@ class _App:
985
995
  if is_generator is None:
986
996
  is_generator = inspect.isgeneratorfunction(raw_f) or inspect.isasyncgenfunction(raw_f)
987
997
 
988
- function = _Function.from_local(
998
+ function = _Function._from_local(
989
999
  info,
990
1000
  app=self,
991
1001
  image=image,
@@ -1221,7 +1231,7 @@ class _App:
1221
1231
  info = FunctionInfo(None, serialized=serialized, user_cls=user_cls)
1222
1232
 
1223
1233
  i6pn_enabled = i6pn or cluster_size is not None
1224
- cls_func = _Function.from_local(
1234
+ cls_func = _Function._from_local(
1225
1235
  info,
1226
1236
  app=self,
1227
1237
  image=image or self._get_default_image(),
@@ -1264,7 +1274,7 @@ class _App:
1264
1274
 
1265
1275
  self._add_function(cls_func, is_web_endpoint=False)
1266
1276
 
1267
- cls: _Cls = _Cls.from_local(user_cls, self, cls_func)
1277
+ cls: _Cls = _Cls._from_local(user_cls, self, cls_func)
1268
1278
 
1269
1279
  for method_name, partial_function in cls._method_partials.items():
1270
1280
  if partial_function.params.webhook_config is not None:
@@ -1432,7 +1442,7 @@ class _App:
1432
1442
  # Create the FunctionInfo for the server, note we treat FunctionInfo as a class for servers
1433
1443
  info = FunctionInfo(None, serialized=serialized, user_cls=user_cls, name_override=name or user_cls.__name__)
1434
1444
  # Create the service function
1435
- service_function = _Function.from_local(
1445
+ service_function = _Function._from_local(
1436
1446
  info,
1437
1447
  app=self,
1438
1448
  image=image or self._get_default_image(),
@@ -205,6 +205,11 @@ class _App:
205
205
 
206
206
  @property
207
207
  def is_interactive(self) -> bool:
208
+ """mdmd:hidden"""
209
+ ...
210
+
211
+ @property
212
+ def _is_interactive_(self) -> bool:
208
213
  """mdmd:hidden
209
214
  Whether the current app for the app is running in interactive mode.
210
215
 
@@ -230,6 +235,11 @@ class _App:
230
235
  """
231
236
  ...
232
237
 
238
+ @description.setter
239
+ def description(self, value):
240
+ """mdmd:hidden"""
241
+ ...
242
+
233
243
  @staticmethod
234
244
  async def lookup(
235
245
  name: str,
@@ -1023,6 +1033,11 @@ class App:
1023
1033
 
1024
1034
  @property
1025
1035
  def is_interactive(self) -> bool:
1036
+ """mdmd:hidden"""
1037
+ ...
1038
+
1039
+ @property
1040
+ def _is_interactive_(self) -> bool:
1026
1041
  """mdmd:hidden
1027
1042
  Whether the current app for the app is running in interactive mode.
1028
1043
 
@@ -1048,6 +1063,11 @@ class App:
1048
1063
  """
1049
1064
  ...
1050
1065
 
1066
+ @description.setter
1067
+ def description(self, value):
1068
+ """mdmd:hidden"""
1069
+ ...
1070
+
1051
1071
  class __lookup_spec(typing_extensions.Protocol):
1052
1072
  def __call__(
1053
1073
  self,
@@ -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
 
@@ -27,6 +27,8 @@ from modal.exception import InvalidError, _CliUserExecutionError
27
27
  from modal.functions import Function
28
28
  from modal.output import OutputManager
29
29
 
30
+ from .._utils.async_utils import synchronizer
31
+
30
32
 
31
33
  @dataclasses.dataclass
32
34
  class ImportRef:
@@ -165,15 +167,18 @@ def list_cli_commands(
165
167
  all_runnables: dict[Runnable, list[str]] = defaultdict(list)
166
168
  priorities: dict[Runnable, int] = defaultdict(lambda: AutoRunPriority.APP_FUNCTION)
167
169
  for app_name, app in apps:
168
- for name, local_entrypoint in app.registered_entrypoints.items():
170
+ for name, inner_entrypoint in app._local_state.local_entrypoints.items():
171
+ local_entrypoint = cast(LocalEntrypoint, synchronizer._translate_out(inner_entrypoint))
169
172
  all_runnables[local_entrypoint].append(f"{app_name}.{name}")
170
173
  priorities[local_entrypoint] = AutoRunPriority.APP_LOCAL_ENTRYPOINT
171
- for name, function in app.registered_functions.items():
172
- if function.info.is_service_class() and not include_service_functions:
174
+ for name, inner_function in app._local_state.functions.items():
175
+ function = cast(Function, synchronizer._translate_out(inner_function))
176
+ if function._info_.is_service_class() and not include_service_functions:
173
177
  continue # Skip class and server service functions for all commands except `modal shell`.
174
178
  all_runnables[function].append(f"{app_name}.{name}")
175
179
  priorities[function] = AutoRunPriority.APP_FUNCTION
176
- for cls_name, cls in app.registered_classes.items():
180
+ for cls_name, inner_cls in app._local_state.classes.items():
181
+ cls = cast(Cls, synchronizer._translate_out(inner_cls))
177
182
  for method_name in cls._get_method_names():
178
183
  method_ref = MethodReference(cls, method_name)
179
184
  all_runnables[method_ref].append(f"{app_name}.{cls_name}.{method_name}")
@@ -4,12 +4,15 @@ import inspect
4
4
  import json
5
5
  import os
6
6
  from pathlib import Path
7
- from typing import Any
7
+ from typing import Any, cast
8
8
 
9
9
  import click
10
10
  import rich.panel
11
11
  from rich.markdown import Markdown
12
12
 
13
+ from modal.app import _App
14
+
15
+ from .._utils.async_utils import synchronizer
13
16
  from ..exception import _CliUserExecutionError
14
17
  from ..output import OutputManager
15
18
  from ..runner import run_app
@@ -40,7 +43,8 @@ def _launch_program(
40
43
  entrypoint = module.main
41
44
 
42
45
  app = _get_runnable_app(entrypoint)
43
- app.set_description(description if description else base_cmd)
46
+ inner = cast(_App, synchronizer._translate_in(app))
47
+ inner._description = description if description else base_cmd
44
48
 
45
49
  # `launch/` scripts must have a `local_entrypoint()` with no args, for simplicity here.
46
50
  func = entrypoint.info.raw_f