modal 1.5.3.dev13__tar.gz → 1.5.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. {modal-1.5.3.dev13 → modal-1.5.4}/PKG-INFO +1 -1
  2. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_clustered_functions.py +18 -4
  3. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_clustered_functions.pyi +6 -2
  4. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_environments.py +72 -38
  5. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_functions.py +71 -14
  6. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_image.py +121 -52
  7. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_logs.py +9 -7
  8. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_logs_manager.py +340 -108
  9. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_logs_manager.pyi +373 -173
  10. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_output/pty.py +12 -9
  11. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_output/rich.py +12 -2
  12. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_runtime/asgi.py +1 -1
  13. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_runtime/container_io_manager.py +107 -19
  14. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_runtime/container_io_manager.pyi +21 -9
  15. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_runtime/execution_context.py +6 -0
  16. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_runtime/execution_context.pyi +1 -0
  17. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_server.py +14 -4
  18. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_supports_logs.py +20 -2
  19. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_tunnel.py +2 -2
  20. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/async_utils.py +19 -2
  21. modal-1.5.4/modal/_utils/auth_token_manager.py +181 -0
  22. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/blob_utils.py +17 -11
  23. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/function_utils.py +32 -4
  24. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/grpc_utils.py +4 -2
  25. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/task_command_router_client.py +59 -13
  26. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/time_utils.py +4 -1
  27. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_watcher.py +4 -2
  28. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_workspace.py +83 -1
  29. {modal-1.5.3.dev13 → modal-1.5.4}/modal/app.py +37 -6
  30. {modal-1.5.3.dev13 → modal-1.5.4}/modal/app.pyi +59 -6
  31. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/_download.py +3 -6
  32. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/app.py +16 -9
  33. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/billing.py +30 -0
  34. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/container.py +66 -99
  35. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/entry_point.py +3 -0
  36. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/environment.py +107 -44
  37. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/image.py +50 -25
  38. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/run.py +36 -8
  39. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/shell.py +6 -7
  40. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/utils.py +8 -6
  41. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/volume.py +14 -17
  42. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/workspace.py +34 -8
  43. {modal-1.5.3.dev13 → modal-1.5.4}/modal/client.py +1 -0
  44. {modal-1.5.3.dev13 → modal-1.5.4}/modal/client.pyi +4 -10
  45. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cls.py +7 -1
  46. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cls.pyi +16 -3
  47. {modal-1.5.3.dev13 → modal-1.5.4}/modal/config.py +1 -0
  48. {modal-1.5.3.dev13 → modal-1.5.4}/modal/dict.py +19 -15
  49. {modal-1.5.3.dev13 → modal-1.5.4}/modal/environments.py +3 -0
  50. {modal-1.5.3.dev13 → modal-1.5.4}/modal/environments.pyi +82 -55
  51. {modal-1.5.3.dev13 → modal-1.5.4}/modal/exception.py +8 -0
  52. {modal-1.5.3.dev13 → modal-1.5.4}/modal/experimental/__init__.py +12 -3
  53. {modal-1.5.3.dev13 → modal-1.5.4}/modal/experimental/flash.py +15 -9
  54. {modal-1.5.3.dev13 → modal-1.5.4}/modal/experimental/flash.pyi +6 -2
  55. {modal-1.5.3.dev13 → modal-1.5.4}/modal/functions.pyi +47 -16
  56. {modal-1.5.3.dev13 → modal-1.5.4}/modal/image.pyi +36 -4
  57. {modal-1.5.3.dev13 → modal-1.5.4}/modal/mount.py +2 -2
  58. {modal-1.5.3.dev13 → modal-1.5.4}/modal/mount.pyi +2 -2
  59. {modal-1.5.3.dev13 → modal-1.5.4}/modal/network_file_system.py +15 -11
  60. {modal-1.5.3.dev13 → modal-1.5.4}/modal/parallel_map.py +14 -12
  61. {modal-1.5.3.dev13 → modal-1.5.4}/modal/parallel_map.pyi +3 -2
  62. {modal-1.5.3.dev13 → modal-1.5.4}/modal/queue.py +19 -15
  63. {modal-1.5.3.dev13 → modal-1.5.4}/modal/runner.py +13 -6
  64. {modal-1.5.3.dev13 → modal-1.5.4}/modal/runner.pyi +9 -3
  65. {modal-1.5.3.dev13 → modal-1.5.4}/modal/sandbox.py +267 -142
  66. {modal-1.5.3.dev13 → modal-1.5.4}/modal/sandbox.pyi +174 -37
  67. {modal-1.5.3.dev13 → modal-1.5.4}/modal/server.pyi +25 -6
  68. {modal-1.5.3.dev13 → modal-1.5.4}/modal/token_flow.py +7 -5
  69. {modal-1.5.3.dev13 → modal-1.5.4}/modal/types.py +49 -3
  70. {modal-1.5.3.dev13 → modal-1.5.4}/modal/volume.py +61 -39
  71. {modal-1.5.3.dev13 → modal-1.5.4}/modal/volume.pyi +21 -15
  72. {modal-1.5.3.dev13 → modal-1.5.4}/modal/workspace.pyi +20 -0
  73. {modal-1.5.3.dev13 → modal-1.5.4}/modal.egg-info/PKG-INFO +1 -1
  74. modal-1.5.4/modal_proto/__init__.py +11 -0
  75. {modal-1.5.3.dev13 → modal-1.5.4}/modal_proto/api_grpc.py +96 -0
  76. {modal-1.5.3.dev13 → modal-1.5.4}/modal_proto/api_pb2.py +1438 -1282
  77. {modal-1.5.3.dev13 → modal-1.5.4}/modal_proto/api_pb2.pyi +403 -30
  78. {modal-1.5.3.dev13 → modal-1.5.4}/modal_proto/api_pb2_grpc.py +201 -2
  79. {modal-1.5.3.dev13 → modal-1.5.4}/modal_proto/api_pb2_grpc.pyi +73 -6
  80. {modal-1.5.3.dev13 → modal-1.5.4}/modal_proto/modal_api_grpc.py +6 -0
  81. {modal-1.5.3.dev13 → modal-1.5.4}/modal_proto/task_command_router_pb2.py +92 -92
  82. {modal-1.5.3.dev13 → modal-1.5.4}/modal_proto/task_command_router_pb2.pyi +10 -2
  83. {modal-1.5.3.dev13 → modal-1.5.4}/modal_version/__init__.py +1 -1
  84. {modal-1.5.3.dev13 → modal-1.5.4}/pyproject.toml +10 -35
  85. modal-1.5.3.dev13/modal/_utils/auth_token_manager.py +0 -110
  86. modal-1.5.3.dev13/modal_proto/__init__.py +0 -4
  87. {modal-1.5.3.dev13 → modal-1.5.4}/LICENSE +0 -0
  88. {modal-1.5.3.dev13 → modal-1.5.4}/README.md +0 -0
  89. {modal-1.5.3.dev13 → modal-1.5.4}/modal/__init__.py +0 -0
  90. {modal-1.5.3.dev13 → modal-1.5.4}/modal/__main__.py +0 -0
  91. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_billing.py +0 -0
  92. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_container_entrypoint.py +0 -0
  93. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_function_variants.py +0 -0
  94. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_grpc_client.py +0 -0
  95. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_ipython.py +0 -0
  96. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_load_context.py +0 -0
  97. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_location.py +0 -0
  98. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_object.py +0 -0
  99. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_output/__init__.py +0 -0
  100. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_output/manager.py +0 -0
  101. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_output/status.py +0 -0
  102. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_partial_function.py +0 -0
  103. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_resolver.py +0 -0
  104. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_resources.py +0 -0
  105. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_runtime/__init__.py +0 -0
  106. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  107. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_runtime/task_lifecycle_manager.py +0 -0
  108. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
  109. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_runtime/telemetry.py +0 -0
  110. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_runtime/user_code_event_loop.py +0 -0
  111. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_runtime/user_code_imports.py +0 -0
  112. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_serialization.py +0 -0
  113. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_traceback.py +0 -0
  114. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_tunnel.pyi +0 -0
  115. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_type_manager.py +0 -0
  116. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/__init__.py +0 -0
  117. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/app_utils.py +0 -0
  118. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/browser_utils.py +0 -0
  119. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/bytes_io_segment_payload.py +0 -0
  120. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/curl_utils.py +0 -0
  121. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/deprecation.py +0 -0
  122. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/display_utils.py +0 -0
  123. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/docker_utils.py +0 -0
  124. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/git_utils.py +0 -0
  125. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/grpc_testing.py +0 -0
  126. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/hash_utils.py +0 -0
  127. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/http_utils.py +0 -0
  128. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/jwt_utils.py +0 -0
  129. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/logger.py +0 -0
  130. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/mount_utils.py +0 -0
  131. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/name_utils.py +0 -0
  132. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/package_utils.py +0 -0
  133. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/pattern_utils.py +0 -0
  134. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/proxy_support.py +0 -0
  135. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/rand_pb_testing.py +0 -0
  136. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/sandbox_fs_utils.py +0 -0
  137. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_utils/shell_utils.py +0 -0
  138. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_vendor/__init__.py +0 -0
  139. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  140. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_vendor/cloudpickle.py +0 -0
  141. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_vendor/tblib.py +0 -0
  142. {modal-1.5.3.dev13 → modal-1.5.4}/modal/_vendor/version.py +0 -0
  143. {modal-1.5.3.dev13 → modal-1.5.4}/modal/billing.py +0 -0
  144. {modal-1.5.3.dev13 → modal-1.5.4}/modal/billing.pyi +0 -0
  145. {modal-1.5.3.dev13 → modal-1.5.4}/modal/builder/2023.12.312.txt +0 -0
  146. {modal-1.5.3.dev13 → modal-1.5.4}/modal/builder/2023.12.txt +0 -0
  147. {modal-1.5.3.dev13 → modal-1.5.4}/modal/builder/2024.04.txt +0 -0
  148. {modal-1.5.3.dev13 → modal-1.5.4}/modal/builder/2024.10.txt +0 -0
  149. {modal-1.5.3.dev13 → modal-1.5.4}/modal/builder/2025.06.txt +0 -0
  150. {modal-1.5.3.dev13 → modal-1.5.4}/modal/builder/PREVIEW.txt +0 -0
  151. {modal-1.5.3.dev13 → modal-1.5.4}/modal/builder/README.md +0 -0
  152. {modal-1.5.3.dev13 → modal-1.5.4}/modal/builder/base-images.json +0 -0
  153. {modal-1.5.3.dev13 → modal-1.5.4}/modal/call_graph.py +0 -0
  154. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/__init__.py +0 -0
  155. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/_help.py +0 -0
  156. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/_traceback.py +0 -0
  157. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/bootstrap.py +0 -0
  158. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/changelog.py +0 -0
  159. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/cluster.py +0 -0
  160. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/config.py +0 -0
  161. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/curl.py +0 -0
  162. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/dashboard.py +0 -0
  163. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/dict.py +0 -0
  164. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/endpoint.py +0 -0
  165. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/import_refs.py +0 -0
  166. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/launch.py +0 -0
  167. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/logo.py +0 -0
  168. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/network_file_system.py +0 -0
  169. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/profile.py +0 -0
  170. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/programs/__init__.py +0 -0
  171. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/programs/run_jupyter.py +0 -0
  172. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/programs/vscode.py +0 -0
  173. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/queues.py +0 -0
  174. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/secret.py +0 -0
  175. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/selector.py +0 -0
  176. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/skills.py +0 -0
  177. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cli/token.py +0 -0
  178. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cloud_bucket_mount.py +0 -0
  179. {modal-1.5.3.dev13 → modal-1.5.4}/modal/cloud_bucket_mount.pyi +0 -0
  180. {modal-1.5.3.dev13 → modal-1.5.4}/modal/container_process.py +0 -0
  181. {modal-1.5.3.dev13 → modal-1.5.4}/modal/container_process.pyi +0 -0
  182. {modal-1.5.3.dev13 → modal-1.5.4}/modal/dict.pyi +0 -0
  183. {modal-1.5.3.dev13 → modal-1.5.4}/modal/experimental/ipython.py +0 -0
  184. {modal-1.5.3.dev13 → modal-1.5.4}/modal/file_io.py +0 -0
  185. {modal-1.5.3.dev13 → modal-1.5.4}/modal/file_io.pyi +0 -0
  186. {modal-1.5.3.dev13 → modal-1.5.4}/modal/file_pattern_matcher.py +0 -0
  187. {modal-1.5.3.dev13 → modal-1.5.4}/modal/functions.py +0 -0
  188. {modal-1.5.3.dev13 → modal-1.5.4}/modal/image.py +0 -0
  189. {modal-1.5.3.dev13 → modal-1.5.4}/modal/io_streams.py +0 -0
  190. {modal-1.5.3.dev13 → modal-1.5.4}/modal/io_streams.pyi +0 -0
  191. {modal-1.5.3.dev13 → modal-1.5.4}/modal/network_file_system.pyi +0 -0
  192. {modal-1.5.3.dev13 → modal-1.5.4}/modal/object.py +0 -0
  193. {modal-1.5.3.dev13 → modal-1.5.4}/modal/object.pyi +0 -0
  194. {modal-1.5.3.dev13 → modal-1.5.4}/modal/output.py +0 -0
  195. {modal-1.5.3.dev13 → modal-1.5.4}/modal/partial_function.py +0 -0
  196. {modal-1.5.3.dev13 → modal-1.5.4}/modal/partial_function.pyi +0 -0
  197. {modal-1.5.3.dev13 → modal-1.5.4}/modal/proxy.py +0 -0
  198. {modal-1.5.3.dev13 → modal-1.5.4}/modal/proxy.pyi +0 -0
  199. {modal-1.5.3.dev13 → modal-1.5.4}/modal/py.typed +0 -0
  200. {modal-1.5.3.dev13 → modal-1.5.4}/modal/queue.pyi +0 -0
  201. {modal-1.5.3.dev13 → modal-1.5.4}/modal/retries.py +0 -0
  202. {modal-1.5.3.dev13 → modal-1.5.4}/modal/running_app.py +0 -0
  203. {modal-1.5.3.dev13 → modal-1.5.4}/modal/sandbox_fs.py +0 -0
  204. {modal-1.5.3.dev13 → modal-1.5.4}/modal/sandbox_fs.pyi +0 -0
  205. {modal-1.5.3.dev13 → modal-1.5.4}/modal/schedule.py +0 -0
  206. {modal-1.5.3.dev13 → modal-1.5.4}/modal/scheduler_placement.py +0 -0
  207. {modal-1.5.3.dev13 → modal-1.5.4}/modal/secret.py +0 -0
  208. {modal-1.5.3.dev13 → modal-1.5.4}/modal/secret.pyi +0 -0
  209. {modal-1.5.3.dev13 → modal-1.5.4}/modal/server.py +0 -0
  210. {modal-1.5.3.dev13 → modal-1.5.4}/modal/serving.py +0 -0
  211. {modal-1.5.3.dev13 → modal-1.5.4}/modal/serving.pyi +0 -0
  212. {modal-1.5.3.dev13 → modal-1.5.4}/modal/skills/modal/SKILL.md +0 -0
  213. {modal-1.5.3.dev13 → modal-1.5.4}/modal/snapshot.py +0 -0
  214. {modal-1.5.3.dev13 → modal-1.5.4}/modal/snapshot.pyi +0 -0
  215. {modal-1.5.3.dev13 → modal-1.5.4}/modal/stream_type.py +0 -0
  216. {modal-1.5.3.dev13 → modal-1.5.4}/modal/token_flow.pyi +0 -0
  217. {modal-1.5.3.dev13 → modal-1.5.4}/modal/workspace.py +0 -0
  218. {modal-1.5.3.dev13 → modal-1.5.4}/modal.egg-info/SOURCES.txt +0 -0
  219. {modal-1.5.3.dev13 → modal-1.5.4}/modal.egg-info/dependency_links.txt +0 -0
  220. {modal-1.5.3.dev13 → modal-1.5.4}/modal.egg-info/entry_points.txt +0 -0
  221. {modal-1.5.3.dev13 → modal-1.5.4}/modal.egg-info/requires.txt +0 -0
  222. {modal-1.5.3.dev13 → modal-1.5.4}/modal.egg-info/top_level.txt +0 -0
  223. {modal-1.5.3.dev13 → modal-1.5.4}/modal_docs/__init__.py +0 -0
  224. {modal-1.5.3.dev13 → modal-1.5.4}/modal_docs/gen_cli_docs.py +0 -0
  225. {modal-1.5.3.dev13 → modal-1.5.4}/modal_docs/gen_cli_docs_main.py +0 -0
  226. {modal-1.5.3.dev13 → modal-1.5.4}/modal_docs/gen_reference_docs.py +0 -0
  227. {modal-1.5.3.dev13 → modal-1.5.4}/modal_docs/gen_reference_docs_main.py +0 -0
  228. {modal-1.5.3.dev13 → modal-1.5.4}/modal_docs/mdmd/__init__.py +0 -0
  229. {modal-1.5.3.dev13 → modal-1.5.4}/modal_docs/mdmd/mdmd.py +0 -0
  230. {modal-1.5.3.dev13 → modal-1.5.4}/modal_docs/mdmd/signatures.py +0 -0
  231. {modal-1.5.3.dev13 → modal-1.5.4}/modal_docs/mdmd/types.py +0 -0
  232. {modal-1.5.3.dev13 → modal-1.5.4}/modal_docs/reference_intro.md +0 -0
  233. {modal-1.5.3.dev13 → modal-1.5.4}/modal_proto/py.typed +0 -0
  234. {modal-1.5.3.dev13 → modal-1.5.4}/modal_proto/task_command_router_grpc.py +0 -0
  235. {modal-1.5.3.dev13 → modal-1.5.4}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  236. {modal-1.5.3.dev13 → modal-1.5.4}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  237. {modal-1.5.3.dev13 → modal-1.5.4}/modal_version/__main__.py +0 -0
  238. {modal-1.5.3.dev13 → modal-1.5.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.5.3.dev13
3
+ Version: 1.5.4
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -2,6 +2,7 @@
2
2
  import os
3
3
  import socket
4
4
  from dataclasses import dataclass
5
+ from typing import cast
5
6
 
6
7
  from modal._utils.async_utils import synchronize_api
7
8
  from modal.client import _Client
@@ -15,6 +16,7 @@ class ClusterInfo:
15
16
  cluster_id: str
16
17
  container_ips: list[str]
17
18
  container_ipv4_ips: list[str]
19
+ fabric_ids: list[str]
18
20
 
19
21
 
20
22
  cluster_info: ClusterInfo | None = None
@@ -29,12 +31,22 @@ def get_cluster_info() -> ClusterInfo:
29
31
  return cluster_info
30
32
 
31
33
 
34
+ def get_fabric_peers() -> list[int]:
35
+ info = get_cluster_info()
36
+ if info.rank >= len(info.fabric_ids) or not info.fabric_ids[info.rank]:
37
+ return [info.rank]
38
+ own_fabric_id = info.fabric_ids[info.rank]
39
+ return [rank for rank, fabric_id in enumerate(info.fabric_ids) if fabric_id == own_fabric_id]
40
+
41
+
32
42
  async def _initialize_clustered_function(client: _Client, task_id: str, world_size: int):
33
43
  global cluster_info
34
44
 
35
- def get_i6pn():
45
+ def get_i6pn() -> str:
36
46
  """Returns the ipv6 address assigned to this container."""
37
- return socket.getaddrinfo("i6pn.modal.local", None, socket.AF_INET6)[0][4][0]
47
+ # An AF_INET6 result always carries a (host, port, flowinfo, scope_id) sockaddr,
48
+ # but getaddrinfo is typed for every address family, some of which lead with an int
49
+ return cast(str, socket.getaddrinfo("i6pn.modal.local", None, socket.AF_INET6)[0][4][0])
38
50
 
39
51
  hostname = socket.gethostname()
40
52
  container_ip = get_i6pn()
@@ -68,8 +80,9 @@ async def _initialize_clustered_function(client: _Client, task_id: str, world_si
68
80
  cluster_info = ClusterInfo(
69
81
  rank=resp.cluster_rank,
70
82
  cluster_id=resp.cluster_id,
71
- container_ips=resp.container_ips,
72
- container_ipv4_ips=resp.container_ipv4_ips,
83
+ container_ips=list(resp.container_ips),
84
+ container_ipv4_ips=list(resp.container_ipv4_ips),
85
+ fabric_ids=list(resp.fabric_ids),
73
86
  )
74
87
  else:
75
88
  cluster_info = ClusterInfo(
@@ -77,6 +90,7 @@ async def _initialize_clustered_function(client: _Client, task_id: str, world_si
77
90
  cluster_id="", # No cluster ID for single-node # TODO(irfansharif): Is this right?
78
91
  container_ips=[container_ip],
79
92
  container_ipv4_ips=[], # No IPv4 IPs for single-node
93
+ fabric_ids=[],
80
94
  )
81
95
 
82
96
 
@@ -3,14 +3,17 @@ import types
3
3
  import typing_extensions
4
4
 
5
5
  class ClusterInfo:
6
- """ClusterInfo(rank: int, cluster_id: str, container_ips: list[str], container_ipv4_ips: list[str])"""
6
+ """ClusterInfo(rank: int, cluster_id: str, container_ips: list[str], container_ipv4_ips: list[str], fabric_ids: list[str])"""
7
7
 
8
8
  rank: int
9
9
  cluster_id: str
10
10
  container_ips: list[str]
11
11
  container_ipv4_ips: list[str]
12
+ fabric_ids: list[str]
12
13
 
13
- def __init__(self, rank: int, cluster_id: str, container_ips: list[str], container_ipv4_ips: list[str]) -> None:
14
+ def __init__(
15
+ self, rank: int, cluster_id: str, container_ips: list[str], container_ipv4_ips: list[str], fabric_ids: list[str]
16
+ ) -> None:
14
17
  """Initialize self. See help(type(self)) for accurate signature."""
15
18
  ...
16
19
 
@@ -23,6 +26,7 @@ class ClusterInfo:
23
26
  ...
24
27
 
25
28
  def get_cluster_info() -> ClusterInfo: ...
29
+ def get_fabric_peers() -> list[int]: ...
26
30
  async def _initialize_clustered_function(client: modal.client._Client, task_id: str, world_size: int): ...
27
31
 
28
32
  class __initialize_clustered_function_spec(typing_extensions.Protocol):
@@ -4,7 +4,7 @@ import builtins
4
4
  from collections.abc import Iterable, Mapping
5
5
  from dataclasses import dataclass
6
6
  from datetime import datetime, timezone
7
- from typing import Literal
7
+ from typing import Any, Literal
8
8
 
9
9
  from google.protobuf.empty_pb2 import Empty
10
10
  from google.protobuf.message import Message
@@ -16,6 +16,7 @@ from modal_proto import api_pb2
16
16
  from ._load_context import LoadContext
17
17
  from ._object import _Object
18
18
  from ._resolver import Resolver
19
+ from ._utils.deprecation import deprecation_warning
19
20
  from ._utils.name_utils import check_environment_name
20
21
  from ._utils.time_utils import is_utc_month_aligned, parse_billing_cycle
21
22
  from .client import _Client
@@ -38,6 +39,7 @@ class _EnvironmentManager:
38
39
  name: str, # Name to use for the new Environment
39
40
  *,
40
41
  restricted: bool = False, # If True, enable RBAC restrictions on the Environment
42
+ experimental_options: dict[str, Any] | None = None, # Experimental options for Environment creation
41
43
  client: _Client | None = None, # Optional client with Modal credentials
42
44
  ) -> None:
43
45
  """Create a new Environment.
@@ -50,7 +52,10 @@ class _EnvironmentManager:
50
52
  """
51
53
  check_environment_name(name)
52
54
  client = await _Client.from_env() if client is None else client
53
- await client.stub.EnvironmentCreate(api_pb2.EnvironmentCreateRequest(name=name, is_managed=restricted))
55
+ request = api_pb2.EnvironmentCreateRequest(name=name, is_managed=restricted)
56
+ if (experimental_options or {}).get("is_public", False):
57
+ request.environment_type = api_pb2.ENVIRONMENT_TYPE_PUBLIC
58
+ await client.stub.EnvironmentCreate(request)
54
59
 
55
60
  async def list(
56
61
  self,
@@ -104,7 +109,7 @@ class _EnvironmentManager:
104
109
  await client.stub.EnvironmentDelete(api_pb2.EnvironmentDeleteRequest(name=name))
105
110
 
106
111
 
107
- class _EnvironmentMembersManager:
112
+ class _EnvironmentRolesManager:
108
113
  """mdmd:namespace"""
109
114
 
110
115
  def __init__(self, environment: "_Environment"):
@@ -112,13 +117,13 @@ class _EnvironmentMembersManager:
112
117
  self._environment = environment
113
118
 
114
119
  async def list(self) -> dict[Literal["users", "service_users"], dict[str, str]]:
115
- """Enumerate the environment roles for each user and service user in the workspace.
120
+ """Enumerate the Environment Role for each user and service user in the workspace.
116
121
 
117
122
  **Examples:**
118
123
 
119
124
  ```python notest
120
- members = modal.Environment.from_name("my-env").members.list()
121
- print(members)
125
+ roles = modal.Environment.from_name("my-env").roles.list()
126
+ print(roles)
122
127
  # {
123
128
  # "users": {"alice": "contributor", "bob": "viewer", "carol": "contributor"},
124
129
  # "service_users": {"alice-bot": "contributor", "ops-bot": "viewer", "ci-bot": "no-access"},
@@ -145,16 +150,17 @@ class _EnvironmentMembersManager:
145
150
  users: Mapping[str, str] | None = None,
146
151
  service_users: Mapping[str, str] | None = None,
147
152
  ) -> None:
148
- """Add or modify roles for members of a restricted Environment.
153
+ """Update the Environment Role of users and service users.
149
154
 
150
- Each user or service user will be added to the Environment if not currently a member;
151
- if already a member, the user or service user's role will be updated.
155
+ Each role is one of 'contributor', 'viewer', or 'no-access'. Service users can be
156
+ assigned a role on any Environment, while workspace members can only be assigned a
157
+ role on restricted Environments.
152
158
 
153
159
  **Examples:**
154
160
 
155
161
  ```python notest
156
162
  env = modal.Environment.from_name("my-restricted-env")
157
- env.members.update(
163
+ env.roles.update(
158
164
  users={"alice": "contributor", "bob": "viewer"},
159
165
  service_users={"alice-bot": "contributor"},
160
166
  )
@@ -196,24 +202,59 @@ class _EnvironmentMembersManager:
196
202
 
197
203
  await self._dispatch_role_updates(requests)
198
204
 
205
+ async def _dispatch_role_updates(self, requests: dict[str, api_pb2.EnvironmentRoleSetRequest]) -> None:
206
+ """Send batched EnvironmentRoleSet RPCs and report all errors encountered."""
207
+ results = await asyncio.gather(
208
+ *(self._environment.client.stub.EnvironmentRoleSet(req) for req in requests.values()),
209
+ return_exceptions=True,
210
+ )
211
+ errors = [(label, result) for label, result in zip(requests.keys(), results) if isinstance(result, Exception)]
212
+ if errors:
213
+ n = len(errors)
214
+ header = f"{n} error{'s' if n != 1 else ''} occurred while updating Environment roles:"
215
+ details = "\n".join(f" - {label}: {e}" for label, e in errors)
216
+ raise WorkspaceManagementError(f"{header}\n{details}")
217
+
218
+
219
+ # Deprecated alias for `_EnvironmentRolesManager`; each method warns and delegates.
220
+ class _EnvironmentMembersManager:
221
+ """mdmd:hidden"""
222
+
223
+ def __init__(self, environment: "_Environment"):
224
+ """mdmd:hidden"""
225
+ self._environment = environment
226
+
227
+ async def list(self) -> dict[Literal["users", "service_users"], dict[str, str]]:
228
+ deprecation_warning(
229
+ (2026, 7, 23),
230
+ "`Environment.members.list()` is deprecated; use `Environment.roles.list()` instead.",
231
+ )
232
+ return await _EnvironmentRolesManager(self._environment).list()
233
+
234
+ async def update(
235
+ self,
236
+ *,
237
+ users: Mapping[str, str] | None = None,
238
+ service_users: Mapping[str, str] | None = None,
239
+ ) -> None:
240
+ deprecation_warning(
241
+ (2026, 7, 23),
242
+ "`Environment.members.update()` is deprecated; use `Environment.roles.update()` instead.",
243
+ )
244
+ await _EnvironmentRolesManager(self._environment).update(users=users, service_users=service_users)
245
+
199
246
  async def remove(
200
247
  self,
201
248
  *,
202
249
  users: Iterable[str] | None = None,
203
250
  service_users: Iterable[str] | None = None,
204
251
  ) -> None:
205
- """Remove members from a restricted Environment.
206
-
207
- **Examples:**
208
-
209
- ```python notest
210
- env = modal.Environment.from_name("my-restricted-env")
211
- env.members.remove(
212
- users=["alice"],
213
- service_users=["alice-bot"],
252
+ """Remove the Environment Role of users and service users, reverting them to the default."""
253
+ deprecation_warning(
254
+ (2026, 7, 23),
255
+ "`Environment.members.remove()` is deprecated. Environment Roles are now explicit; "
256
+ "set a role (e.g. 'no-access') with `Environment.roles.update()` instead.",
214
257
  )
215
- ```
216
- """
217
258
  await self._environment.hydrate()
218
259
  users = users or []
219
260
  service_users = service_users or []
@@ -247,20 +288,7 @@ class _EnvironmentMembersManager:
247
288
  role=api_pb2.ENVIRONMENT_ROLE_UNSPECIFIED,
248
289
  )
249
290
 
250
- await self._dispatch_role_updates(requests)
251
-
252
- async def _dispatch_role_updates(self, requests: dict[str, api_pb2.EnvironmentRoleSetRequest]) -> None:
253
- """Send batched EnvironmentRoleSet RPCs and report all errors encountered."""
254
- results = await asyncio.gather(
255
- *(self._environment.client.stub.EnvironmentRoleSet(req) for req in requests.values()),
256
- return_exceptions=True,
257
- )
258
- errors = [(label, result) for label, result in zip(requests.keys(), results) if isinstance(result, Exception)]
259
- if errors:
260
- n = len(errors)
261
- header = f"{n} error{'s' if n != 1 else ''} occurred while updating Environment members:"
262
- details = "\n".join(f" - {label}: {e}" for label, e in errors)
263
- raise WorkspaceManagementError(f"{header}\n{details}")
291
+ await _EnvironmentRolesManager(self._environment)._dispatch_role_updates(requests)
264
292
 
265
293
 
266
294
  class _Environment(_Object, type_prefix="en"):
@@ -284,11 +312,17 @@ class _Environment(_Object, type_prefix="en"):
284
312
  return _EnvironmentManager()
285
313
 
286
314
  @property
287
- def members(self) -> "_EnvironmentMembersManager":
288
- """Namespace with methods for managing the membership of a restricted Environment.
315
+ def roles(self) -> "_EnvironmentRolesManager":
316
+ """Namespace with methods for managing the Environment Roles of users and service users.
289
317
 
290
- See https://modal.com/docs/guide/rbac for more information on restricted Environments.
318
+ See https://modal.com/docs/guide/rbac for more information on Environment Roles.
291
319
  """
320
+ return _EnvironmentRolesManager(self)
321
+
322
+ @property
323
+ def members(self) -> "_EnvironmentMembersManager":
324
+ """mdmd:hidden"""
325
+ # Deprecated alias for `Environment.roles`.
292
326
  return _EnvironmentMembersManager(self)
293
327
 
294
328
  # TODO(michael) Keeping this private for now until we decide what else should be in it
@@ -45,7 +45,7 @@ from ._utils.async_utils import (
45
45
  synchronizer,
46
46
  warn_if_generator_is_not_consumed,
47
47
  )
48
- from ._utils.blob_utils import MAX_OBJECT_SIZE_BYTES
48
+ from ._utils.blob_utils import MAX_ASYNC_OBJECT_SIZE_BYTES, MAX_OBJECT_SIZE_BYTES
49
49
  from ._utils.function_utils import (
50
50
  ATTEMPT_TIMEOUT_GRACE_PERIOD,
51
51
  OUTPUTS_TIMEOUT,
@@ -56,7 +56,9 @@ from ._utils.function_utils import (
56
56
  _stream_function_call_data,
57
57
  get_function_type,
58
58
  is_async,
59
+ normalize_fractional_target_concurrency,
59
60
  parse_gpu_config,
61
+ validate_target_concurrency,
60
62
  )
61
63
  from ._utils.grpc_utils import Retry, RetryWarningMessage
62
64
  from ._utils.mount_utils import validate_network_file_systems, validate_volumes, validate_volumes_by_object_id
@@ -93,7 +95,7 @@ from .proxy import _Proxy
93
95
  from .retries import Retries, RetryManager
94
96
  from .schedule import Schedule
95
97
  from .secret import _Secret
96
- from .types import FunctionStats
98
+ from .types import FunctionAutoscalerSettings, FunctionStats, ServerAutoscalerSettings
97
99
  from .volume import _Volume, _volume_to_mount_proto
98
100
 
99
101
  if TYPE_CHECKING:
@@ -424,6 +426,7 @@ class _InputPlaneInvocation:
424
426
  client: _Client,
425
427
  input_plane_url: str,
426
428
  input_plane_region: str,
429
+ function_call_invocation_type: "api_pb2.FunctionCallInvocationType.ValueType",
427
430
  ) -> "_InputPlaneInvocation":
428
431
  stub = await client.get_stub(input_plane_url)
429
432
 
@@ -435,6 +438,7 @@ class _InputPlaneInvocation:
435
438
  kwargs,
436
439
  control_plane_stub,
437
440
  function=function,
441
+ function_call_invocation_type=function_call_invocation_type,
438
442
  )
439
443
 
440
444
  request = api_pb2.AttemptStartRequest(
@@ -636,7 +640,12 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
636
640
  await self.hydrate()
637
641
  if not self._app_id:
638
642
  raise ExecutionError("app_id should have been set during function hydration")
639
- return _LogQueryData(self.client, self._app_id, LogsFilters(function_id=self.object_id))
643
+ return _LogQueryData(
644
+ self.client,
645
+ self._app_id,
646
+ LogsFilters(function_id=self.object_id),
647
+ source_object_id=self.object_id,
648
+ )
640
649
 
641
650
  @property
642
651
  def logs(self) -> _FunctionLogsManager:
@@ -679,7 +688,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
679
688
  scaleup_window: int | None = None,
680
689
  scaledown_window: int | None = None,
681
690
  max_concurrent_inputs: int | None = None,
682
- target_concurrent_inputs: int | None = None,
691
+ target_concurrent_inputs: float | None = None,
683
692
  batch_max_size: int | None = None,
684
693
  batch_wait_ms: int | None = None,
685
694
  cloud: str | None = None,
@@ -787,6 +796,17 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
787
796
  scaledown_window=scaledown_window,
788
797
  )
789
798
 
799
+ target_concurrent_inputs_int = 0
800
+ if target_concurrent_inputs is not None:
801
+ if is_server:
802
+ validate_target_concurrency(target_concurrent_inputs, "target_inputs", allow_fractional=True)
803
+ autoscaler_settings.target_concurrency_float = normalize_fractional_target_concurrency(
804
+ target_concurrent_inputs
805
+ )
806
+ else:
807
+ validate_target_concurrency(target_concurrent_inputs, "target_inputs", allow_fractional=False)
808
+ target_concurrent_inputs_int = int(target_concurrent_inputs)
809
+
790
810
  # For clustered functions, container settings must be multiples of cluster_size
791
811
  if cluster_size is not None and cluster_size > 1:
792
812
  for field in ["min_containers", "max_containers", "buffer_containers"]:
@@ -1012,7 +1032,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1012
1032
  app_name=app_name,
1013
1033
  is_builder_function=is_builder_function,
1014
1034
  max_concurrent_inputs=max_concurrent_inputs or 0,
1015
- target_concurrent_inputs=target_concurrent_inputs or 0,
1035
+ target_concurrent_inputs=target_concurrent_inputs_int,
1016
1036
  batch_max_size=batch_max_size or 0,
1017
1037
  batch_linger_ms=batch_wait_ms or 0,
1018
1038
  worker_id=config.get("worker_id"),
@@ -1172,6 +1192,25 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1172
1192
  return obj
1173
1193
 
1174
1194
  async def _update_autoscaler(
1195
+ self,
1196
+ *,
1197
+ min_containers: int | None = None,
1198
+ max_containers: int | None = None,
1199
+ buffer_containers: int | None = None,
1200
+ scaledown_window: int | None = None,
1201
+ ) -> FunctionAutoscalerSettings:
1202
+ settings = api_pb2.AutoscalerSettings(
1203
+ min_containers=min_containers,
1204
+ max_containers=max_containers,
1205
+ buffer_containers=buffer_containers,
1206
+ scaledown_window=scaledown_window,
1207
+ )
1208
+ request = api_pb2.FunctionUpdateSchedulingParamsRequest(function_id=self.object_id, settings=settings)
1209
+ response = await self.client.stub.FunctionUpdateSchedulingParams(request)
1210
+
1211
+ return FunctionAutoscalerSettings._from_proto(response.current_settings)
1212
+
1213
+ async def _update_autoscaler_server(
1175
1214
  self,
1176
1215
  *,
1177
1216
  min_containers: int | None = None,
@@ -1179,21 +1218,22 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1179
1218
  buffer_containers: int | None = None,
1180
1219
  scaleup_window: int | None = None,
1181
1220
  scaledown_window: int | None = None,
1182
- target_concurrency: int | None = None,
1183
- ) -> None:
1221
+ target_concurrency: float | None = None,
1222
+ ) -> ServerAutoscalerSettings:
1184
1223
  settings = api_pb2.AutoscalerSettings(
1185
1224
  min_containers=min_containers,
1186
1225
  max_containers=max_containers,
1187
1226
  buffer_containers=buffer_containers,
1188
1227
  scaleup_window=scaleup_window,
1189
1228
  scaledown_window=scaledown_window,
1190
- target_concurrency=target_concurrency,
1191
1229
  )
1230
+ if target_concurrency is not None:
1231
+ validate_target_concurrency(target_concurrency, "target_concurrency", allow_fractional=True)
1232
+ settings.target_concurrency_float = normalize_fractional_target_concurrency(target_concurrency)
1192
1233
  request = api_pb2.FunctionUpdateSchedulingParamsRequest(function_id=self.object_id, settings=settings)
1193
- await self.client.stub.FunctionUpdateSchedulingParams(request)
1234
+ response = await self.client.stub.FunctionUpdateSchedulingParams(request)
1194
1235
 
1195
- # One idea would be for FunctionUpdateScheduleParams to return the current (coalesced) settings
1196
- # and then we could return them here (would need some ad hoc dataclass, which I don't love)
1236
+ return ServerAutoscalerSettings._from_proto(response.current_settings)
1197
1237
 
1198
1238
  @live_method
1199
1239
  async def update_autoscaler(
@@ -1203,7 +1243,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1203
1243
  max_containers: int | None = None,
1204
1244
  buffer_containers: int | None = None,
1205
1245
  scaledown_window: int | None = None,
1206
- ) -> None:
1246
+ ) -> FunctionAutoscalerSettings:
1207
1247
  """Override the current autoscaler behavior for this Function.
1208
1248
 
1209
1249
  Unspecified parameters will retain their current value, i.e. either the static value
@@ -1218,6 +1258,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1218
1258
  buffer_containers: Extra containers to keep warm beyond current demand.
1219
1259
  scaledown_window: Maximum duration (in seconds) idle containers wait before scaling down.
1220
1260
 
1261
+ Returns:
1262
+ A `FunctionAutoscalerSettings` dataclass which contains the current autoscaler settings
1263
+ of this Function after the call.
1264
+
1221
1265
  Examples:
1222
1266
  ```python notest
1223
1267
  f = modal.Function.from_name("my-app", "function")
@@ -1237,7 +1281,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1237
1281
  if self._is_method:
1238
1282
  raise InvalidError("Cannot call .update_autoscaler() on a method. Call it on the class instance instead.")
1239
1283
 
1240
- await self._update_autoscaler(
1284
+ return await self._update_autoscaler(
1241
1285
  min_containers=min_containers,
1242
1286
  max_containers=max_containers,
1243
1287
  buffer_containers=buffer_containers,
@@ -1427,6 +1471,11 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1427
1471
  self._max_object_size_bytes = (
1428
1472
  metadata.max_object_size_bytes if metadata.HasField("max_object_size_bytes") else MAX_OBJECT_SIZE_BYTES
1429
1473
  )
1474
+ self._max_async_object_size_bytes = (
1475
+ metadata.max_async_object_size_bytes
1476
+ if metadata.HasField("max_async_object_size_bytes")
1477
+ else MAX_ASYNC_OBJECT_SIZE_BYTES
1478
+ )
1430
1479
  self._experimental_flash_urls = metadata._experimental_flash_urls
1431
1480
  self._app_id = metadata.app_id or None
1432
1481
 
@@ -1451,6 +1500,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1451
1500
  input_plane_url=self._input_plane_url,
1452
1501
  input_plane_region=self._input_plane_region,
1453
1502
  max_object_size_bytes=self._max_object_size_bytes,
1503
+ max_async_object_size_bytes=self._max_async_object_size_bytes,
1454
1504
  _experimental_flash_urls=self._experimental_flash_urls,
1455
1505
  supported_input_formats=self._metadata.supported_input_formats if self._metadata else [],
1456
1506
  supported_output_formats=self._metadata.supported_output_formats if self._metadata else [],
@@ -1714,6 +1764,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1714
1764
  client=self.client,
1715
1765
  input_plane_url=self._input_plane_url,
1716
1766
  input_plane_region=self._input_plane_region,
1767
+ function_call_invocation_type=api_pb2.FUNCTION_CALL_INVOCATION_TYPE_SYNC,
1717
1768
  )
1718
1769
  else:
1719
1770
  invocation = await _Invocation.create(
@@ -1755,6 +1806,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1755
1806
  client=self.client,
1756
1807
  input_plane_url=self._input_plane_url,
1757
1808
  input_plane_region=self._input_plane_region,
1809
+ function_call_invocation_type=api_pb2.FUNCTION_CALL_INVOCATION_TYPE_SYNC_LEGACY,
1758
1810
  )
1759
1811
  else:
1760
1812
  invocation = await _Invocation.create(
@@ -2030,7 +2082,12 @@ class _FunctionCall(typing.Generic[ReturnType], _Object, type_prefix="fc"):
2030
2082
  await self._hydrate_from_id_metadata()
2031
2083
  if not self._app_id:
2032
2084
  raise ExecutionError("app_id should have been set during function call hydration")
2033
- return _LogQueryData(self.client, self._app_id, LogsFilters(function_call_id=self.object_id))
2085
+ return _LogQueryData(
2086
+ self.client,
2087
+ self._app_id,
2088
+ LogsFilters(function_call_id=self.object_id),
2089
+ source_object_id=self.object_id,
2090
+ )
2034
2091
 
2035
2092
  @property
2036
2093
  def logs(self) -> _FunctionCallLogsManager: