modal 1.5.5.dev15__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.dev15 → modal-1.5.5.dev16}/PKG-INFO +1 -1
  2. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_environments.py +2 -2
  3. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_function_variants.py +2 -2
  4. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_functions.py +2 -2
  5. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_image.py +4 -4
  6. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_resolver.py +5 -5
  7. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_runtime/user_code_imports.py +5 -5
  8. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_serialization.py +7 -2
  9. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/mount_utils.py +1 -1
  10. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_workspace.py +6 -6
  11. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/app.py +13 -13
  12. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/config.py +5 -1
  13. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/import_refs.py +9 -4
  14. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/launch.py +6 -2
  15. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/run.py +10 -6
  16. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/client.py +137 -20
  17. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/client.pyi +124 -3
  18. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cls.py +13 -13
  19. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/config.py +15 -7
  20. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/functions.pyi +6 -6
  21. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/runner.py +5 -5
  22. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/sandbox.py +72 -11
  23. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/sandbox.pyi +42 -12
  24. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal.egg-info/PKG-INFO +1 -1
  25. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/api_grpc.py +16 -0
  26. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/api_pb2.py +799 -769
  27. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/api_pb2.pyi +124 -0
  28. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/api_pb2_grpc.py +33 -0
  29. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/api_pb2_grpc.pyi +10 -0
  30. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/modal_api_grpc.py +1 -0
  31. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_version/__init__.py +1 -1
  32. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/pyproject.toml +1 -1
  33. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/LICENSE +0 -0
  34. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/README.md +0 -0
  35. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/__init__.py +0 -0
  36. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/__main__.py +0 -0
  37. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_billing.py +0 -0
  38. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_clustered_functions.py +0 -0
  39. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_clustered_functions.pyi +0 -0
  40. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_container_entrypoint.py +0 -0
  41. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_grpc_client.py +0 -0
  42. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_ipython.py +0 -0
  43. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_load_context.py +0 -0
  44. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_location.py +0 -0
  45. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_logs.py +0 -0
  46. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_logs_manager.py +0 -0
  47. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_logs_manager.pyi +0 -0
  48. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_object.py +0 -0
  49. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_output/__init__.py +0 -0
  50. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_output/manager.py +0 -0
  51. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_output/pty.py +0 -0
  52. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_output/rich.py +0 -0
  53. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_output/status.py +0 -0
  54. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_partial_function.py +0 -0
  55. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_resources.py +0 -0
  56. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_runtime/__init__.py +0 -0
  57. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_runtime/asgi.py +0 -0
  58. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_runtime/container_io_manager.py +0 -0
  59. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_runtime/container_io_manager.pyi +0 -0
  60. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_runtime/execution_context.py +0 -0
  61. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_runtime/execution_context.pyi +0 -0
  62. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  63. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_runtime/task_lifecycle_manager.py +0 -0
  64. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
  65. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_runtime/telemetry.py +0 -0
  66. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_runtime/user_code_event_loop.py +0 -0
  67. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_server.py +0 -0
  68. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_supports_logs.py +0 -0
  69. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_traceback.py +0 -0
  70. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_tunnel.py +0 -0
  71. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_tunnel.pyi +0 -0
  72. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_type_manager.py +0 -0
  73. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/__init__.py +0 -0
  74. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/app_utils.py +0 -0
  75. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/async_utils.py +0 -0
  76. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/auth_token_manager.py +0 -0
  77. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/blob_utils.py +0 -0
  78. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/browser_utils.py +0 -0
  79. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/bytes_io_segment_payload.py +0 -0
  80. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/curl_utils.py +0 -0
  81. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/deprecation.py +0 -0
  82. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/display_utils.py +0 -0
  83. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/docker_utils.py +0 -0
  84. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/function_utils.py +0 -0
  85. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/git_utils.py +0 -0
  86. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/grpc_testing.py +0 -0
  87. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/grpc_utils.py +0 -0
  88. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/hash_utils.py +0 -0
  89. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/http_utils.py +0 -0
  90. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/jwt_utils.py +0 -0
  91. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/logger.py +0 -0
  92. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/name_utils.py +0 -0
  93. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/package_utils.py +0 -0
  94. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/pattern_utils.py +0 -0
  95. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/proxy_support.py +0 -0
  96. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/rand_pb_testing.py +0 -0
  97. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/sandbox_fs_utils.py +0 -0
  98. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/shell_utils.py +0 -0
  99. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/task_command_router_client.py +0 -0
  100. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_utils/time_utils.py +0 -0
  101. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_vendor/__init__.py +0 -0
  102. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  103. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_vendor/cloudpickle.py +0 -0
  104. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_vendor/tblib.py +0 -0
  105. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_vendor/version.py +0 -0
  106. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/_watcher.py +0 -0
  107. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/app.pyi +0 -0
  108. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/billing.py +0 -0
  109. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/billing.pyi +0 -0
  110. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/builder/2023.12.312.txt +0 -0
  111. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/builder/2023.12.txt +0 -0
  112. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/builder/2024.04.txt +0 -0
  113. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/builder/2024.10.txt +0 -0
  114. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/builder/2025.06.txt +0 -0
  115. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/builder/PREVIEW.txt +0 -0
  116. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/builder/README.md +0 -0
  117. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/builder/base-images.json +0 -0
  118. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/call_graph.py +0 -0
  119. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/__init__.py +0 -0
  120. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/_download.py +0 -0
  121. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/_help.py +0 -0
  122. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/_traceback.py +0 -0
  123. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/app.py +0 -0
  124. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/billing.py +0 -0
  125. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/bootstrap.py +0 -0
  126. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/changelog.py +0 -0
  127. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/cluster.py +0 -0
  128. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/container.py +0 -0
  129. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/curl.py +0 -0
  130. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/dashboard.py +0 -0
  131. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/dict.py +0 -0
  132. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/endpoint.py +0 -0
  133. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/entry_point.py +0 -0
  134. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/environment.py +0 -0
  135. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/image.py +0 -0
  136. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/logo.py +0 -0
  137. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/network_file_system.py +0 -0
  138. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/profile.py +0 -0
  139. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/programs/__init__.py +0 -0
  140. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/programs/run_jupyter.py +0 -0
  141. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/programs/vscode.py +0 -0
  142. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/queues.py +0 -0
  143. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/secret.py +0 -0
  144. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/selector.py +0 -0
  145. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/shell.py +0 -0
  146. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/skills.py +0 -0
  147. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/token.py +0 -0
  148. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/utils.py +0 -0
  149. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/volume.py +0 -0
  150. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cli/workspace.py +0 -0
  151. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cloud_bucket_mount.py +0 -0
  152. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cloud_bucket_mount.pyi +0 -0
  153. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/cls.pyi +0 -0
  154. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/container_process.py +0 -0
  155. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/container_process.pyi +0 -0
  156. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/dict.py +0 -0
  157. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/dict.pyi +0 -0
  158. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/environments.py +0 -0
  159. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/environments.pyi +0 -0
  160. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/exception.py +0 -0
  161. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/experimental/__init__.py +0 -0
  162. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/experimental/flash.py +0 -0
  163. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/experimental/flash.pyi +0 -0
  164. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/experimental/ipython.py +0 -0
  165. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/file_io.py +0 -0
  166. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/file_io.pyi +0 -0
  167. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/file_pattern_matcher.py +0 -0
  168. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/functions.py +0 -0
  169. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/image.py +0 -0
  170. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/image.pyi +0 -0
  171. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/io_streams.py +0 -0
  172. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/io_streams.pyi +0 -0
  173. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/mount.py +0 -0
  174. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/mount.pyi +0 -0
  175. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/network_file_system.py +0 -0
  176. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/network_file_system.pyi +0 -0
  177. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/object.py +0 -0
  178. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/object.pyi +0 -0
  179. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/output.py +0 -0
  180. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/parallel_map.py +0 -0
  181. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/parallel_map.pyi +0 -0
  182. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/partial_function.py +0 -0
  183. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/partial_function.pyi +0 -0
  184. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/proxy.py +0 -0
  185. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/proxy.pyi +0 -0
  186. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/py.typed +0 -0
  187. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/queue.py +0 -0
  188. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/queue.pyi +0 -0
  189. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/retries.py +0 -0
  190. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/runner.pyi +0 -0
  191. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/running_app.py +0 -0
  192. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/sandbox_fs.py +0 -0
  193. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/sandbox_fs.pyi +0 -0
  194. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/schedule.py +0 -0
  195. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/scheduler_placement.py +0 -0
  196. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/secret.py +0 -0
  197. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/secret.pyi +0 -0
  198. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/server.py +0 -0
  199. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/server.pyi +0 -0
  200. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/serving.py +0 -0
  201. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/serving.pyi +0 -0
  202. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/skills/modal/SKILL.md +0 -0
  203. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/snapshot.py +0 -0
  204. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/snapshot.pyi +0 -0
  205. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/stream_type.py +0 -0
  206. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/token_flow.py +0 -0
  207. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/token_flow.pyi +0 -0
  208. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/types.py +0 -0
  209. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/volume.py +0 -0
  210. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/volume.pyi +0 -0
  211. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/workspace.py +0 -0
  212. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal/workspace.pyi +0 -0
  213. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal.egg-info/SOURCES.txt +0 -0
  214. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal.egg-info/dependency_links.txt +0 -0
  215. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal.egg-info/entry_points.txt +0 -0
  216. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal.egg-info/requires.txt +0 -0
  217. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal.egg-info/top_level.txt +0 -0
  218. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_docs/__init__.py +0 -0
  219. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_docs/gen_cli_docs.py +0 -0
  220. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_docs/gen_cli_docs_main.py +0 -0
  221. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_docs/gen_reference_docs.py +0 -0
  222. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_docs/gen_reference_docs_main.py +0 -0
  223. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_docs/mdmd/__init__.py +0 -0
  224. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_docs/mdmd/mdmd.py +0 -0
  225. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_docs/mdmd/signatures.py +0 -0
  226. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_docs/mdmd/types.py +0 -0
  227. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_docs/reference_intro.md +0 -0
  228. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/__init__.py +0 -0
  229. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/py.typed +0 -0
  230. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/task_command_router_grpc.py +0 -0
  231. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/task_command_router_pb2.py +0 -0
  232. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/task_command_router_pb2.pyi +0 -0
  233. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  234. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  235. {modal-1.5.5.dev15 → modal-1.5.5.dev16}/modal_version/__main__.py +0 -0
  236. {modal-1.5.5.dev15 → 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.dev15
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
 
@@ -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
@@ -1934,7 +1934,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1934
1934
  # TODO: check if we end up here in a container for a serialized function?
1935
1935
  raise ExecutionError("Can't call .local on service function")
1936
1936
 
1937
- 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:
1938
1938
  warnings.warn(
1939
1939
  f"The {info.function_name} function is executing locally "
1940
1940
  + "and will not have access to the mounted Volume or NetworkFileSystem data"
@@ -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
  )
@@ -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)
@@ -599,14 +599,14 @@ class _App:
599
599
  raise ExecutionError("`_get_watch_mounts` requires a running app.")
600
600
 
601
601
  all_mounts = []
602
- for function in self.registered_functions.values():
602
+ for function in self._local_state.functions.values():
603
603
  all_mounts.extend(function._serve_mounts)
604
604
 
605
605
  return [m for m in all_mounts if m.is_local()]
606
606
 
607
607
  def _add_function(self, function: _Function, is_web_endpoint: bool):
608
608
  local_state = self._local_state
609
- if old_function := local_state.functions.get(function.tag, None):
609
+ if old_function := local_state.functions.get(function._tag_, None):
610
610
  if old_function is function:
611
611
  return # already added the same exact instance, ignore
612
612
 
@@ -615,25 +615,25 @@ class _App:
615
615
  # and we don't want to warn about a collision in that case.
616
616
  if not is_interactive_ipython():
617
617
  logger.warning(
618
- f"Warning: function name '{function.tag}' collision!"
618
+ f"Warning: function name '{function._tag_}' collision!"
619
619
  " Overriding existing function "
620
620
  f"[{old_function._info.module_name}].{old_function._info.function_name}"
621
621
  f" with new function [{function._info.module_name}].{function._info.function_name}"
622
622
  )
623
- if function.tag in local_state.classes:
624
- 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")
625
625
 
626
626
  if self._running_app:
627
627
  # If this is inside a container, then objects can be defined after app initialization.
628
628
  # 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]
629
+ if function._tag_ in self._running_app.function_ids:
630
+ object_id: str = self._running_app.function_ids[function._tag_]
631
631
  metadata: Message = self._running_app.object_handle_metadata[object_id]
632
632
  function._hydrate(object_id, self._client, metadata)
633
633
 
634
- local_state.functions[function.tag] = function
634
+ local_state.functions[function._tag_] = function
635
635
  if is_web_endpoint:
636
- local_state.web_endpoints.append(function.tag)
636
+ local_state.web_endpoints.append(function._tag_)
637
637
 
638
638
  def _add_class(self, tag: str, cls: _Cls):
639
639
  if self._running_app:
@@ -995,7 +995,7 @@ class _App:
995
995
  if is_generator is None:
996
996
  is_generator = inspect.isgeneratorfunction(raw_f) or inspect.isasyncgenfunction(raw_f)
997
997
 
998
- function = _Function.from_local(
998
+ function = _Function._from_local(
999
999
  info,
1000
1000
  app=self,
1001
1001
  image=image,
@@ -1231,7 +1231,7 @@ class _App:
1231
1231
  info = FunctionInfo(None, serialized=serialized, user_cls=user_cls)
1232
1232
 
1233
1233
  i6pn_enabled = i6pn or cluster_size is not None
1234
- cls_func = _Function.from_local(
1234
+ cls_func = _Function._from_local(
1235
1235
  info,
1236
1236
  app=self,
1237
1237
  image=image or self._get_default_image(),
@@ -1274,7 +1274,7 @@ class _App:
1274
1274
 
1275
1275
  self._add_function(cls_func, is_web_endpoint=False)
1276
1276
 
1277
- cls: _Cls = _Cls.from_local(user_cls, self, cls_func)
1277
+ cls: _Cls = _Cls._from_local(user_cls, self, cls_func)
1278
1278
 
1279
1279
  for method_name, partial_function in cls._method_partials.items():
1280
1280
  if partial_function.params.webhook_config is not None:
@@ -1442,7 +1442,7 @@ class _App:
1442
1442
  # Create the FunctionInfo for the server, note we treat FunctionInfo as a class for servers
1443
1443
  info = FunctionInfo(None, serialized=serialized, user_cls=user_cls, name_override=name or user_cls.__name__)
1444
1444
  # Create the service function
1445
- service_function = _Function.from_local(
1445
+ service_function = _Function._from_local(
1446
1446
  info,
1447
1447
  app=self,
1448
1448
  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
 
@@ -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
@@ -8,14 +8,15 @@ import time
8
8
  import typing
9
9
  from collections.abc import Callable
10
10
  from dataclasses import dataclass
11
- from typing import Any, get_args
11
+ from typing import Any, cast, get_args
12
12
 
13
13
  import click
14
14
  from click import ClickException
15
15
  from typing_extensions import TypedDict
16
16
 
17
17
  from .._environments import ensure_env
18
- from ..app import App, LocalEntrypoint
18
+ from .._utils.async_utils import synchronizer
19
+ from ..app import App, LocalEntrypoint, _App
19
20
  from ..cls import _get_class_constructor_signature
20
21
  from ..config import config
21
22
  from ..exception import ExecutionError, InvalidError, _CliUserExecutionError
@@ -466,9 +467,10 @@ class RunGroup(ModalGroup):
466
467
  raise ClickException(f"{help_header}\n\n{help_footer}")
467
468
 
468
469
  app = _get_runnable_app(runnable)
470
+ inner = cast(_App, synchronizer._translate_in(app))
469
471
 
470
- if app.description is None:
471
- app.set_description(_get_clean_app_description(func_ref))
472
+ if inner._description is None:
473
+ inner._description = _get_clean_app_description(func_ref)
472
474
 
473
475
  if isinstance(runnable, LocalEntrypoint):
474
476
  click_command = _get_click_command_for_local_entrypoint(app, runnable)
@@ -672,8 +674,10 @@ def serve(
672
674
 
673
675
  OutputManager.get().set_timestamps(timestamps)
674
676
  app = import_app_from_ref(import_ref, base_cmd="modal serve")
675
- if app.description is None:
676
- app.set_description(_get_clean_app_description(app_ref))
677
+ inner = cast(_App, synchronizer._translate_in(app))
678
+
679
+ if inner._description is None:
680
+ inner._description = _get_clean_app_description(app_ref)
677
681
  with serve_app(app, import_ref, name=name, environment_name=env):
678
682
  if timeout is None:
679
683
  timeout = config["serve_timeout"]