modal 1.5.3.dev10__tar.gz → 1.5.3.dev12__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.3.dev10 → modal-1.5.3.dev12}/PKG-INFO +1 -1
  2. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_environments.py +67 -1
  3. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_functions.py +47 -0
  4. modal-1.5.3.dev12/modal/_logs_manager.py +674 -0
  5. modal-1.5.3.dev12/modal/_logs_manager.pyi +1063 -0
  6. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_server.py +20 -0
  7. modal-1.5.3.dev12/modal/_supports_logs.py +32 -0
  8. modal-1.5.3.dev12/modal/_utils/display_utils.py +15 -0
  9. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/time_utils.py +103 -13
  10. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_workspace.py +66 -1
  11. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/billing.py +120 -16
  12. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/endpoint.py +21 -1
  13. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/environment.py +102 -3
  14. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/client.pyi +2 -2
  15. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/environments.pyi +69 -0
  16. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/exception.py +4 -0
  17. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/functions.pyi +44 -0
  18. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/sandbox.py +67 -0
  19. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/sandbox.pyi +78 -0
  20. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/server.pyi +23 -0
  21. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/types.py +81 -1
  22. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/workspace.pyi +71 -0
  23. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal.egg-info/PKG-INFO +1 -1
  24. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal.egg-info/SOURCES.txt +4 -0
  25. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/api_grpc.py +16 -0
  26. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/api_pb2.py +499 -441
  27. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/api_pb2.pyi +88 -0
  28. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/api_pb2_grpc.py +33 -0
  29. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/api_pb2_grpc.pyi +10 -0
  30. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/modal_api_grpc.py +1 -0
  31. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/task_command_router_pb2.py +92 -92
  32. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/task_command_router_pb2.pyi +11 -1
  33. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_version/__init__.py +1 -1
  34. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/pyproject.toml +0 -1
  35. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/LICENSE +0 -0
  36. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/README.md +0 -0
  37. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/__init__.py +0 -0
  38. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/__main__.py +0 -0
  39. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_billing.py +0 -0
  40. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_clustered_functions.py +0 -0
  41. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_clustered_functions.pyi +0 -0
  42. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_container_entrypoint.py +0 -0
  43. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_function_variants.py +0 -0
  44. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_grpc_client.py +0 -0
  45. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_image.py +0 -0
  46. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_ipython.py +0 -0
  47. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_load_context.py +0 -0
  48. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_location.py +0 -0
  49. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_logs.py +0 -0
  50. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_object.py +0 -0
  51. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_output/__init__.py +0 -0
  52. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_output/manager.py +0 -0
  53. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_output/pty.py +0 -0
  54. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_output/rich.py +0 -0
  55. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_output/status.py +0 -0
  56. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_partial_function.py +0 -0
  57. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_resolver.py +0 -0
  58. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_resources.py +0 -0
  59. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_runtime/__init__.py +0 -0
  60. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_runtime/asgi.py +0 -0
  61. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_runtime/container_io_manager.py +0 -0
  62. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_runtime/container_io_manager.pyi +0 -0
  63. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_runtime/execution_context.py +0 -0
  64. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_runtime/execution_context.pyi +0 -0
  65. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  66. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_runtime/task_lifecycle_manager.py +0 -0
  67. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
  68. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_runtime/telemetry.py +0 -0
  69. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_runtime/user_code_event_loop.py +0 -0
  70. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_runtime/user_code_imports.py +0 -0
  71. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_serialization.py +0 -0
  72. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_traceback.py +0 -0
  73. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_tunnel.py +0 -0
  74. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_tunnel.pyi +0 -0
  75. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_type_manager.py +0 -0
  76. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/__init__.py +0 -0
  77. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/app_utils.py +0 -0
  78. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/async_utils.py +0 -0
  79. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/auth_token_manager.py +0 -0
  80. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/blob_utils.py +0 -0
  81. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/browser_utils.py +0 -0
  82. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/bytes_io_segment_payload.py +0 -0
  83. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/curl_utils.py +0 -0
  84. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/deprecation.py +0 -0
  85. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/docker_utils.py +0 -0
  86. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/function_utils.py +0 -0
  87. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/git_utils.py +0 -0
  88. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/grpc_testing.py +0 -0
  89. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/grpc_utils.py +0 -0
  90. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/hash_utils.py +0 -0
  91. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/http_utils.py +0 -0
  92. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/jwt_utils.py +0 -0
  93. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/logger.py +0 -0
  94. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/mount_utils.py +0 -0
  95. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/name_utils.py +0 -0
  96. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/package_utils.py +0 -0
  97. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/pattern_utils.py +0 -0
  98. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/proxy_support.py +0 -0
  99. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/rand_pb_testing.py +0 -0
  100. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/sandbox_fs_utils.py +0 -0
  101. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/shell_utils.py +0 -0
  102. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_utils/task_command_router_client.py +0 -0
  103. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_vendor/__init__.py +0 -0
  104. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  105. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_vendor/cloudpickle.py +0 -0
  106. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_vendor/tblib.py +0 -0
  107. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_vendor/version.py +0 -0
  108. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/_watcher.py +0 -0
  109. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/app.py +0 -0
  110. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/app.pyi +0 -0
  111. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/billing.py +0 -0
  112. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/billing.pyi +0 -0
  113. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/builder/2023.12.312.txt +0 -0
  114. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/builder/2023.12.txt +0 -0
  115. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/builder/2024.04.txt +0 -0
  116. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/builder/2024.10.txt +0 -0
  117. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/builder/2025.06.txt +0 -0
  118. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/builder/PREVIEW.txt +0 -0
  119. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/builder/README.md +0 -0
  120. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/builder/base-images.json +0 -0
  121. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/call_graph.py +0 -0
  122. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/__init__.py +0 -0
  123. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/_download.py +0 -0
  124. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/_help.py +0 -0
  125. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/_traceback.py +0 -0
  126. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/app.py +0 -0
  127. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/bootstrap.py +0 -0
  128. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/changelog.py +0 -0
  129. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/cluster.py +0 -0
  130. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/config.py +0 -0
  131. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/container.py +0 -0
  132. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/curl.py +0 -0
  133. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/dashboard.py +0 -0
  134. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/dict.py +0 -0
  135. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/entry_point.py +0 -0
  136. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/image.py +0 -0
  137. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/import_refs.py +0 -0
  138. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/launch.py +0 -0
  139. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/logo.py +0 -0
  140. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/network_file_system.py +0 -0
  141. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/profile.py +0 -0
  142. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/programs/__init__.py +0 -0
  143. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/programs/run_jupyter.py +0 -0
  144. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/programs/vscode.py +0 -0
  145. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/queues.py +0 -0
  146. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/run.py +0 -0
  147. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/secret.py +0 -0
  148. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/selector.py +0 -0
  149. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/shell.py +0 -0
  150. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/skills.py +0 -0
  151. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/token.py +0 -0
  152. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/utils.py +0 -0
  153. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/volume.py +0 -0
  154. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cli/workspace.py +0 -0
  155. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/client.py +0 -0
  156. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cloud_bucket_mount.py +0 -0
  157. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cloud_bucket_mount.pyi +0 -0
  158. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cls.py +0 -0
  159. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/cls.pyi +0 -0
  160. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/config.py +0 -0
  161. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/container_process.py +0 -0
  162. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/container_process.pyi +0 -0
  163. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/dict.py +0 -0
  164. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/dict.pyi +0 -0
  165. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/environments.py +0 -0
  166. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/experimental/__init__.py +0 -0
  167. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/experimental/flash.py +0 -0
  168. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/experimental/flash.pyi +0 -0
  169. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/experimental/ipython.py +0 -0
  170. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/file_io.py +0 -0
  171. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/file_io.pyi +0 -0
  172. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/file_pattern_matcher.py +0 -0
  173. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/functions.py +0 -0
  174. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/image.py +0 -0
  175. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/image.pyi +0 -0
  176. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/io_streams.py +0 -0
  177. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/io_streams.pyi +0 -0
  178. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/mount.py +0 -0
  179. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/mount.pyi +0 -0
  180. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/network_file_system.py +0 -0
  181. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/network_file_system.pyi +0 -0
  182. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/object.py +0 -0
  183. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/object.pyi +0 -0
  184. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/output.py +0 -0
  185. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/parallel_map.py +0 -0
  186. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/parallel_map.pyi +0 -0
  187. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/partial_function.py +0 -0
  188. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/partial_function.pyi +0 -0
  189. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/proxy.py +0 -0
  190. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/proxy.pyi +0 -0
  191. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/py.typed +0 -0
  192. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/queue.py +0 -0
  193. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/queue.pyi +0 -0
  194. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/retries.py +0 -0
  195. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/runner.py +0 -0
  196. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/runner.pyi +0 -0
  197. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/running_app.py +0 -0
  198. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/sandbox_fs.py +0 -0
  199. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/sandbox_fs.pyi +0 -0
  200. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/schedule.py +0 -0
  201. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/scheduler_placement.py +0 -0
  202. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/secret.py +0 -0
  203. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/secret.pyi +0 -0
  204. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/server.py +0 -0
  205. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/serving.py +0 -0
  206. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/serving.pyi +0 -0
  207. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/skills/modal/SKILL.md +0 -0
  208. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/snapshot.py +0 -0
  209. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/snapshot.pyi +0 -0
  210. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/stream_type.py +0 -0
  211. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/token_flow.py +0 -0
  212. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/token_flow.pyi +0 -0
  213. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/volume.py +0 -0
  214. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/volume.pyi +0 -0
  215. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal/workspace.py +0 -0
  216. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal.egg-info/dependency_links.txt +0 -0
  217. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal.egg-info/entry_points.txt +0 -0
  218. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal.egg-info/requires.txt +0 -0
  219. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal.egg-info/top_level.txt +0 -0
  220. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_docs/__init__.py +0 -0
  221. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_docs/gen_cli_docs.py +0 -0
  222. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_docs/gen_cli_docs_main.py +0 -0
  223. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_docs/gen_reference_docs.py +0 -0
  224. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_docs/gen_reference_docs_main.py +0 -0
  225. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_docs/mdmd/__init__.py +0 -0
  226. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_docs/mdmd/mdmd.py +0 -0
  227. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_docs/mdmd/signatures.py +0 -0
  228. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_docs/mdmd/types.py +0 -0
  229. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_docs/reference_intro.md +0 -0
  230. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/__init__.py +0 -0
  231. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/py.typed +0 -0
  232. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/task_command_router_grpc.py +0 -0
  233. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  234. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  235. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/modal_version/__main__.py +0 -0
  236. {modal-1.5.3.dev10 → modal-1.5.3.dev12}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.5.3.dev10
3
+ Version: 1.5.3.dev12
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -17,10 +17,11 @@ from ._load_context import LoadContext
17
17
  from ._object import _Object
18
18
  from ._resolver import Resolver
19
19
  from ._utils.name_utils import check_environment_name
20
+ from ._utils.time_utils import is_utc_month_aligned, parse_billing_cycle
20
21
  from .client import _Client
21
22
  from .config import config, logger
22
23
  from .exception import InvalidError, WorkspaceManagementError
23
- from .types import BillingReportItem
24
+ from .types import BillingReportItem, EnvironmentBillingSummary
24
25
 
25
26
 
26
27
  @dataclass(frozen=True)
@@ -450,6 +451,71 @@ class _EnvironmentBillingManager:
450
451
  async for pb_item in self._environment.client.stub.WorkspaceBillingReport.unary_stream(request)
451
452
  ]
452
453
 
454
+ async def summary(
455
+ self,
456
+ cycle: str | datetime | None = None, # Start of the summary, inclusive
457
+ ) -> EnvironmentBillingSummary:
458
+ """Return a summary of environment cost over a single billing cycle determined by `cycle`.
459
+
460
+ Unlike the analogous `Workspace.billing.summary()`, this API only emits metered cost
461
+ information. This is because billing adjustments due to credits, free storage, etc. are
462
+ applied at the Workspace level, and thus cannot be attributed to individual Environments.
463
+
464
+ Args:
465
+ cycle: Start of the summary, inclusive. Must be the first of a month, and must be in UTC
466
+ or timezone-naive (interpreted as UTC). If provided as a string, it must either be
467
+ formatted as an ISO 8601 month (YYYY-MM), or must be one of the convenience spellings
468
+ "this month" or "last month". If not provided, `cycle` defaults to the first of the
469
+ current month (in which case a summary is generated for the current billing cycle).
470
+
471
+ Returns:
472
+ A single `EnvironmentBillingSummary` dataclass containing the following fields:
473
+ - `metered_cost` representing cost before any adjustments, and
474
+ - `metered_cost_breakdown` containing a breakdown of that cost by the Modal resources
475
+ that generated it. The exact keys of this are subject to change as Modal's billing
476
+ model evolves.
477
+
478
+ All values are reported as `decimal.Decimal`s.
479
+
480
+ See also:
481
+ - [`modal environment billing summary`](https://modal.com/docs/cli/latest/billing#modal-environment-billing-summary):
482
+ An environment summary CLI that has convenience features around relative time range queries.
483
+ - [`Environment.billing.report()`](https://modal.com/docs/sdk/py/latest/Environment#billingreport):
484
+ An analogous report API that is scoped to a specific Environment.
485
+ """
486
+
487
+ if cycle is None:
488
+ cycle = datetime.now(timezone.utc).replace(
489
+ day=1,
490
+ hour=0,
491
+ minute=0,
492
+ second=0,
493
+ microsecond=0,
494
+ )
495
+ elif isinstance(cycle, str):
496
+ cycle = parse_billing_cycle(cycle)
497
+
498
+ if cycle.tzinfo is None:
499
+ cycle = cycle.replace(tzinfo=timezone.utc)
500
+ elif cycle.tzinfo != timezone.utc:
501
+ raise InvalidError("Timezone-aware 'cycle' parameter must be in UTC.")
502
+
503
+ if not is_utc_month_aligned(cycle):
504
+ raise InvalidError("Provided 'cycle' parameter must be the first of a month.")
505
+
506
+ if cycle > datetime.now(timezone.utc):
507
+ raise InvalidError("Provided 'cycle' parameter cannot be in the future.")
508
+
509
+ if not self._environment.is_hydrated:
510
+ await self._environment.hydrate()
511
+
512
+ request = api_pb2.EnvironmentBillingSummaryRequest(environment_id=self._environment.object_id)
513
+ request.start_timestamp.FromDatetime(cycle)
514
+
515
+ return EnvironmentBillingSummary._from_proto(
516
+ await self._environment.client.stub.EnvironmentBillingSummary(request)
517
+ )
518
+
453
519
 
454
520
  ENVIRONMENT_CACHE: dict[str, _Environment] = {}
455
521
 
@@ -22,6 +22,8 @@ from modal_proto.modal_api_grpc import ModalClientModal
22
22
  from ._function_variants import _FunctionOptions, _make_function_variant
23
23
  from ._image import _Image
24
24
  from ._load_context import LoadContext
25
+ from ._logs import LogsFilters
26
+ from ._logs_manager import _FunctionCallLogsManager, _FunctionLogsManager
25
27
  from ._object import _Object, live_method, live_method_gen
26
28
  from ._output.pty import get_pty_info
27
29
  from ._output.status import FunctionCreationStatus
@@ -32,6 +34,7 @@ from ._serialization import (
32
34
  get_callable_schema,
33
35
  serialize,
34
36
  )
37
+ from ._supports_logs import _LogQueryData
35
38
  from ._traceback import print_server_warnings
36
39
  from ._utils.async_utils import (
37
40
  TaskContext,
@@ -629,6 +632,27 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
629
632
  _base_function: "_Function | None" = None
630
633
  _app_id: str | None = None
631
634
 
635
+ async def _get_log_query_data(self) -> _LogQueryData:
636
+ await self.hydrate()
637
+ if not self._app_id:
638
+ 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))
640
+
641
+ @property
642
+ def logs(self) -> _FunctionLogsManager:
643
+ """Access logs for a `Function`.
644
+
645
+ Use [`fetch()`](#logsfetch)
646
+ to read logs from a UTC time range, [`tail()`](#logstail)
647
+ to read the most recent logs, and [`stream()`](#logsstream)
648
+ to follow new logs as they arrive.
649
+
650
+ See also:
651
+ - [`modal app logs`](https://modal.com/docs/cli/latest/app#modal-app-logs):
652
+ CLI access to logs for an App.
653
+ """
654
+ return _FunctionLogsManager(self)
655
+
632
656
  @staticmethod
633
657
  def from_local(
634
658
  info: FunctionInfo,
@@ -2000,6 +2024,29 @@ class _FunctionCall(typing.Generic[ReturnType], _Object, type_prefix="fc"):
2000
2024
  resp = await self.client.stub.FunctionCallFromId(request)
2001
2025
  self._hydrate_metadata(resp)
2002
2026
 
2027
+ async def _get_log_query_data(self) -> _LogQueryData:
2028
+ await self.hydrate()
2029
+ if not self._app_id:
2030
+ await self._hydrate_from_id_metadata()
2031
+ if not self._app_id:
2032
+ 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))
2034
+
2035
+ @property
2036
+ def logs(self) -> _FunctionCallLogsManager:
2037
+ """Access logs for a single `FunctionCall`.
2038
+
2039
+ Use [`fetch()`](#logsfetch)
2040
+ to read logs from a UTC time range, [`tail()`](#logstail)
2041
+ to read the most recent logs, and [`stream()`](#logsstream)
2042
+ to follow new logs as they arrive.
2043
+
2044
+ See also:
2045
+ - [`modal app logs`](https://modal.com/docs/cli/latest/app#modal-app-logs):
2046
+ CLI access to logs for an App.
2047
+ """
2048
+ return _FunctionCallLogsManager(self)
2049
+
2003
2050
  @live_method
2004
2051
  async def num_inputs(self) -> int:
2005
2052
  """Get the number of inputs in the function call.