modal 1.1.2.dev5__py3-none-any.whl → 1.1.2.dev7__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.

Potentially problematic release.


This version of modal might be problematic. Click here for more details.

@@ -300,11 +300,7 @@ class _ContainerIOManager:
300
300
  self.function_def = container_args.function_def
301
301
  self.checkpoint_id = container_args.checkpoint_id or None
302
302
 
303
- # We could also have the worker pass this in explicitly.
304
- self.input_plane_server_url = None
305
- for obj in container_args.app_layout.objects:
306
- if obj.object_id == self.function_id:
307
- self.input_plane_server_url = obj.function_handle_metadata.input_plane_url
303
+ self.input_plane_server_url = container_args.input_plane_server_url
308
304
 
309
305
  self.calls_completed = 0
310
306
  self.total_user_time = 0.0
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.1.2.dev5",
36
+ version: str = "1.1.2.dev7",
37
37
  ):
38
38
  """mdmd:hidden
39
39
  The Modal client object is not intended to be instantiated directly by users.
@@ -164,7 +164,7 @@ class Client:
164
164
  server_url: str,
165
165
  client_type: int,
166
166
  credentials: typing.Optional[tuple[str, str]],
167
- version: str = "1.1.2.dev5",
167
+ version: str = "1.1.2.dev7",
168
168
  ):
169
169
  """mdmd:hidden
170
170
  The Modal client object is not intended to be instantiated directly by users.
modal/functions.pyi CHANGED
@@ -427,7 +427,7 @@ class Function(
427
427
 
428
428
  _call_generator: ___call_generator_spec[typing_extensions.Self]
429
429
 
430
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
430
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
431
431
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
432
432
  """Calls the function remotely, executing it with the given arguments and returning the execution's result."""
433
433
  ...
@@ -436,7 +436,7 @@ class Function(
436
436
  """Calls the function remotely, executing it with the given arguments and returning the execution's result."""
437
437
  ...
438
438
 
439
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
439
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
440
440
 
441
441
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
442
442
  def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
@@ -463,7 +463,7 @@ class Function(
463
463
  """
464
464
  ...
465
465
 
466
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
466
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
467
467
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
468
468
  """[Experimental] Calls the function with the given arguments, without waiting for the results.
469
469
 
@@ -487,7 +487,7 @@ class Function(
487
487
  ...
488
488
 
489
489
  _experimental_spawn: ___experimental_spawn_spec[
490
- modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
490
+ modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
491
491
  ]
492
492
 
493
493
  class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER, SUPERSELF]):
@@ -496,7 +496,7 @@ class Function(
496
496
 
497
497
  _spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P, typing_extensions.Self]
498
498
 
499
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
499
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
500
500
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
501
501
  """Calls the function with the given arguments, without waiting for the results.
502
502
 
@@ -517,7 +517,7 @@ class Function(
517
517
  """
518
518
  ...
519
519
 
520
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
520
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
521
521
 
522
522
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
523
523
  """Return the inner Python object wrapped by this Modal Function."""
modal/parallel_map.py CHANGED
@@ -86,6 +86,180 @@ if typing.TYPE_CHECKING:
86
86
  import modal.functions
87
87
 
88
88
 
89
+ class InputPreprocessor:
90
+ """
91
+ Constructs FunctionPutInputsItem objects from the raw-input queue, and puts them in the processed-input queue.
92
+ """
93
+
94
+ def __init__(
95
+ self,
96
+ client: "modal.client._Client",
97
+ *,
98
+ raw_input_queue: _SynchronizedQueue,
99
+ processed_input_queue: asyncio.Queue,
100
+ function: "modal.functions._Function",
101
+ created_callback: Callable[[int], None],
102
+ done_callback: Callable[[], None],
103
+ ):
104
+ self.client = client
105
+ self.function = function
106
+ self.inputs_created = 0
107
+ self.raw_input_queue = raw_input_queue
108
+ self.processed_input_queue = processed_input_queue
109
+ self.created_callback = created_callback
110
+ self.done_callback = done_callback
111
+
112
+ async def input_iter(self):
113
+ while 1:
114
+ raw_input = await self.raw_input_queue.get()
115
+ if raw_input is None: # end of input sentinel
116
+ break
117
+ yield raw_input # args, kwargs
118
+
119
+ def create_input_factory(self):
120
+ async def create_input(argskwargs):
121
+ idx = self.inputs_created
122
+ self.inputs_created += 1
123
+ self.created_callback(self.inputs_created)
124
+ (args, kwargs) = argskwargs
125
+ return await _create_input(
126
+ args,
127
+ kwargs,
128
+ self.client.stub,
129
+ max_object_size_bytes=self.function._max_object_size_bytes,
130
+ idx=idx,
131
+ method_name=self.function._use_method_name,
132
+ )
133
+
134
+ return create_input
135
+
136
+ async def drain_input_generator(self):
137
+ # Parallelize uploading blobs
138
+ async with aclosing(
139
+ async_map_ordered(self.input_iter(), self.create_input_factory(), concurrency=BLOB_MAX_PARALLELISM)
140
+ ) as streamer:
141
+ async for item in streamer:
142
+ await self.processed_input_queue.put(item)
143
+
144
+ # close queue iterator
145
+ await self.processed_input_queue.put(None)
146
+ self.done_callback()
147
+ yield
148
+
149
+
150
+ class InputPumper:
151
+ """
152
+ Reads inputs from a queue of FunctionPutInputsItems, and sends them to the server.
153
+ """
154
+
155
+ def __init__(
156
+ self,
157
+ client: "modal.client._Client",
158
+ *,
159
+ input_queue: asyncio.Queue,
160
+ function: "modal.functions._Function",
161
+ function_call_id: str,
162
+ map_items_manager: Optional["_MapItemsManager"] = None,
163
+ ):
164
+ self.client = client
165
+ self.function = function
166
+ self.map_items_manager = map_items_manager
167
+ self.input_queue = input_queue
168
+ self.inputs_sent = 0
169
+ self.function_call_id = function_call_id
170
+
171
+ async def pump_inputs(self):
172
+ assert self.client.stub
173
+ async for items in queue_batch_iterator(self.input_queue, max_batch_size=MAP_INVOCATION_CHUNK_SIZE):
174
+ # Add items to the manager. Their state will be SENDING.
175
+ if self.map_items_manager is not None:
176
+ await self.map_items_manager.add_items(items)
177
+ request = api_pb2.FunctionPutInputsRequest(
178
+ function_id=self.function.object_id,
179
+ inputs=items,
180
+ function_call_id=self.function_call_id,
181
+ )
182
+ logger.debug(
183
+ f"Pushing {len(items)} inputs to server. Num queued inputs awaiting"
184
+ f" push is {self.input_queue.qsize()}. "
185
+ )
186
+
187
+ resp = await self._send_inputs(self.client.stub.FunctionPutInputs, request)
188
+ self.inputs_sent += len(items)
189
+ # Change item state to WAITING_FOR_OUTPUT, and set the input_id and input_jwt which are in the response.
190
+ if self.map_items_manager is not None:
191
+ self.map_items_manager.handle_put_inputs_response(resp.inputs)
192
+ logger.debug(
193
+ f"Successfully pushed {len(items)} inputs to server. "
194
+ f"Num queued inputs awaiting push is {self.input_queue.qsize()}."
195
+ )
196
+ yield
197
+
198
+ async def _send_inputs(
199
+ self,
200
+ fn: "modal.client.UnaryUnaryWrapper",
201
+ request: typing.Union[api_pb2.FunctionPutInputsRequest, api_pb2.FunctionRetryInputsRequest],
202
+ ) -> typing.Union[api_pb2.FunctionPutInputsResponse, api_pb2.FunctionRetryInputsResponse]:
203
+ # with 8 retries we log the warning below about every 30 seconds which isn't too spammy.
204
+ retry_warning_message = RetryWarningMessage(
205
+ message=f"Warning: map progress for function {self.function._function_name} is limited."
206
+ " Common bottlenecks include slow iteration over results, or function backlogs.",
207
+ warning_interval=8,
208
+ errors_to_warn_for=[Status.RESOURCE_EXHAUSTED],
209
+ )
210
+ return await retry_transient_errors(
211
+ fn,
212
+ request,
213
+ max_retries=None,
214
+ max_delay=PUMP_INPUTS_MAX_RETRY_DELAY,
215
+ additional_status_codes=[Status.RESOURCE_EXHAUSTED],
216
+ retry_warning_message=retry_warning_message,
217
+ )
218
+
219
+
220
+ class SyncInputPumper(InputPumper):
221
+ def __init__(
222
+ self,
223
+ client: "modal.client._Client",
224
+ *,
225
+ input_queue: asyncio.Queue,
226
+ retry_queue: TimestampPriorityQueue,
227
+ function: "modal.functions._Function",
228
+ function_call_jwt: str,
229
+ function_call_id: str,
230
+ map_items_manager: "_MapItemsManager",
231
+ ):
232
+ super().__init__(
233
+ client,
234
+ input_queue=input_queue,
235
+ function=function,
236
+ function_call_id=function_call_id,
237
+ map_items_manager=map_items_manager,
238
+ )
239
+ self.retry_queue = retry_queue
240
+ self.inputs_retried = 0
241
+ self.function_call_jwt = function_call_jwt
242
+
243
+ async def retry_inputs(self):
244
+ async for retriable_idxs in queue_batch_iterator(self.retry_queue, max_batch_size=MAP_INVOCATION_CHUNK_SIZE):
245
+ # For each index, use the context in the manager to create a FunctionRetryInputsItem.
246
+ # This will also update the context state to RETRYING.
247
+ inputs: list[api_pb2.FunctionRetryInputsItem] = await self.map_items_manager.prepare_items_for_retry(
248
+ retriable_idxs
249
+ )
250
+ request = api_pb2.FunctionRetryInputsRequest(
251
+ function_call_jwt=self.function_call_jwt,
252
+ inputs=inputs,
253
+ )
254
+ resp = await self._send_inputs(self.client.stub.FunctionRetryInputs, request)
255
+ # Update the state to WAITING_FOR_OUTPUT, and update the input_jwt in the context
256
+ # to the new value in the response.
257
+ self.map_items_manager.handle_retry_response(resp.input_jwts)
258
+ logger.debug(f"Successfully pushed retry for {len(inputs)} to server.")
259
+ self.inputs_retried += len(inputs)
260
+ yield
261
+
262
+
89
263
  async def _map_invocation(
90
264
  function: "modal.functions._Function",
91
265
  raw_input_queue: _SynchronizedQueue,
@@ -117,8 +291,6 @@ async def _map_invocation(
117
291
  have_all_inputs = False
118
292
  map_done_event = asyncio.Event()
119
293
  inputs_created = 0
120
- inputs_sent = 0
121
- inputs_retried = 0
122
294
  outputs_completed = 0
123
295
  outputs_received = 0
124
296
  retried_outputs = 0
@@ -135,25 +307,24 @@ async def _map_invocation(
135
307
  retry_policy, function_call_invocation_type, retry_queue, sync_client_retries_enabled, max_inputs_outstanding
136
308
  )
137
309
 
138
- async def create_input(argskwargs):
139
- idx = inputs_created
140
- update_state(set_inputs_created=inputs_created + 1)
141
- (args, kwargs) = argskwargs
142
- return await _create_input(
143
- args,
144
- kwargs,
145
- client.stub,
146
- max_object_size_bytes=function._max_object_size_bytes,
147
- idx=idx,
148
- method_name=function._use_method_name,
149
- )
310
+ input_preprocessor = InputPreprocessor(
311
+ client=client,
312
+ raw_input_queue=raw_input_queue,
313
+ processed_input_queue=input_queue,
314
+ function=function,
315
+ created_callback=lambda x: update_state(set_inputs_created=x),
316
+ done_callback=lambda: update_state(set_have_all_inputs=True),
317
+ )
150
318
 
151
- async def input_iter():
152
- while 1:
153
- raw_input = await raw_input_queue.get()
154
- if raw_input is None: # end of input sentinel
155
- break
156
- yield raw_input # args, kwargs
319
+ input_pumper = SyncInputPumper(
320
+ client=client,
321
+ input_queue=input_queue,
322
+ retry_queue=retry_queue,
323
+ function=function,
324
+ map_items_manager=map_items_manager,
325
+ function_call_jwt=function_call_jwt,
326
+ function_call_id=function_call_id,
327
+ )
157
328
 
158
329
  def update_state(set_have_all_inputs=None, set_inputs_created=None, set_outputs_completed=None):
159
330
  # This should be the only method that needs nonlocal of the following vars
@@ -175,84 +346,6 @@ async def _map_invocation(
175
346
  # map is done
176
347
  map_done_event.set()
177
348
 
178
- async def drain_input_generator():
179
- # Parallelize uploading blobs
180
- async with aclosing(
181
- async_map_ordered(input_iter(), create_input, concurrency=BLOB_MAX_PARALLELISM)
182
- ) as streamer:
183
- async for item in streamer:
184
- await input_queue.put(item)
185
-
186
- # close queue iterator
187
- await input_queue.put(None)
188
- update_state(set_have_all_inputs=True)
189
- yield
190
-
191
- async def pump_inputs():
192
- assert client.stub
193
- nonlocal inputs_sent
194
- async for items in queue_batch_iterator(input_queue, max_batch_size=MAP_INVOCATION_CHUNK_SIZE):
195
- # Add items to the manager. Their state will be SENDING.
196
- await map_items_manager.add_items(items)
197
- request = api_pb2.FunctionPutInputsRequest(
198
- function_id=function.object_id,
199
- inputs=items,
200
- function_call_id=function_call_id,
201
- )
202
- logger.debug(
203
- f"Pushing {len(items)} inputs to server. Num queued inputs awaiting push is {input_queue.qsize()}."
204
- )
205
-
206
- resp = await send_inputs(client.stub.FunctionPutInputs, request)
207
- inputs_sent += len(items)
208
- # Change item state to WAITING_FOR_OUTPUT, and set the input_id and input_jwt which are in the response.
209
- map_items_manager.handle_put_inputs_response(resp.inputs)
210
- logger.debug(
211
- f"Successfully pushed {len(items)} inputs to server. "
212
- f"Num queued inputs awaiting push is {input_queue.qsize()}."
213
- )
214
- yield
215
-
216
- async def retry_inputs():
217
- nonlocal inputs_retried
218
- async for retriable_idxs in queue_batch_iterator(retry_queue, max_batch_size=MAP_INVOCATION_CHUNK_SIZE):
219
- # For each index, use the context in the manager to create a FunctionRetryInputsItem.
220
- # This will also update the context state to RETRYING.
221
- inputs: list[api_pb2.FunctionRetryInputsItem] = await map_items_manager.prepare_items_for_retry(
222
- retriable_idxs
223
- )
224
- request = api_pb2.FunctionRetryInputsRequest(
225
- function_call_jwt=function_call_jwt,
226
- inputs=inputs,
227
- )
228
- resp = await send_inputs(client.stub.FunctionRetryInputs, request)
229
- # Update the state to WAITING_FOR_OUTPUT, and update the input_jwt in the context
230
- # to the new value in the response.
231
- map_items_manager.handle_retry_response(resp.input_jwts)
232
- logger.debug(f"Successfully pushed retry for {len(inputs)} to server.")
233
- inputs_retried += len(inputs)
234
- yield
235
-
236
- async def send_inputs(
237
- fn: "modal.client.UnaryUnaryWrapper",
238
- request: typing.Union[api_pb2.FunctionPutInputsRequest, api_pb2.FunctionRetryInputsRequest],
239
- ) -> typing.Union[api_pb2.FunctionPutInputsResponse, api_pb2.FunctionRetryInputsResponse]:
240
- # with 8 retries we log the warning below about every 30 seconds which isn't too spammy.
241
- retry_warning_message = RetryWarningMessage(
242
- message=f"Warning: map progress for function {function._function_name} is limited."
243
- " Common bottlenecks include slow iteration over results, or function backlogs.",
244
- warning_interval=8,
245
- errors_to_warn_for=[Status.RESOURCE_EXHAUSTED],
246
- )
247
- return await retry_transient_errors(
248
- fn,
249
- request,
250
- max_retries=None,
251
- max_delay=PUMP_INPUTS_MAX_RETRY_DELAY,
252
- additional_status_codes=[Status.RESOURCE_EXHAUSTED],
253
- retry_warning_message=retry_warning_message,
254
- )
255
-
256
349
  async def get_all_outputs():
257
350
  assert client.stub
258
351
  nonlocal \
@@ -395,8 +488,11 @@ async def _map_invocation(
395
488
  def log_stats():
396
489
  logger.debug(
397
490
  f"Map stats: sync_client_retries_enabled={sync_client_retries_enabled} "
398
- f"have_all_inputs={have_all_inputs} inputs_created={inputs_created} input_sent={inputs_sent} "
399
- f"inputs_retried={inputs_retried} outputs_received={outputs_received} "
491
+ f"have_all_inputs={have_all_inputs} "
492
+ f"inputs_created={inputs_created} "
493
+ f"input_sent={input_pumper.inputs_sent} "
494
+ f"inputs_retried={input_pumper.inputs_retried} "
495
+ f"outputs_received={outputs_received} "
400
496
  f"successful_completions={successful_completions} failed_completions={failed_completions} "
401
497
  f"no_context_duplicates={no_context_duplicates} old_retry_duplicates={stale_retry_duplicates} "
402
498
  f"already_complete_duplicates={already_complete_duplicates} "
@@ -415,7 +511,12 @@ async def _map_invocation(
415
511
 
416
512
  log_debug_stats_task = asyncio.create_task(log_debug_stats())
417
513
  async with aclosing(
418
- async_merge(drain_input_generator(), pump_inputs(), poll_outputs(), retry_inputs())
514
+ async_merge(
515
+ input_preprocessor.drain_input_generator(),
516
+ input_pumper.pump_inputs(),
517
+ input_pumper.retry_inputs(),
518
+ poll_outputs(),
519
+ )
419
520
  ) as streamer:
420
521
  async for response in streamer:
421
522
  if response is not None: # type: ignore[unreachable]
modal/parallel_map.pyi CHANGED
@@ -1,5 +1,6 @@
1
1
  import asyncio
2
2
  import asyncio.events
3
+ import asyncio.queues
3
4
  import collections.abc
4
5
  import enum
5
6
  import modal._functions
@@ -60,6 +61,68 @@ class _OutputValue:
60
61
  """Return self==value."""
61
62
  ...
62
63
 
64
+ class InputPreprocessor:
65
+ """Constructs FunctionPutInputsItem objects from the raw-input queue, and puts them in the processed-input queue."""
66
+ def __init__(
67
+ self,
68
+ client: modal.client._Client,
69
+ *,
70
+ raw_input_queue: _SynchronizedQueue,
71
+ processed_input_queue: asyncio.queues.Queue,
72
+ function: modal._functions._Function,
73
+ created_callback: collections.abc.Callable[[int], None],
74
+ done_callback: collections.abc.Callable[[], None],
75
+ ):
76
+ """Initialize self. See help(type(self)) for accurate signature."""
77
+ ...
78
+
79
+ def input_iter(self): ...
80
+ def create_input_factory(self): ...
81
+ def drain_input_generator(self): ...
82
+
83
+ class InputPumper:
84
+ """Reads inputs from a queue of FunctionPutInputsItems, and sends them to the server."""
85
+ def __init__(
86
+ self,
87
+ client: modal.client._Client,
88
+ *,
89
+ input_queue: asyncio.queues.Queue,
90
+ function: modal._functions._Function,
91
+ function_call_id: str,
92
+ map_items_manager: typing.Optional[_MapItemsManager] = None,
93
+ ):
94
+ """Initialize self. See help(type(self)) for accurate signature."""
95
+ ...
96
+
97
+ def pump_inputs(self): ...
98
+ async def _send_inputs(
99
+ self,
100
+ fn: modal.client.UnaryUnaryWrapper,
101
+ request: typing.Union[
102
+ modal_proto.api_pb2.FunctionPutInputsRequest, modal_proto.api_pb2.FunctionRetryInputsRequest
103
+ ],
104
+ ) -> typing.Union[
105
+ modal_proto.api_pb2.FunctionPutInputsResponse, modal_proto.api_pb2.FunctionRetryInputsResponse
106
+ ]: ...
107
+
108
+ class SyncInputPumper(InputPumper):
109
+ """Reads inputs from a queue of FunctionPutInputsItems, and sends them to the server."""
110
+ def __init__(
111
+ self,
112
+ client: modal.client._Client,
113
+ *,
114
+ input_queue: asyncio.queues.Queue,
115
+ retry_queue: modal._utils.async_utils.TimestampPriorityQueue,
116
+ function: modal._functions._Function,
117
+ function_call_jwt: str,
118
+ function_call_id: str,
119
+ map_items_manager: _MapItemsManager,
120
+ ):
121
+ """Initialize self. See help(type(self)) for accurate signature."""
122
+ ...
123
+
124
+ def retry_inputs(self): ...
125
+
63
126
  def _map_invocation(
64
127
  function: modal._functions._Function,
65
128
  raw_input_queue: _SynchronizedQueue,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.1.2.dev5
3
+ Version: 1.1.2.dev7
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=kpq4kXp7pch688y6g55QYAC10wqPTU5FXKoWPMirA3E,47899
22
22
  modal/app.pyi,sha256=-jKXlGDBWRPVsuenBhdMRqawK-L2eiJ7gHbmSblhltg,43525
23
23
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
24
24
  modal/client.py,sha256=kyAIVB3Ay-XKJizQ_1ufUFB__EagV0MLmHJpyYyJ7J0,18636
25
- modal/client.pyi,sha256=Nvs8SDDhrbxNENPrXRovDqf5XATGbiL6XgcYP-sdh2c,15829
25
+ modal/client.pyi,sha256=XkYAet9eGfbO6wW4bcZfOEgO14pM4jUoNrsdUQ9mOFw,15829
26
26
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
27
27
  modal/cloud_bucket_mount.pyi,sha256=-qSfYAQvIoO_l2wsCCGTG5ZUwQieNKXdAO00yP1-LYU,7394
28
28
  modal/cls.py,sha256=7A0xGnugQzm8dOfnKMjLjtqekRlRtQ0jPFRYgq6xdUM,40018
@@ -39,7 +39,7 @@ modal/file_io.py,sha256=BVqAJ0sgPUfN8QsYztWiGB4j56he60TncM02KsylnCw,21449
39
39
  modal/file_io.pyi,sha256=cPT_hsplE5iLCXhYOLn1Sp9eDdk7DxdFmicQHanJZyg,15918
40
40
  modal/file_pattern_matcher.py,sha256=A_Kdkej6q7YQyhM_2-BvpFmPqJ0oHb54B6yf9VqvPVE,8116
41
41
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
42
- modal/functions.pyi,sha256=VYPnfnCLfHRDAl6t5AaVHmZEz0T5f2igjTeMOtHPie8,34766
42
+ modal/functions.pyi,sha256=cS7QYPHcFD_p95hrAU-TWxBIraIzzG-uO9KyPAwfxdw,34766
43
43
  modal/gpu.py,sha256=Fe5ORvVPDIstSq1xjmM6OoNgLYFWvogP9r5BgmD3hYg,6769
44
44
  modal/image.py,sha256=A83nmo0zfCUwgvJh0LZ7Yc1sYvDnZLl_phbKxN-9HIw,103144
45
45
  modal/image.pyi,sha256=oH-GCHVEwD5fOX0K_IaWN5RKZlYwX82z-K4wxx8aN3c,68541
@@ -52,8 +52,8 @@ modal/network_file_system.pyi,sha256=Td_IobHr84iLo_9LZKQ4tNdUB60yjX8QWBaFiUvhfi8
52
52
  modal/object.py,sha256=bTeskuY8JFrESjU4_UL_nTwYlBQdOLmVaOX3X6EMxsg,164
53
53
  modal/object.pyi,sha256=sgbaq_d3QSmnPKg5jRbMG3dOceKs0l54kHUAhAyZKAE,6796
54
54
  modal/output.py,sha256=q4T9uHduunj4NwY-YSwkHGgjZlCXMuJbfQ5UFaAGRAc,1968
55
- modal/parallel_map.py,sha256=qZjvo33YAifqCVGz-d_PCRhA70sAF01EbqxQHBAdVsg,59293
56
- modal/parallel_map.pyi,sha256=T2HsEJVYT0KpDy8kqGz98WgH3HnIqz4kvIhZXs7c3Dw,11724
55
+ modal/parallel_map.py,sha256=Uvc8r9QJbzBlyDc7lhYG4Ul5VPnceGl73Y0CJJfeD54,62556
56
+ modal/parallel_map.pyi,sha256=Z-nIQDFiQMEABr5wNy3HH4K6DIr0LcnxrihF9kqdHa0,13938
57
57
  modal/partial_function.py,sha256=aIdlGfTjjgqY6Fpr-biCjvRU9W542_S5N2xkNN_rYGM,1127
58
58
  modal/partial_function.pyi,sha256=lqqOzZ9-QvHTDWKQ_oAYYOvsXgTOBKhO9u-RI98JbUk,13986
59
59
  modal/proxy.py,sha256=NQJJMGo-D2IfmeU0vb10WWaE4oTLcuf9jTeEJvactOg,1446
@@ -82,7 +82,7 @@ modal/volume.py,sha256=784Wz4XeLYPGWChfpRbukvGK2Ujazf7-lHwDxUNoKfY,45424
82
82
  modal/volume.pyi,sha256=YIzDSxDxy_pNrcWWX0cpAoNkFWwC-kzSnQQAaGeSW0Y,41951
83
83
  modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
84
84
  modal/_runtime/asgi.py,sha256=_2xSTsDD27Cit7xnMs4lzkJA2wzer2_N4Oa3BkXFzVA,22521
85
- modal/_runtime/container_io_manager.py,sha256=hjkK4gke_A8_mULSfm3F1hZKR0C61lKbRUI8mHS-LGE,45464
85
+ modal/_runtime/container_io_manager.py,sha256=ujNpa8bLFM3krzWID8dLDjhEHNcd__Yb3b6XqeDRe8g,45237
86
86
  modal/_runtime/container_io_manager.pyi,sha256=_HvYZzpXX-msFDFuOvk1z6L5DBbv5Dfly16PgYDOojY,23065
87
87
  modal/_runtime/execution_context.py,sha256=73Y5zH_o-MhVCrkJXakYVlFkKqCa2CWvqoHjOfJrJGg,3034
88
88
  modal/_runtime/execution_context.pyi,sha256=IFcW1jphqTchX4fy-45rqfz91RhkZPWtIhIvLvGsNGM,2294
@@ -151,7 +151,7 @@ modal/experimental/__init__.py,sha256=nuc7AL4r_Fs08DD5dciWFZhrV1nanwoClOfdTcudU0
151
151
  modal/experimental/flash.py,sha256=viXQumCIFp5VFsPFURdFTBTjP_QnsAi8nSWXAMmfjeQ,19744
152
152
  modal/experimental/flash.pyi,sha256=A8_qJGtGoXEzKDdHbvhmCw7oqfneFEvJQK3ZdTOvUdU,10830
153
153
  modal/experimental/ipython.py,sha256=TrCfmol9LGsRZMeDoeMPx3Hv3BFqQhYnmD_iH0pqdhk,2904
154
- modal-1.1.2.dev5.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
154
+ modal-1.1.2.dev7.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
155
155
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
156
156
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
157
157
  modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
@@ -174,10 +174,10 @@ modal_proto/options_pb2.pyi,sha256=l7DBrbLO7q3Ir-XDkWsajm0d0TQqqrfuX54i4BMpdQg,1
174
174
  modal_proto/options_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
175
175
  modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0yJSI,247
176
176
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
177
- modal_version/__init__.py,sha256=JTDZv3OoN5NztUcE4VJjLoMa4CV9SjWiQC7feCbOkWU,120
177
+ modal_version/__init__.py,sha256=FBVqTKrDDKpzKSeuzdoOpG8l9rtT4-DQXthg9YcqBS4,120
178
178
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
179
- modal-1.1.2.dev5.dist-info/METADATA,sha256=pEc6L6RUpV7_GsWPbujiVrPePrhWjQtlJKeeYNpb3nk,2459
180
- modal-1.1.2.dev5.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
181
- modal-1.1.2.dev5.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
182
- modal-1.1.2.dev5.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
183
- modal-1.1.2.dev5.dist-info/RECORD,,
179
+ modal-1.1.2.dev7.dist-info/METADATA,sha256=YymEqhZHcg5dEYtMpAzhLjhPWHckBw8bnJM6g5Zo-i4,2459
180
+ modal-1.1.2.dev7.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
181
+ modal-1.1.2.dev7.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
182
+ modal-1.1.2.dev7.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
183
+ modal-1.1.2.dev7.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.1.2.dev5"
4
+ __version__ = "1.1.2.dev7"