modal 0.73.100__py3-none-any.whl → 0.73.102__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.
@@ -207,6 +207,7 @@ class FunctionInfo:
207
207
  if serialized: # if explicit
208
208
  self._type = FunctionInfoType.SERIALIZED
209
209
  else:
210
+ # notebook, or in general any exec() on a function definition
210
211
  self._type = FunctionInfoType.NOTEBOOK
211
212
 
212
213
  if not self.is_serialized():
modal/cli/import_refs.py CHANGED
@@ -12,7 +12,7 @@ import importlib
12
12
  import importlib.util
13
13
  import inspect
14
14
  import sys
15
- import types
15
+ import typing
16
16
  from collections import defaultdict
17
17
  from dataclasses import dataclass
18
18
  from pathlib import Path
@@ -130,7 +130,7 @@ class AutoRunPriority:
130
130
 
131
131
 
132
132
  def list_cli_commands(
133
- module: types.ModuleType,
133
+ module_members: dict[str, typing.Any],
134
134
  ) -> list[CLICommand]:
135
135
  """
136
136
  Extracts all runnables found either directly in the input module, or in any of the Apps listed in that module
@@ -142,7 +142,9 @@ def list_cli_commands(
142
142
 
143
143
  Where the first name is always the module level name if such a name exists
144
144
  """
145
- apps = cast(list[tuple[str, App]], inspect.getmembers(module, lambda x: isinstance(x, App)))
145
+ apps = cast(
146
+ list[tuple[str, App]], [(name, member) for name, member in module_members.items() if isinstance(member, App)]
147
+ )
146
148
 
147
149
  all_runnables: dict[Runnable, list[str]] = defaultdict(list)
148
150
  priorities: dict[Runnable, int] = defaultdict(lambda: AutoRunPriority.APP_FUNCTION)
@@ -163,10 +165,11 @@ def list_cli_commands(
163
165
 
164
166
  # If any class or function is exported as a module level object, use that
165
167
  # as the preferred name by putting it first in the list
166
- module_level_entities = cast(
167
- list[tuple[str, Runnable]],
168
- inspect.getmembers(module, lambda x: isinstance(x, (Function, Cls, LocalEntrypoint))),
169
- )
168
+ module_level_entities = [
169
+ (name, member)
170
+ for name, member in module_members.items()
171
+ if isinstance(member, (Function, Cls, LocalEntrypoint))
172
+ ]
170
173
  for name, entity in module_level_entities:
171
174
  if isinstance(entity, Cls) and entity._is_local():
172
175
  for method_name in entity._get_method_names():
@@ -335,25 +338,35 @@ def import_and_filter(
335
338
  """
336
339
  # all commands:
337
340
  module = import_file_or_module(import_ref, base_cmd)
338
- cli_commands = list_cli_commands(module)
341
+ cli_commands = list_cli_commands(dict(inspect.getmembers(module)))
339
342
 
340
343
  # all commands that satisfy local entrypoint/accept webhook limitations AND object path prefix
341
- filtered_commands = filter_cli_commands(
342
- cli_commands, import_ref.object_path, accept_local_entrypoint, accept_webhook
343
- )
344
344
 
345
345
  all_usable_commands = filter_cli_commands(cli_commands, "", accept_local_entrypoint, accept_webhook)
346
+ inferred_runnable = infer_runnable(cli_commands, import_ref.object_path, accept_local_entrypoint, accept_webhook)
346
347
 
347
- if filtered_commands:
348
+ if inferred_runnable:
348
349
  # if there is a single command with "highest run prio" - use that
349
- filtered_commands_by_prio = defaultdict(list)
350
- for cmd in filtered_commands:
351
- filtered_commands_by_prio[cmd.priority].append(cmd)
352
-
353
- _, highest_prio_commands = min(filtered_commands_by_prio.items())
354
- if len(highest_prio_commands) == 1:
355
- cli_command = highest_prio_commands[0]
356
- return cli_command.runnable, all_usable_commands
350
+ return inferred_runnable, all_usable_commands
357
351
 
358
352
  # otherwise, just return the list of all commands
359
353
  return None, all_usable_commands
354
+
355
+
356
+ def infer_runnable(
357
+ cli_commands: list[CLICommand], object_path: str, accept_local_entrypoint: bool, accept_webhook: bool
358
+ ) -> Optional[Runnable]:
359
+ filtered_commands = filter_cli_commands(cli_commands, object_path, accept_local_entrypoint, accept_webhook)
360
+ if len(filtered_commands) == 0:
361
+ return None
362
+
363
+ filtered_commands_by_prio = defaultdict(list)
364
+ for cmd in filtered_commands:
365
+ filtered_commands_by_prio[cmd.priority].append(cmd)
366
+
367
+ _, highest_prio_commands = min(filtered_commands_by_prio.items())
368
+ if len(highest_prio_commands) == 1:
369
+ cli_command = highest_prio_commands[0]
370
+ return cli_command.runnable
371
+
372
+ return None
modal/client.pyi CHANGED
@@ -31,7 +31,7 @@ class _Client:
31
31
  server_url: str,
32
32
  client_type: int,
33
33
  credentials: typing.Optional[tuple[str, str]],
34
- version: str = "0.73.100",
34
+ version: str = "0.73.102",
35
35
  ): ...
36
36
  def is_closed(self) -> bool: ...
37
37
  @property
@@ -93,7 +93,7 @@ class Client:
93
93
  server_url: str,
94
94
  client_type: int,
95
95
  credentials: typing.Optional[tuple[str, str]],
96
- version: str = "0.73.100",
96
+ version: str = "0.73.102",
97
97
  ): ...
98
98
  def is_closed(self) -> bool: ...
99
99
  @property
modal/functions.pyi CHANGED
@@ -198,11 +198,11 @@ class Function(
198
198
 
199
199
  _call_generator_nowait: ___call_generator_nowait_spec[typing_extensions.Self]
200
200
 
201
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
201
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
202
202
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
203
203
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
204
204
 
205
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
205
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
206
206
 
207
207
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
208
208
  def __call__(self, *args, **kwargs) -> typing.Generator[typing.Any, None, None]: ...
@@ -217,19 +217,19 @@ class Function(
217
217
  self, *args: modal._functions.P.args, **kwargs: modal._functions.P.kwargs
218
218
  ) -> modal._functions.OriginalReturnType: ...
219
219
 
220
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
220
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
221
221
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
222
222
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
223
223
 
224
224
  _experimental_spawn: ___experimental_spawn_spec[
225
- modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
225
+ modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
226
226
  ]
227
227
 
228
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
228
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
229
229
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
230
230
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
231
231
 
232
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
232
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
233
233
 
234
234
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]: ...
235
235
 
modal/io_streams.py CHANGED
@@ -70,14 +70,14 @@ class _StreamReader(Generic[T]):
70
70
 
71
71
  **Usage**
72
72
 
73
- ```python
73
+ ```python fixture:running_app
74
74
  from modal import Sandbox
75
75
 
76
76
  sandbox = Sandbox.create(
77
77
  "bash",
78
78
  "-c",
79
79
  "for i in $(seq 1 10); do echo foo; sleep 0.1; done",
80
- app=app,
80
+ app=running_app,
81
81
  )
82
82
  for message in sandbox.stdout:
83
83
  print(f"Message: {message}")
@@ -147,10 +147,10 @@ class _StreamReader(Generic[T]):
147
147
 
148
148
  **Usage**
149
149
 
150
- ```python
150
+ ```python fixture:running_app
151
151
  from modal import Sandbox
152
152
 
153
- sandbox = Sandbox.create("echo", "hello", app=app)
153
+ sandbox = Sandbox.create("echo", "hello", app=running_app)
154
154
  sandbox.wait()
155
155
 
156
156
  print(sandbox.stdout.read())
@@ -347,14 +347,14 @@ class _StreamWriter:
347
347
 
348
348
  **Usage**
349
349
 
350
- ```python
350
+ ```python fixture:running_app
351
351
  from modal import Sandbox
352
352
 
353
353
  sandbox = Sandbox.create(
354
354
  "bash",
355
355
  "-c",
356
356
  "while read line; do echo $line; done",
357
- app=app,
357
+ app=running_app,
358
358
  )
359
359
  sandbox.stdin.write(b"foo\\n")
360
360
  sandbox.stdin.write(b"bar\\n")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: modal
3
- Version: 0.73.100
3
+ Version: 0.73.102
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -22,7 +22,7 @@ modal/app.py,sha256=ojhuLZuNZAQ1OsbDH0k6G4pm1W7bOIvZfXbaKlvQ-Ao,45622
22
22
  modal/app.pyi,sha256=tZFbcsu20SuvfB2puxCyuXLFNJ9bQulzag55rVpgZmc,26827
23
23
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
24
24
  modal/client.py,sha256=j9D3hNis1lfhnz9lVFGgJgowbH3PaGUzNKgHPWYG778,15372
25
- modal/client.pyi,sha256=FEU84jA8vf8eCZgXVpJEWv6TL8ezLrhOqptR10cRRME,7661
25
+ modal/client.pyi,sha256=zUHwpjWRBiFlOyWRnztgyJKHBGc0W6a9a7hEtP9KAdo,7661
26
26
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
27
27
  modal/cloud_bucket_mount.pyi,sha256=30T3K1a89l6wzmEJ_J9iWv9SknoGqaZDx59Xs-ZQcmk,1607
28
28
  modal/cls.py,sha256=JhDbaZZHN52lqA_roY1BCbcN9BvbkUcdXiM2Kg9lIc0,31717
@@ -41,11 +41,11 @@ modal/file_io.py,sha256=lcMs_E9Xfm0YX1t9U2wNIBPnqHRxmImqjLW1GHqVmyg,20945
41
41
  modal/file_io.pyi,sha256=NTRft1tbPSWf9TlWVeZmTlgB5AZ_Zhu2srWIrWr7brk,9445
42
42
  modal/file_pattern_matcher.py,sha256=trosX-Bp7dOubudN1bLLhRAoidWy1TcoaR4Pv8CedWw,6497
43
43
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
44
- modal/functions.pyi,sha256=D-PDJfSbwqMDXdq7Bxu2ErZRENo-tRgu_zPoB-jl0OU,14377
44
+ modal/functions.pyi,sha256=ujc6eIYyNmMn__4dpxEy85-vZmAniZv56D2A4uBgs6U,14377
45
45
  modal/gpu.py,sha256=Kbhs_u49FaC2Zi0TjCdrpstpRtT5eZgecynmQi5IZVE,6752
46
46
  modal/image.py,sha256=fWamISDhtUo-DRtIn9c8aevNE78HafOlG9Rn-otUZv8,90800
47
47
  modal/image.pyi,sha256=Im_ap8E2oxDXA6uHQExKtH0KlB17gg6dfgAaJwW38ts,25163
48
- modal/io_streams.py,sha256=QkQiizKRzd5bnbKQsap31LJgBYlAnj4-XkV_50xPYX0,15079
48
+ modal/io_streams.py,sha256=h5O2LmbRoT9l777z3TQhCAm-JF1r7avZ2ykXlejztDs,15163
49
49
  modal/io_streams.pyi,sha256=bJ7ZLmSmJ0nKoa6r4FJpbqvzdUVa0lEe0Fa-MMpMezU,5071
50
50
  modal/mount.py,sha256=JII0zTS1fPCcCbZgO18okkOuTDqYCxY1DIVa6i1E9cI,32196
51
51
  modal/mount.pyi,sha256=CmHa7zKSxHA_7-vMQLnGfw_ZXvAvHlafvUEVJcQ1LQA,12535
@@ -98,7 +98,7 @@ modal/_utils/blob_utils.py,sha256=RB1G6T7eC1Poe-O45qYLaxwCr2jkM-Q6Nexk1J3wk_w,14
98
98
  modal/_utils/bytes_io_segment_payload.py,sha256=uunxVJS4PE1LojF_UpURMzVK9GuvmYWRqQo_bxEj5TU,3385
99
99
  modal/_utils/deprecation.py,sha256=EXP1beU4pmEqEzWMLw6E3kUfNfpmNA_VOp6i0EHi93g,4856
100
100
  modal/_utils/docker_utils.py,sha256=h1uETghR40mp_y3fSWuZAfbIASH1HMzuphJHghAL6DU,3722
101
- modal/_utils/function_utils.py,sha256=Rmz8GJDie-RW_q2RcTwholEWixS2IQDPBsRBJ3f3ZvU,27302
101
+ modal/_utils/function_utils.py,sha256=OqsmLKOqSenxkXiNSPUWpKqD5KotySa_Omw1tmt97K0,27380
102
102
  modal/_utils/grpc_testing.py,sha256=H1zHqthv19eGPJz2HKXDyWXWGSqO4BRsxah3L5Xaa8A,8619
103
103
  modal/_utils/grpc_utils.py,sha256=wmMydVKN9YbugTwUXuOuzxbpzYvxkTDaFRxlBtIDE_0,8526
104
104
  modal/_utils/hash_utils.py,sha256=zg3J6OGxTFGSFri1qQ12giDz90lWk8bzaxCTUCRtiX4,3034
@@ -123,7 +123,7 @@ modal/cli/container.py,sha256=FYwEgjf93j4NMorAjGbSV98i1wpebqdAeNU1wfrFp1k,3668
123
123
  modal/cli/dict.py,sha256=8Wq3w-UDaywk8EVNdj-ECCNV9TYHqh4kzhUqhhulatM,4593
124
124
  modal/cli/entry_point.py,sha256=dOosuCwhfznwTCB4oMljUFhihq5aLUVoAz7RhcBEDnc,4189
125
125
  modal/cli/environment.py,sha256=Ayddkiq9jdj3XYDJ8ZmUqFpPPH8xajYlbexRkzGtUcg,4334
126
- modal/cli/import_refs.py,sha256=kbjWZxSyLc6Bp6UxtB7iJ7qp10DG5j7i4bbbA1bSIXQ,13529
126
+ modal/cli/import_refs.py,sha256=53WmXyOivTk2Pi85NgAr8K5tjwOxNeCmOR0wLNEEX1c,13941
127
127
  modal/cli/launch.py,sha256=0_sBu6bv2xJEPWi-rbGS6Ri9ggnkWQvrGlgpYSUBMyY,3097
128
128
  modal/cli/network_file_system.py,sha256=eq3JnwjbfFNsJodIyANHL06ByYc3BSavzdmu8C96cHA,7948
129
129
  modal/cli/profile.py,sha256=0TYhgRSGUvQZ5LH9nkl6iZllEvAjDniES264dE57wOM,3201
@@ -152,10 +152,10 @@ modal_docs/mdmd/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,2
152
152
  modal_docs/mdmd/mdmd.py,sha256=Irx49MCCTlBOP4FBdLR--JrpA3-WhsVeriq0LGgsRic,6232
153
153
  modal_docs/mdmd/signatures.py,sha256=XJaZrK7Mdepk5fdX51A8uENiLFNil85Ud0d4MH8H5f0,3218
154
154
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
155
- modal_proto/api.proto,sha256=2ZqCWqGd3uou1gB-3BaeHH4ifUc2tGqfuECK5xZ66qs,87119
155
+ modal_proto/api.proto,sha256=S8AuRY85IXHsK7zjGz9rpLrM58wvsndiKTg6mB869_0,87199
156
156
  modal_proto/api_grpc.py,sha256=FYGqDegM_w_qxdtlxum8k31mDibKoMvmNxv_p9cKdKs,109056
157
- modal_proto/api_pb2.py,sha256=_B9huqNJ0UIPxXLZAI951Wm0ZuMuSto08Ohk2jElhbk,312674
158
- modal_proto/api_pb2.pyi,sha256=eBbPOUnaWFd4at5uw4UlBkyFl0H6m2NQNSxYwajIo_Y,422034
157
+ modal_proto/api_pb2.py,sha256=sObPf-wW6CJMyxRKQYvOY3NCZY8vwnA_1PNYLw_5CRY,312842
158
+ modal_proto/api_pb2.pyi,sha256=fONlrXklOTc3tqZ_rdZi5onnUPMBBvgbouW6OcWiJ5M,422539
159
159
  modal_proto/api_pb2_grpc.py,sha256=DNp0Et5i_Ey4dKx_1o1LRtYhyWYyT0NzTcAY4EcHn-c,235765
160
160
  modal_proto/api_pb2_grpc.pyi,sha256=RI6tWC3L8EIN4-izFSEGPPJl5Ta0lXPNuHUJaWAr35s,54892
161
161
  modal_proto/modal_api_grpc.py,sha256=UG8WJU81afrWPwItWB4Ag64E9EpyREMpBbAVGVEYJiM,14550
@@ -169,10 +169,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
169
169
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
170
170
  modal_version/__init__.py,sha256=wiJQ53c-OMs0Xf1UeXOxQ7FwlV1VzIjnX6o-pRYZ_Pk,470
171
171
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
172
- modal_version/_version_generated.py,sha256=jrj-io9Vvj9b8ayvjvkQBghmhFcoL3PoPvuHrMVsV7s,150
173
- modal-0.73.100.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
174
- modal-0.73.100.dist-info/METADATA,sha256=T5xt-lKTVec2t_gdZp-YQOK642mod1EK32esilLdAJk,2453
175
- modal-0.73.100.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
176
- modal-0.73.100.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
177
- modal-0.73.100.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
178
- modal-0.73.100.dist-info/RECORD,,
172
+ modal_version/_version_generated.py,sha256=oH3omNi-OAM0rjMoM0SWBophXz8Tb0WoBdvKLHIz5qk,150
173
+ modal-0.73.102.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
174
+ modal-0.73.102.dist-info/METADATA,sha256=Ndz6dLmlGqDk8oLm9XE_p7esv3KrT8dRcBeY729tvFg,2453
175
+ modal-0.73.102.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
176
+ modal-0.73.102.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
177
+ modal-0.73.102.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
178
+ modal-0.73.102.dist-info/RECORD,,
modal_proto/api.proto CHANGED
@@ -171,6 +171,7 @@ enum ParameterType {
171
171
  PARAM_TYPE_STRING = 1;
172
172
  PARAM_TYPE_INT = 2;
173
173
  PARAM_TYPE_PICKLE = 3;
174
+ PARAM_TYPE_BYTES = 4;
174
175
  }
175
176
 
176
177
  enum ProgressType {
@@ -701,6 +702,7 @@ message ClassParameterSpec {
701
702
  string string_default = 4;
702
703
  int64 int_default = 5;
703
704
  bytes pickle_default = 6;
705
+ bytes bytes_default = 7;
704
706
  }
705
707
  }
706
708
 
@@ -714,6 +716,7 @@ message ClassParameterValue {
714
716
  string string_value = 3;
715
717
  int64 int_value = 4;
716
718
  bytes pickle_value = 5;
719
+ bytes bytes_value = 6;
717
720
  }
718
721
  }
719
722