modAL 1.3.1.dev11__py3-none-any.whl → 1.3.1.dev13__py3-none-any.whl

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.
@@ -92,8 +92,7 @@ class ConnectionManager:
92
92
 
93
93
  def __init__(self, client: "modal.client._Client", metadata: dict[str, str] = {}):
94
94
  self._client = client
95
- # Warning: This metadata is shared across all channels! If the metadata is mutated
96
- # in one `create_channel` call, the mutation will be reflected in all channels.
95
+ # This metadata is injected into all requests on all channels created by this manager.
97
96
  self._metadata = metadata
98
97
  self._channels: dict[str, grpclib.client.Channel] = {}
99
98
 
@@ -168,8 +167,7 @@ def create_channel(
168
167
  ) -> grpclib.client.Channel:
169
168
  """Creates a grpclib.Channel to be used by a GRPC stub.
170
169
 
171
- Note that this function mutates the given metadata argument by adding an x-modal-auth-token
172
- if one is present in the trailing metadata of any response.
170
+ The given metadata dict is injected into all outgoing requests on this channel.
173
171
  """
174
172
  o = urllib.parse.urlparse(server_url)
175
173
 
modal/cli/token.py CHANGED
@@ -1,11 +1,16 @@
1
1
  # Copyright Modal Labs 2022
2
2
  import getpass
3
+ import os
4
+ from datetime import datetime
3
5
  from typing import Optional
4
6
 
5
7
  import typer
6
8
 
9
+ from modal._output import make_console
7
10
  from modal._utils.async_utils import synchronizer
11
+ from modal.client import _Client
8
12
  from modal.token_flow import _new_token, _set_token
13
+ from modal_proto import api_pb2
9
14
 
10
15
  token_cli = typer.Typer(name="token", help="Manage tokens.", no_args_is_help=True)
11
16
 
@@ -58,3 +63,46 @@ async def new(
58
63
  ):
59
64
  """Create a new token by using an authenticated web session."""
60
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]")
modal/client.pyi CHANGED
@@ -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.dev11",
36
+ version: str = "1.3.1.dev13",
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.dev11",
166
+ version: str = "1.3.1.dev13",
167
167
  ):
168
168
  """mdmd:hidden
169
169
  The Modal client object is not intended to be instantiated directly by users.
modal/functions.pyi CHANGED
@@ -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.dev11
3
+ Version: 1.3.1.dev13
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -26,7 +26,7 @@ modal/app.pyi,sha256=WR0nGSUh8-8OYRHFqEnijGoPp_IbawNY1JW_0pozXsE,50857
26
26
  modal/billing.py,sha256=zmQ3bcCJlwa4KD1IA_QgdWpm1pn13c-7qfy79iEauYI,195
27
27
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
28
28
  modal/client.py,sha256=CXnyJYLhY--xaCkjv3tpjYDca8AuXGQG1IiaXQVX4y4,14436
29
- modal/client.pyi,sha256=XgsrSEoKN9k9dLForI8qW4lsoj_NmpIP8xkeIoK6u6g,14473
29
+ modal/client.pyi,sha256=5ssG4KL7GYM8rhhFnw4Zc2szBF0BHGzNc5DAyjr1GHk,14473
30
30
  modal/cloud_bucket_mount.py,sha256=cvVj5Rt4nDHoQbTneoJPTaAcnl_Ab_mrsjnnzd0v9OI,6013
31
31
  modal/cloud_bucket_mount.pyi,sha256=vXusGMOUk9HjCs4lhxteuCK4xLQclPfugGWKo7LECEA,7539
32
32
  modal/cls.py,sha256=DNXcOrd9l2DoX-nLGdpwXm-N9V0BbQEvWA7d2UwFf44,41510
@@ -43,7 +43,7 @@ modal/file_io.py,sha256=dx90C5L8cQv2Z7pVVPaQmE0R3pUOGv2h-wn1qNNXbGQ,19818
43
43
  modal/file_io.pyi,sha256=up9OhV2Y54n-X7nlfV6j_eBwJ8D2cNMEswZ1iddrEQw,15877
44
44
  modal/file_pattern_matcher.py,sha256=A_Kdkej6q7YQyhM_2-BvpFmPqJ0oHb54B6yf9VqvPVE,8116
45
45
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
46
- modal/functions.pyi,sha256=fDH5yZSKq_uUrcze_zwWWZyxSCeEI1PfGlGOqCutCTY,36465
46
+ modal/functions.pyi,sha256=fkjxeYAqh6sX9C84gjUGoLVgHT1IfNB_07h0fpmIyWw,36465
47
47
  modal/gpu.py,sha256=Fe5ORvVPDIstSq1xjmM6OoNgLYFWvogP9r5BgmD3hYg,6769
48
48
  modal/image.py,sha256=sPaYxx4Dwdod1FjVooDaDDcPbcyyBXY4ChpbQvWe5mc,108197
49
49
  modal/image.pyi,sha256=UMwAaYu4feSDzJS9l-5xKYP_yaJm18bY_s3pREOQF6A,78249
@@ -105,7 +105,7 @@ modal/_utils/docker_utils.py,sha256=h1uETghR40mp_y3fSWuZAfbIASH1HMzuphJHghAL6DU,
105
105
  modal/_utils/function_utils.py,sha256=uoOcn_pyl6fOVHr_Q6ci1_5eJqo90so7G9izfs-T-As,28272
106
106
  modal/_utils/git_utils.py,sha256=qtUU6JAttF55ZxYq51y55OR58B0tDPZsZWK5dJe6W5g,3182
107
107
  modal/_utils/grpc_testing.py,sha256=fZLyfMA5VYmIo-dUCcKQrVCH3ZKPT7K4_6ww373jt0Y,8697
108
- modal/_utils/grpc_utils.py,sha256=8KxNd8M8ziVTc-FB2mkmesBG9hscJScjjL0VIUB4T8k,16270
108
+ modal/_utils/grpc_utils.py,sha256=1imvFLM9jx2QyHGld0exIQL-LxGYNsMwlTZBblqeVPM,16110
109
109
  modal/_utils/hash_utils.py,sha256=zg3J6OGxTFGSFri1qQ12giDz90lWk8bzaxCTUCRtiX4,3034
110
110
  modal/_utils/http_utils.py,sha256=yeTFsXYr0rYMEhB7vBP7audG9Uc7OLhzKBANFDZWVt0,2451
111
111
  modal/_utils/jwt_utils.py,sha256=fxH9plyrbAemTbjSsQtzIdDXE9QXxvMC4DiUZ16G0aA,1360
@@ -148,7 +148,7 @@ modal/cli/queues.py,sha256=S5dqk6lEd_2fJolHqoN9iRs6EkeTa0k7KqJWBBGS23k,6170
148
148
  modal/cli/run.py,sha256=j0NJqxZrfPikpuIjLtQV9dwi2GK3rUHcr6_BJabZXBQ,18728
149
149
  modal/cli/secret.py,sha256=zkCztov8c4x8CI8G0EoyieUfv9XLQQtVXV8xeMLK-Os,8044
150
150
  modal/cli/shell.py,sha256=L5Dw8yeuu9-f6vNlBGbUT4oh9AVSK4GuB5J6m6vYLBk,12613
151
- modal/cli/token.py,sha256=NAmQzKBfEHkcldWKeFxAVIqQBoo1RTp7_A4yc7-8qM0,1911
151
+ modal/cli/token.py,sha256=OiVPDsFo6EpCGVuOOx7Q9WjKxVKIka2gRx_676MaITU,4017
152
152
  modal/cli/utils.py,sha256=d7J4j29b6bsj2GqYe3QdqgHpO-QkxcjtF9YnRCYxVIg,2879
153
153
  modal/cli/volume.py,sha256=8_wjfaFmtcPrIYx46__CbCefaSLPJ14nlm6iCLz_HOA,10512
154
154
  modal/cli/programs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
@@ -158,7 +158,7 @@ modal/experimental/__init__.py,sha256=GOuo3t4-Le0ZVddiHIOw0MQxkdTJge-bVbhDvgnblm
158
158
  modal/experimental/flash.py,sha256=GJZwSr-4OHlP6gCIZdcbsSb8D8WX9xJwMphjwcfsRoU,31262
159
159
  modal/experimental/flash.pyi,sha256=W62a0AhmLUuH9a0n8Y3-DYhyEEFH3-bRUQFphOQfKHg,16418
160
160
  modal/experimental/ipython.py,sha256=TrCfmol9LGsRZMeDoeMPx3Hv3BFqQhYnmD_iH0pqdhk,2904
161
- modal-1.3.1.dev11.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
161
+ modal-1.3.1.dev13.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
162
162
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
163
163
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
164
164
  modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
@@ -180,10 +180,10 @@ modal_proto/task_command_router_pb2.py,sha256=2Y8wRvnq4_7RiQ-5ZAPIgXaxrHv_MXzgS5
180
180
  modal_proto/task_command_router_pb2.pyi,sha256=yI4tFteErLlonFA2HyaWtONfhY_VGSe7KCWFIspvmkE,16323
181
181
  modal_proto/task_command_router_pb2_grpc.py,sha256=q2VWfK2-4uDcPaPLhAqPZkgxhuQRYnWmwUcnEbPbGuk,13895
182
182
  modal_proto/task_command_router_pb2_grpc.pyi,sha256=e1MM10VGUgDkm041v53QeTglGQPzTpA0FUsFtezjp74,4536
183
- modal_version/__init__.py,sha256=EEpH1-wmoyfPL1MIk6sGJz9DSJJ8dfIPYlHNeeldQ3I,121
183
+ modal_version/__init__.py,sha256=Dl28ROslCuzHuMFlFXzOFZ9iwYw18N_YmL4yhk5D2AE,121
184
184
  modal_version/__main__.py,sha256=nLUbubxKx7GXNzJIkTB7M7_u8080LyLM0IS0rzFkC_c,119
185
- modal-1.3.1.dev11.dist-info/METADATA,sha256=ZS4XguX9swoczT7JQkl_QMsEES8k3R6rkjqjom2OPKw,2582
186
- modal-1.3.1.dev11.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
187
- modal-1.3.1.dev11.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
188
- modal-1.3.1.dev11.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
189
- modal-1.3.1.dev11.dist-info/RECORD,,
185
+ modal-1.3.1.dev13.dist-info/METADATA,sha256=e55HDpOz2TBik7zExJDz_RA0eqPlhlepSUKTrTQmTSE,2582
186
+ modal-1.3.1.dev13.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
187
+ modal-1.3.1.dev13.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
188
+ modal-1.3.1.dev13.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
189
+ modal-1.3.1.dev13.dist-info/RECORD,,
modal_version/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2025
2
2
  """Supplies the current version of the modal client library."""
3
3
 
4
- __version__ = "1.3.1.dev11"
4
+ __version__ = "1.3.1.dev13"