modAL 1.3.1.dev10__tar.gz → 1.3.1.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 (195) hide show
  1. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/PKG-INFO +1 -1
  2. modal-1.3.1.dev12/modal/cli/token.py +108 -0
  3. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/client.pyi +2 -2
  4. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/functions.pyi +6 -6
  5. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal.egg-info/PKG-INFO +1 -1
  6. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/api.proto +30 -1
  7. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/api_grpc.py +16 -0
  8. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/api_pb2.py +263 -223
  9. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/api_pb2.pyi +87 -0
  10. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/api_pb2_grpc.py +33 -0
  11. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/api_pb2_grpc.pyi +10 -0
  12. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/modal_api_grpc.py +1 -0
  13. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_version/__init__.py +1 -1
  14. modal-1.3.1.dev10/modal/cli/token.py +0 -60
  15. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/LICENSE +0 -0
  16. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/README.md +0 -0
  17. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/__init__.py +0 -0
  18. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/__main__.py +0 -0
  19. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_billing.py +0 -0
  20. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_clustered_functions.py +0 -0
  21. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_clustered_functions.pyi +0 -0
  22. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_container_entrypoint.py +0 -0
  23. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_functions.py +0 -0
  24. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_grpc_client.py +0 -0
  25. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_ipython.py +0 -0
  26. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_load_context.py +0 -0
  27. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_location.py +0 -0
  28. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_object.py +0 -0
  29. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_output.py +0 -0
  30. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_partial_function.py +0 -0
  31. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_pty.py +0 -0
  32. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_resolver.py +0 -0
  33. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_resources.py +0 -0
  34. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_runtime/__init__.py +0 -0
  35. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_runtime/asgi.py +0 -0
  36. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_runtime/container_io_manager.py +0 -0
  37. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_runtime/container_io_manager.pyi +0 -0
  38. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_runtime/execution_context.py +0 -0
  39. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_runtime/execution_context.pyi +0 -0
  40. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  41. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_runtime/telemetry.py +0 -0
  42. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_runtime/user_code_event_loop.py +0 -0
  43. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_runtime/user_code_imports.py +0 -0
  44. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_serialization.py +0 -0
  45. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_traceback.py +0 -0
  46. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_tunnel.py +0 -0
  47. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_tunnel.pyi +0 -0
  48. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_type_manager.py +0 -0
  49. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/__init__.py +0 -0
  50. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/app_utils.py +0 -0
  51. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/async_utils.py +0 -0
  52. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/auth_token_manager.py +0 -0
  53. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/blob_utils.py +0 -0
  54. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/bytes_io_segment_payload.py +0 -0
  55. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/deprecation.py +0 -0
  56. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/docker_utils.py +0 -0
  57. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/function_utils.py +0 -0
  58. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/git_utils.py +0 -0
  59. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/grpc_testing.py +0 -0
  60. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/grpc_utils.py +0 -0
  61. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/hash_utils.py +0 -0
  62. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/http_utils.py +0 -0
  63. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/jwt_utils.py +0 -0
  64. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/logger.py +0 -0
  65. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/mount_utils.py +0 -0
  66. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/name_utils.py +0 -0
  67. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/package_utils.py +0 -0
  68. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/pattern_utils.py +0 -0
  69. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/rand_pb_testing.py +0 -0
  70. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/shell_utils.py +0 -0
  71. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/task_command_router_client.py +0 -0
  72. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_utils/time_utils.py +0 -0
  73. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_vendor/__init__.py +0 -0
  74. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  75. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_vendor/cloudpickle.py +0 -0
  76. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_vendor/tblib.py +0 -0
  77. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/_watcher.py +0 -0
  78. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/app.py +0 -0
  79. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/app.pyi +0 -0
  80. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/billing.py +0 -0
  81. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/builder/2023.12.312.txt +0 -0
  82. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/builder/2023.12.txt +0 -0
  83. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/builder/2024.04.txt +0 -0
  84. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/builder/2024.10.txt +0 -0
  85. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/builder/2025.06.txt +0 -0
  86. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/builder/PREVIEW.txt +0 -0
  87. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/builder/README.md +0 -0
  88. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/builder/base-images.json +0 -0
  89. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/call_graph.py +0 -0
  90. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/__init__.py +0 -0
  91. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/_download.py +0 -0
  92. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/_traceback.py +0 -0
  93. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/app.py +0 -0
  94. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/cluster.py +0 -0
  95. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/config.py +0 -0
  96. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/container.py +0 -0
  97. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/dict.py +0 -0
  98. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/entry_point.py +0 -0
  99. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/environment.py +0 -0
  100. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/import_refs.py +0 -0
  101. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/launch.py +0 -0
  102. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/network_file_system.py +0 -0
  103. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/profile.py +0 -0
  104. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/programs/__init__.py +0 -0
  105. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/programs/run_jupyter.py +0 -0
  106. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/programs/vscode.py +0 -0
  107. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/queues.py +0 -0
  108. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/run.py +0 -0
  109. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/secret.py +0 -0
  110. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/shell.py +0 -0
  111. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/utils.py +0 -0
  112. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cli/volume.py +0 -0
  113. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/client.py +0 -0
  114. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cloud_bucket_mount.py +0 -0
  115. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cloud_bucket_mount.pyi +0 -0
  116. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cls.py +0 -0
  117. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/cls.pyi +0 -0
  118. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/config.py +0 -0
  119. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/container_process.py +0 -0
  120. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/container_process.pyi +0 -0
  121. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/dict.py +0 -0
  122. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/dict.pyi +0 -0
  123. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/environments.py +0 -0
  124. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/environments.pyi +0 -0
  125. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/exception.py +0 -0
  126. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/experimental/__init__.py +0 -0
  127. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/experimental/flash.py +0 -0
  128. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/experimental/flash.pyi +0 -0
  129. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/experimental/ipython.py +0 -0
  130. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/file_io.py +0 -0
  131. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/file_io.pyi +0 -0
  132. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/file_pattern_matcher.py +0 -0
  133. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/functions.py +0 -0
  134. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/gpu.py +0 -0
  135. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/image.py +0 -0
  136. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/image.pyi +0 -0
  137. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/io_streams.py +0 -0
  138. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/io_streams.pyi +0 -0
  139. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/mount.py +0 -0
  140. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/mount.pyi +0 -0
  141. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/network_file_system.py +0 -0
  142. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/network_file_system.pyi +0 -0
  143. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/object.py +0 -0
  144. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/object.pyi +0 -0
  145. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/output.py +0 -0
  146. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/parallel_map.py +0 -0
  147. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/parallel_map.pyi +0 -0
  148. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/partial_function.py +0 -0
  149. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/partial_function.pyi +0 -0
  150. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/proxy.py +0 -0
  151. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/proxy.pyi +0 -0
  152. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/py.typed +0 -0
  153. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/queue.py +0 -0
  154. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/queue.pyi +0 -0
  155. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/retries.py +0 -0
  156. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/runner.py +0 -0
  157. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/runner.pyi +0 -0
  158. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/running_app.py +0 -0
  159. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/sandbox.py +0 -0
  160. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/sandbox.pyi +0 -0
  161. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/schedule.py +0 -0
  162. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/scheduler_placement.py +0 -0
  163. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/secret.py +0 -0
  164. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/secret.pyi +0 -0
  165. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/serving.py +0 -0
  166. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/serving.pyi +0 -0
  167. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/snapshot.py +0 -0
  168. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/snapshot.pyi +0 -0
  169. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/stream_type.py +0 -0
  170. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/token_flow.py +0 -0
  171. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/token_flow.pyi +0 -0
  172. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/volume.py +0 -0
  173. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal/volume.pyi +0 -0
  174. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal.egg-info/SOURCES.txt +0 -0
  175. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal.egg-info/dependency_links.txt +0 -0
  176. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal.egg-info/entry_points.txt +0 -0
  177. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal.egg-info/requires.txt +0 -0
  178. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal.egg-info/top_level.txt +0 -0
  179. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_docs/__init__.py +0 -0
  180. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_docs/gen_cli_docs.py +0 -0
  181. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_docs/gen_reference_docs.py +0 -0
  182. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_docs/mdmd/__init__.py +0 -0
  183. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_docs/mdmd/mdmd.py +0 -0
  184. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_docs/mdmd/signatures.py +0 -0
  185. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/__init__.py +0 -0
  186. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/py.typed +0 -0
  187. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/task_command_router.proto +0 -0
  188. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/task_command_router_grpc.py +0 -0
  189. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/task_command_router_pb2.py +0 -0
  190. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/task_command_router_pb2.pyi +0 -0
  191. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  192. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  193. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/modal_version/__main__.py +0 -0
  194. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/pyproject.toml +0 -0
  195. {modal-1.3.1.dev10 → modal-1.3.1.dev12}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.3.1.dev10
3
+ Version: 1.3.1.dev12
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -0,0 +1,108 @@
1
+ # Copyright Modal Labs 2022
2
+ import getpass
3
+ import os
4
+ from datetime import datetime
5
+ from typing import Optional
6
+
7
+ import typer
8
+
9
+ from modal._output import make_console
10
+ from modal._utils.async_utils import synchronizer
11
+ from modal.client import _Client
12
+ from modal.token_flow import _new_token, _set_token
13
+ from modal_proto import api_pb2
14
+
15
+ token_cli = typer.Typer(name="token", help="Manage tokens.", no_args_is_help=True)
16
+
17
+ profile_option = typer.Option(
18
+ None,
19
+ help=(
20
+ "Modal profile to set credentials for. If unspecified "
21
+ "(and MODAL_PROFILE environment variable is not set), "
22
+ "uses the workspace name associated with the credentials."
23
+ ),
24
+ )
25
+ activate_option = typer.Option(
26
+ True,
27
+ help="Activate the profile containing this token after creation.",
28
+ )
29
+
30
+ verify_option = typer.Option(
31
+ True,
32
+ help="Make a test request to verify the new credentials.",
33
+ )
34
+
35
+
36
+ @token_cli.command(name="set")
37
+ @synchronizer.create_blocking
38
+ async def set(
39
+ token_id: Optional[str] = typer.Option(None, help="Account token ID."),
40
+ token_secret: Optional[str] = typer.Option(None, help="Account token secret."),
41
+ profile: Optional[str] = profile_option,
42
+ activate: bool = activate_option,
43
+ verify: bool = verify_option,
44
+ ):
45
+ """Set account credentials for connecting to Modal.
46
+
47
+ If the credentials are not provided on the command line, you will be prompted to enter them.
48
+ """
49
+ if token_id is None:
50
+ token_id = getpass.getpass("Token ID:")
51
+ if token_secret is None:
52
+ token_secret = getpass.getpass("Token secret:")
53
+ await _set_token(token_id, token_secret, profile=profile, activate=activate, verify=verify)
54
+
55
+
56
+ @token_cli.command(name="new")
57
+ @synchronizer.create_blocking
58
+ async def new(
59
+ profile: Optional[str] = profile_option,
60
+ activate: bool = activate_option,
61
+ verify: bool = verify_option,
62
+ source: Optional[str] = None,
63
+ ):
64
+ """Create a new token by using an authenticated web session."""
65
+ await _new_token(profile=profile, activate=activate, verify=verify, source=source)
66
+
67
+
68
+ @token_cli.command(name="info")
69
+ @synchronizer.create_blocking
70
+ async def info():
71
+ """Display information about the token that is currently in use."""
72
+ console = make_console()
73
+
74
+ client = await _Client.from_env()
75
+ req = api_pb2.TokenInfoGetRequest()
76
+ resp = await client.stub.TokenInfoGet(req)
77
+
78
+ env_vars = []
79
+ if os.environ.get("MODAL_TOKEN_ID"):
80
+ env_vars.append("MODAL_TOKEN_ID")
81
+ if os.environ.get("MODAL_TOKEN_SECRET"):
82
+ env_vars.append("MODAL_TOKEN_SECRET")
83
+
84
+ if env_vars:
85
+ env_vars_str = " and ".join(env_vars)
86
+ plural = "s" if len(env_vars) > 1 else ""
87
+ console.print(f"[dim](Using {env_vars_str} environment variable{plural})[/dim]")
88
+
89
+ console.print(f"[bold]Token:[/bold] {resp.token_id}")
90
+ console.print(f"[bold]Workspace:[/bold] {resp.workspace_name} [dim]({resp.workspace_id})[/dim]")
91
+
92
+ if resp.HasField("user_identity"):
93
+ console.print(f"[bold]User:[/bold] {resp.user_identity.username} [dim]({resp.user_identity.user_id})[/dim]")
94
+ elif resp.HasField("service_user_identity"):
95
+ service = resp.service_user_identity
96
+ console.print(f"[bold]Service User:[/bold] {service.service_user_name} [dim]({service.service_user_id})[/dim]")
97
+ if service.HasField("created_by"):
98
+ console.print(
99
+ f"[bold]Created By:[/bold] {service.created_by.username} [dim]({service.created_by.user_id})[/dim]"
100
+ )
101
+
102
+ if resp.HasField("created_at") and resp.created_at.seconds > 0:
103
+ created_dt = datetime.fromtimestamp(resp.created_at.seconds).astimezone()
104
+ console.print(f"[bold]Created at:[/bold] [white]{created_dt.strftime('%Y-%m-%d %H:%M:%S %Z')}[/white]")
105
+
106
+ if resp.HasField("expires_at") and resp.expires_at.seconds > 0:
107
+ expires_dt = datetime.fromtimestamp(resp.expires_at.seconds).astimezone()
108
+ console.print(f"[bold]Expires at:[/bold] [white]{expires_dt.strftime('%Y-%m-%d %H:%M:%S %Z')}[/white]")
@@ -33,7 +33,7 @@ class _Client:
33
33
  server_url: str,
34
34
  client_type: int,
35
35
  credentials: typing.Optional[tuple[str, str]],
36
- version: str = "1.3.1.dev10",
36
+ version: str = "1.3.1.dev12",
37
37
  ):
38
38
  """mdmd:hidden
39
39
  The Modal client object is not intended to be instantiated directly by users.
@@ -163,7 +163,7 @@ class Client:
163
163
  server_url: str,
164
164
  client_type: int,
165
165
  credentials: typing.Optional[tuple[str, str]],
166
- version: str = "1.3.1.dev10",
166
+ version: str = "1.3.1.dev12",
167
167
  ):
168
168
  """mdmd:hidden
169
169
  The Modal client object is not intended to be instantiated directly by users.
@@ -407,7 +407,7 @@ class Function(
407
407
 
408
408
  _call_generator: ___call_generator_spec
409
409
 
410
- class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
410
+ class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
411
411
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
412
412
  """Calls the function remotely, executing it with the given arguments and returning the execution's result."""
413
413
  ...
@@ -416,7 +416,7 @@ class Function(
416
416
  """Calls the function remotely, executing it with the given arguments and returning the execution's result."""
417
417
  ...
418
418
 
419
- remote: __remote_spec[modal._functions.P, modal._functions.ReturnType]
419
+ remote: __remote_spec[modal._functions.ReturnType, modal._functions.P]
420
420
 
421
421
  class __remote_gen_spec(typing_extensions.Protocol):
422
422
  def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
@@ -443,7 +443,7 @@ class Function(
443
443
  """
444
444
  ...
445
445
 
446
- class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
446
+ class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
447
447
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
448
448
  """[Experimental] Calls the function with the given arguments, without waiting for the results.
449
449
 
@@ -466,7 +466,7 @@ class Function(
466
466
  """
467
467
  ...
468
468
 
469
- _experimental_spawn: ___experimental_spawn_spec[modal._functions.P, modal._functions.ReturnType]
469
+ _experimental_spawn: ___experimental_spawn_spec[modal._functions.ReturnType, modal._functions.P]
470
470
 
471
471
  class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
472
472
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
@@ -474,7 +474,7 @@ class Function(
474
474
 
475
475
  _spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
476
476
 
477
- class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
477
+ class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
478
478
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
479
479
  """Calls the function with the given arguments, without waiting for the results.
480
480
 
@@ -495,7 +495,7 @@ class Function(
495
495
  """
496
496
  ...
497
497
 
498
- spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType]
498
+ spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P]
499
499
 
500
500
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
501
501
  """Return the inner Python object wrapped by this Modal Function."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.3.1.dev10
3
+ Version: 1.3.1.dev12
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -2894,6 +2894,7 @@ message SandboxHandleMetadata {
2894
2894
 
2895
2895
  message SandboxInfo {
2896
2896
  string id = 1;
2897
+ reserved 2; // modal.client.Sandbox definition
2897
2898
  double created_at = 3;
2898
2899
  TaskInfo task_info = 4;
2899
2900
  string app_id = 5;
@@ -2902,7 +2903,6 @@ message SandboxInfo {
2902
2903
  string image_id = 8;
2903
2904
  ResourceInfo resource_info = 9;
2904
2905
  repeated string regions = 10;
2905
- reserved 2; // modal.client.Sandbox definition
2906
2906
  }
2907
2907
 
2908
2908
 
@@ -3115,6 +3115,12 @@ message SecretMetadata {
3115
3115
  CreationInfo creation_info = 2;
3116
3116
  }
3117
3117
 
3118
+ message ServiceUserIdentity {
3119
+ string service_user_id = 1;
3120
+ string service_user_name = 2;
3121
+ UserIdentity created_by = 3;
3122
+ }
3123
+
3118
3124
  // SharedVolume in the backend corresponds to NetworkFileSystem in the current API
3119
3125
 
3120
3126
  message SharedVolumeDeleteRequest {
@@ -3336,6 +3342,23 @@ message TokenFlowWaitResponse {
3336
3342
  string workspace_username = 4;
3337
3343
  }
3338
3344
 
3345
+ message TokenInfoGetRequest {}
3346
+
3347
+ message TokenInfoGetResponse {
3348
+ string token_id = 1;
3349
+ string workspace_id = 2;
3350
+ string workspace_name = 3;
3351
+
3352
+ oneof identity {
3353
+ UserIdentity user_identity = 4;
3354
+ ServiceUserIdentity service_user_identity = 5;
3355
+ }
3356
+
3357
+ // Token metadata
3358
+ google.protobuf.Timestamp created_at = 6;
3359
+ google.protobuf.Timestamp expires_at = 7;
3360
+ }
3361
+
3339
3362
  message TunnelData {
3340
3363
  string host = 1;
3341
3364
  uint32 port = 2;
@@ -3375,6 +3398,11 @@ message UserActionInfo {
3375
3398
  double timestamp = 2;
3376
3399
  }
3377
3400
 
3401
+ message UserIdentity {
3402
+ string user_id = 1;
3403
+ string username = 2;
3404
+ }
3405
+
3378
3406
  message VolumeCommitRequest {
3379
3407
  // NOTE(staffan): Mounting a volume in multiple locations is not supported, so volume_id alone uniquely identifies
3380
3408
  // a volume mount.
@@ -3858,6 +3886,7 @@ service ModalClient {
3858
3886
  // Tokens (web auth flow)
3859
3887
  rpc TokenFlowCreate(TokenFlowCreateRequest) returns (TokenFlowCreateResponse);
3860
3888
  rpc TokenFlowWait(TokenFlowWaitRequest) returns (TokenFlowWaitResponse);
3889
+ rpc TokenInfoGet(TokenInfoGetRequest) returns (TokenInfoGetResponse);
3861
3890
 
3862
3891
  // Tunnels
3863
3892
  rpc TunnelStart(TunnelStartRequest) returns (TunnelStartResponse);
@@ -631,6 +631,10 @@ class ModalClientBase(abc.ABC):
631
631
  async def TokenFlowWait(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.TokenFlowWaitRequest, modal_proto.api_pb2.TokenFlowWaitResponse]') -> None:
632
632
  pass
633
633
 
634
+ @abc.abstractmethod
635
+ async def TokenInfoGet(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.TokenInfoGetRequest, modal_proto.api_pb2.TokenInfoGetResponse]') -> None:
636
+ pass
637
+
634
638
  @abc.abstractmethod
635
639
  async def TunnelStart(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.TunnelStartRequest, modal_proto.api_pb2.TunnelStartResponse]') -> None:
636
640
  pass
@@ -1635,6 +1639,12 @@ class ModalClientBase(abc.ABC):
1635
1639
  modal_proto.api_pb2.TokenFlowWaitRequest,
1636
1640
  modal_proto.api_pb2.TokenFlowWaitResponse,
1637
1641
  ),
1642
+ '/modal.client.ModalClient/TokenInfoGet': grpclib.const.Handler(
1643
+ self.TokenInfoGet,
1644
+ grpclib.const.Cardinality.UNARY_UNARY,
1645
+ modal_proto.api_pb2.TokenInfoGetRequest,
1646
+ modal_proto.api_pb2.TokenInfoGetResponse,
1647
+ ),
1638
1648
  '/modal.client.ModalClient/TunnelStart': grpclib.const.Handler(
1639
1649
  self.TunnelStart,
1640
1650
  grpclib.const.Cardinality.UNARY_UNARY,
@@ -2685,6 +2695,12 @@ class ModalClientStub:
2685
2695
  modal_proto.api_pb2.TokenFlowWaitRequest,
2686
2696
  modal_proto.api_pb2.TokenFlowWaitResponse,
2687
2697
  )
2698
+ self.TokenInfoGet = grpclib.client.UnaryUnaryMethod(
2699
+ channel,
2700
+ '/modal.client.ModalClient/TokenInfoGet',
2701
+ modal_proto.api_pb2.TokenInfoGetRequest,
2702
+ modal_proto.api_pb2.TokenInfoGetResponse,
2703
+ )
2688
2704
  self.TunnelStart = grpclib.client.UnaryUnaryMethod(
2689
2705
  channel,
2690
2706
  '/modal.client.ModalClient/TunnelStart',