modal 0.73.167__py3-none-any.whl → 0.73.169__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.
@@ -33,7 +33,6 @@ from modal._partial_function import (
33
33
  _find_callables_for_obj,
34
34
  _PartialFunctionFlags,
35
35
  )
36
- from modal._proxy_tunnel import proxy_tunnel
37
36
  from modal._serialization import deserialize_params
38
37
  from modal._utils.async_utils import TaskContext, synchronizer
39
38
  from modal._utils.function_utils import (
@@ -586,11 +585,9 @@ if __name__ == "__main__":
586
585
  client = Client.from_env()
587
586
 
588
587
  try:
589
- with proxy_tunnel(container_args.proxy_info):
590
- try:
591
- main(container_args, client)
592
- except UserException:
593
- logger.info("User exception caught, exiting")
588
+ main(container_args, client)
589
+ except UserException:
590
+ logger.info("User exception caught, exiting")
594
591
  except KeyboardInterrupt:
595
592
  logger.debug("Container: interrupted")
596
593
 
modal/_functions.py CHANGED
@@ -530,12 +530,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
530
530
  if is_generator:
531
531
  raise InvalidError("Generator functions do not support retries.")
532
532
 
533
- if proxy:
534
- # HACK: remove this once we stop using ssh tunnels for this.
535
- if image:
536
- # TODO(elias): this will cause an error if users use prior `.add_local_*` commands without copy=True
537
- image = image.apt_install("autossh")
538
-
539
533
  function_spec = _FunctionSpec(
540
534
  mounts=all_mounts,
541
535
  secrets=secrets,
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.167",
34
+ version: str = "0.73.169",
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.167",
96
+ version: str = "0.73.169",
97
97
  ): ...
98
98
  def is_closed(self) -> bool: ...
99
99
  @property
modal/parallel_map.py CHANGED
@@ -41,7 +41,8 @@ if typing.TYPE_CHECKING:
41
41
  # pump_inputs should retry if it receives any of the standard retryable codes plus RESOURCE_EXHAUSTED.
42
42
  PUMP_INPUTS_RETRYABLE_GRPC_STATUS_CODES = RETRYABLE_GRPC_STATUS_CODES + [Status.RESOURCE_EXHAUSTED]
43
43
  PUMP_INPUTS_MAX_RETRIES = 8
44
- PUMP_INPUTS_MAX_RETRY_DELAY=15
44
+ PUMP_INPUTS_MAX_RETRY_DELAY = 15
45
+
45
46
 
46
47
  class _SynchronizedQueue:
47
48
  """mdmd:hidden"""
@@ -357,6 +358,7 @@ async def _map_invocation(
357
358
  f"retried_outputs={retried_outputs} input_queue_size={input_queue.qsize()} "
358
359
  f"retry_queue_size={retry_queue.qsize()} map_items_manager={len(map_items_manager)}"
359
360
  )
361
+
360
362
  while True:
361
363
  log_stats()
362
364
  try:
@@ -401,7 +403,7 @@ def _map_sync(
401
403
  assert list(my_func.map([1, 2, 3, 4])) == [1, 4, 9, 16]
402
404
  ```
403
405
 
404
- If applied to a `stub.function`, `map()` returns one result per input and the output order
406
+ If applied to a `app.function`, `map()` returns one result per input and the output order
405
407
  is guaranteed to be the same as the input order. Set `order_outputs=False` to return results
406
408
  in the order that they are completed instead.
407
409
 
@@ -570,6 +572,7 @@ class _MapItemState(enum.Enum):
570
572
  # The output has been received and was either successful, or failed with no more retries remaining.
571
573
  COMPLETE = 5
572
574
 
575
+
573
576
  class _OutputType(enum.Enum):
574
577
  SUCCESSFUL_COMPLETION = 1
575
578
  FAILED_COMPLETION = 2
@@ -578,11 +581,12 @@ class _OutputType(enum.Enum):
578
581
  STALE_RETRY_DUPLICATE = 5
579
582
  NO_CONTEXT_DUPLICATE = 6
580
583
 
584
+
581
585
  class _MapItemContext:
582
586
  state: _MapItemState
583
587
  input: api_pb2.FunctionInput
584
588
  retry_manager: RetryManager
585
- sync_client_retries_enabled:bool
589
+ sync_client_retries_enabled: bool
586
590
  # Both these futures are strings. Omitting generic type because
587
591
  # it causes an error when running `inv protoc type-stubs`.
588
592
  input_id: asyncio.Future
@@ -701,8 +705,7 @@ class _MapItemsManager:
701
705
  function_call_invocation_type: "api_pb2.FunctionCallInvocationType.ValueType",
702
706
  retry_queue: TimestampPriorityQueue,
703
707
  sync_client_retries_enabled: bool,
704
- max_inputs_outstanding: int
705
-
708
+ max_inputs_outstanding: int,
706
709
  ):
707
710
  self._retry_policy = retry_policy
708
711
  self.function_call_invocation_type = function_call_invocation_type
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 0.73.167
3
+ Version: 0.73.169
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -2,14 +2,13 @@ modal/__init__.py,sha256=7wz1AT_bpWJJEzXsAo3QMb7i87y7UGXwfneb0bGDhRg,2502
2
2
  modal/__main__.py,sha256=CgIjP8m1xJjjd4AXc-delmR6LdBCZclw2A_V38CFIio,2870
3
3
  modal/_clustered_functions.py,sha256=kTf-9YBXY88NutC1akI-gCbvf01RhMPCw-zoOI_YIUE,2700
4
4
  modal/_clustered_functions.pyi,sha256=vllkegc99A0jrUOWa8mdlSbdp6uz36TsHhGxysAOpaQ,771
5
- modal/_container_entrypoint.py,sha256=85KptUAmlftjHR-mpl32H5deATqqDrRWp0Z1XrKmWyk,29166
6
- modal/_functions.py,sha256=M94gzMA9xfW9086djoG2yYFVihcslKnsleacmNbVrG0,74996
5
+ modal/_container_entrypoint.py,sha256=PVs5WDgm0_vZlECf_Ga58L49zceTMKPlUA10YRpPmy8,29026
6
+ modal/_functions.py,sha256=EoJ2IbApVoJYELjB0KvXwRV2J6jElhwGHzTbXbXef6A,74712
7
7
  modal/_ipython.py,sha256=TW1fkVOmZL3YYqdS2YlM1hqpf654Yf8ZyybHdBnlhSw,301
8
8
  modal/_location.py,sha256=joiX-0ZeutEUDTrrqLF1GHXCdVLF-rHzstocbMcd_-k,366
9
9
  modal/_object.py,sha256=JBIECWdfpRKCaCxVWZbC3Q1kF5Whk_EKvY9f4Y6AFyg,11446
10
10
  modal/_output.py,sha256=Z0nngPh2mKHMQc4MQ92YjVPc3ewOLa3I4dFBlL9nvQY,25656
11
11
  modal/_partial_function.py,sha256=8mmd5lvjZaC7qi0KAnLR1H590MlxNslAE2_Kr9biJUA,39704
12
- modal/_proxy_tunnel.py,sha256=gnKyCfmVB7x2d1A6c-JDysNIP3kEFxmXzhcXhPrzPn0,1906
13
12
  modal/_pty.py,sha256=JZfPDDpzqICZqtyPI_oMJf_9w-p_lLNuzHhwhodUXio,1329
14
13
  modal/_resolver.py,sha256=RtoXoYzSllPlFu0D1vel_FWiEmDO7RyToiC2bxeN8ZY,6917
15
14
  modal/_resources.py,sha256=5qmcirXUI8dSH926nwkUaeX9H25mqYu9mXD_KuT79-o,1733
@@ -23,7 +22,7 @@ modal/app.py,sha256=bJp7W3liuVG2VwWkG31tMFogDh84EKppzP8YJFWl3eQ,48140
23
22
  modal/app.pyi,sha256=SkqXNrdnGIZ4MmNNvpGtzNLoUdyuvi9IjQQR_DRiRHk,26968
24
23
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
25
24
  modal/client.py,sha256=U-YKSw0n7J1ZLREt9cbEJCtmHe5YoPKFxl0xlkan2yc,15565
26
- modal/client.pyi,sha256=AGcVcEelqx_X_Jfb4xfzqsQLTEdabMRN3AWICFkwqc8,7661
25
+ modal/client.pyi,sha256=OPhN2duy3E59Cd0XH_KxhMf2Asehk37vBruSo_mJEZ8,7661
27
26
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
28
27
  modal/cloud_bucket_mount.pyi,sha256=30T3K1a89l6wzmEJ_J9iWv9SknoGqaZDx59Xs-ZQcmk,1607
29
28
  modal/cls.py,sha256=x3CUDPC-QK7pa9E2eiFsiCS2ULvVi8UzNZQw1i9drsU,32945
@@ -53,7 +52,7 @@ modal/network_file_system.pyi,sha256=4N3eqMbTSlqmS8VV_aJK-uvrgJC8xnf_YtW5FHfRfc8
53
52
  modal/object.py,sha256=bTeskuY8JFrESjU4_UL_nTwYlBQdOLmVaOX3X6EMxsg,164
54
53
  modal/object.pyi,sha256=kyJkRQcVv3ct7zSAxvvXcuhBVeH914v80uSlqeS7cA4,5632
55
54
  modal/output.py,sha256=q4T9uHduunj4NwY-YSwkHGgjZlCXMuJbfQ5UFaAGRAc,1968
56
- modal/parallel_map.py,sha256=p9dklKZTxYCFb7szYWqTGjPZ-Yikvm6OFhU3JNoiTB4,33850
55
+ modal/parallel_map.py,sha256=NN48Xg_qzbL4lbw781-t1HDV19w8lib8-9HofoAKxh4,33856
57
56
  modal/parallel_map.pyi,sha256=mEenHruPiZDq3ucV_6RM8ctc0c_Qpqra5MBagXeHiiQ,5708
58
57
  modal/partial_function.py,sha256=SwuAAj2wj4SO6F6nkSnwNZrczEmm9w9YdlQTHh6hr04,1195
59
58
  modal/partial_function.pyi,sha256=NFWz1aCAs2B3-GnPf1cTatWRZOLnYpFKCnjP_X9iNRs,6411
@@ -146,7 +145,7 @@ modal/requirements/2024.10.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddR
146
145
  modal/requirements/PREVIEW.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddRo,296
147
146
  modal/requirements/README.md,sha256=9tK76KP0Uph7O0M5oUgsSwEZDj5y-dcUPsnpR0Sc-Ik,854
148
147
  modal/requirements/base-images.json,sha256=57vMSqzMbLBxw5tFWSaMiIkkVEps4JfX5PAtXGnkS4U,740
149
- modal-0.73.167.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
148
+ modal-0.73.169.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
150
149
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
151
150
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
152
151
  modal_docs/gen_reference_docs.py,sha256=cvTgltucqYLLIX84QxAwf51Z5Vc2n6cLxS8VcrxNCAo,6401
@@ -171,9 +170,9 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
171
170
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
172
171
  modal_version/__init__.py,sha256=wiJQ53c-OMs0Xf1UeXOxQ7FwlV1VzIjnX6o-pRYZ_Pk,470
173
172
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
174
- modal_version/_version_generated.py,sha256=48GMAoPZ_ag_EWB42SJTPQblePrD_fvU9USnaFhq-D8,150
175
- modal-0.73.167.dist-info/METADATA,sha256=J9mj1Rd5kLYwuVHbs9jgxiyd5e19wUDaQZS76blat3g,2475
176
- modal-0.73.167.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
177
- modal-0.73.167.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
- modal-0.73.167.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
179
- modal-0.73.167.dist-info/RECORD,,
173
+ modal_version/_version_generated.py,sha256=K1I-OHoqF3Qf9hN8YD8e7nCzAieLwZ3R8l4ov209qJs,150
174
+ modal-0.73.169.dist-info/METADATA,sha256=1QhcQPji6dqJkEd3YfibNbEuaI5JLzZAsF9LmPZ8FFQ,2475
175
+ modal-0.73.169.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
176
+ modal-0.73.169.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
177
+ modal-0.73.169.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
178
+ modal-0.73.169.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2025
2
2
 
3
3
  # Note: Reset this value to -1 whenever you make a minor `0.X` release of the client.
4
- build_number = 167 # git: b37dda4
4
+ build_number = 169 # git: 4137d51
modal/_proxy_tunnel.py DELETED
@@ -1,63 +0,0 @@
1
- # Copyright Modal Labs 2022
2
- import contextlib
3
- import os
4
- import subprocess
5
- import tempfile
6
-
7
- from modal_proto import api_pb2
8
-
9
-
10
- @contextlib.contextmanager
11
- def proxy_tunnel(info: api_pb2.ProxyInfo):
12
- if not info.elastic_ip:
13
- yield
14
- return
15
-
16
- with tempfile.NamedTemporaryFile(suffix=".pem") as t:
17
- f = open(t.name, "w")
18
- f.write(info.proxy_key)
19
- f.close()
20
-
21
- if info.remote_addr:
22
- # Forward port from address.
23
- args = [
24
- "-L",
25
- f"{info.remote_port}:{info.remote_addr}:{info.remote_port}",
26
- ]
27
- else:
28
- # Set up SOCKS proxy.
29
- # TODO: add a local_port column and proxy_type (this is all being rewritten anyway)
30
- args = ["-D", f"{info.remote_port}"]
31
- os.environ["HTTP_PROXY"] = f"socks5://localhost:{info.remote_port}"
32
-
33
- # https://github.com/getsentry/sentry-python/issues/1049
34
- os.environ["NO_PROXY"] = "sentry.io"
35
-
36
- cmd = [
37
- "autossh",
38
- "-M 0", # don't use a monitoring port for autossh
39
- "-i",
40
- t.name, # use pem file
41
- "-T", # ignore the tty
42
- "-n", # no input
43
- "-N", # don't execute a command
44
- *args,
45
- f"ubuntu@{info.elastic_ip}",
46
- "-o",
47
- "StrictHostKeyChecking=no", # avoid prompt for host
48
- "-o",
49
- "ServerAliveInterval=5", # seconds before client sends keepalive to server
50
- "-o",
51
- "ServerAliveCountMax=1", # number of failures before terminating ssh (autossh will restart)
52
- "-o",
53
- "LogLevel=ERROR", # disable warning "Permanently added '...' to the list of known hosts."
54
- ]
55
- p = subprocess.Popen(cmd)
56
-
57
- import time
58
-
59
- time.sleep(3)
60
- try:
61
- yield
62
- finally:
63
- p.kill()