modal 1.1.5.dev48__py3-none-any.whl → 1.1.5.dev50__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.

modal/_output.py CHANGED
@@ -35,7 +35,7 @@ from modal._utils.time_utils import timestamp_to_localized_str
35
35
  from modal_proto import api_pb2
36
36
 
37
37
  from ._utils.grpc_utils import RETRYABLE_GRPC_STATUS_CODES, retry_transient_errors
38
- from ._utils.shell_utils import stream_from_stdin
38
+ from ._utils.shell_utils import stream_from_stdin, write_to_fd
39
39
  from .client import _Client
40
40
  from .config import logger
41
41
 
@@ -507,17 +507,32 @@ async def put_pty_content(log: api_pb2.TaskLogs, stdout):
507
507
  # because the progress spinner can't interfere with output.
508
508
 
509
509
  data = log.data.encode("utf-8")
510
- written = 0
511
- n_retries = 0
512
- while written < len(data):
513
- try:
514
- written += stdout.buffer.write(data[written:])
515
- stdout.flush()
516
- except BlockingIOError:
517
- if n_retries >= 5:
518
- raise
519
- n_retries += 1
520
- await asyncio.sleep(0.1)
510
+ # Non-blocking terminals can fill the kernel buffer on output bursts, making flush() raise
511
+ # BlockingIOError (EAGAIN) and appear frozen until a key is pressed (this happened e.g. when
512
+ # printing large data from a pdb breakpoint). If stdout has a real fd, we await a
513
+ # non-blocking fd write (write_to_fd) instead.
514
+ fd = None
515
+ try:
516
+ if hasattr(stdout, "fileno"):
517
+ fd = stdout.fileno()
518
+ except Exception:
519
+ fd = None
520
+
521
+ if fd is not None:
522
+ await write_to_fd(fd, data)
523
+ else:
524
+ # For streams without fileno(), use the normal write/flush path.
525
+ written = 0
526
+ n_retries = 0
527
+ while written < len(data):
528
+ try:
529
+ written += stdout.buffer.write(data[written:])
530
+ stdout.flush()
531
+ except BlockingIOError:
532
+ if n_retries >= 5:
533
+ raise
534
+ n_retries += 1
535
+ await asyncio.sleep(0.1)
521
536
  else:
522
537
  # `stdout` isn't always buffered (e.g. %%capture in Jupyter notebooks redirects it to
523
538
  # io.StringIO).
@@ -31,12 +31,27 @@ def is_valid_environment_name(name: str) -> bool:
31
31
  return len(name) <= 64 and re.match(r"^[a-zA-Z0-9][a-zA-Z0-9-_.]+$", name) is not None
32
32
 
33
33
 
34
- def is_valid_tag(tag: str) -> bool:
35
- """Tags are alphanumeric, dashes, periods, and underscores, and must be 50 characters or less"""
36
- pattern = r"^[a-zA-Z0-9._-]{1,50}$"
34
+ def is_valid_tag(tag: str, max_length: int = 50) -> bool:
35
+ """Tags are alphanumeric, dashes, periods, and underscores, and not longer than the max_length."""
36
+ pattern = rf"^[a-zA-Z0-9._-]{{1,{max_length}}}$"
37
37
  return bool(re.match(pattern, tag))
38
38
 
39
39
 
40
+ def check_tag_dict(tags: dict[str, str]) -> dict[str, str]:
41
+ rules = (
42
+ "\n\nTags may contain only alphanumeric characters, dashes, periods, or underscores, "
43
+ "and must be 63 characters or less."
44
+ )
45
+ max_length = 63
46
+ for key, value in tags.items():
47
+ if not is_valid_tag(key, max_length):
48
+ raise InvalidError(f"Invalid tag key: {key!r}.{rules}")
49
+ if not is_valid_tag(value, max_length):
50
+ raise InvalidError(f"Invalid tag value: {value!r}.{rules}")
51
+
52
+ return tags
53
+
54
+
40
55
  def check_object_name(name: str, object_type: str) -> None:
41
56
  message = (
42
57
  f"Invalid {object_type} name: '{name}'."
modal/app.py CHANGED
@@ -35,7 +35,7 @@ from ._utils.deprecation import (
35
35
  from ._utils.function_utils import FunctionInfo, is_global_object, is_method_fn
36
36
  from ._utils.grpc_utils import retry_transient_errors
37
37
  from ._utils.mount_utils import validate_volumes
38
- from ._utils.name_utils import check_object_name
38
+ from ._utils.name_utils import check_object_name, check_tag_dict
39
39
  from .client import _Client
40
40
  from .cloud_bucket_mount import _CloudBucketMount
41
41
  from .cls import _Cls, parameter
@@ -151,6 +151,8 @@ class _App:
151
151
 
152
152
  _name: Optional[str]
153
153
  _description: Optional[str]
154
+ _tags: dict[str, str]
155
+
154
156
  _functions: dict[str, _Function]
155
157
  _classes: dict[str, _Cls]
156
158
 
@@ -171,6 +173,7 @@ class _App:
171
173
  self,
172
174
  name: Optional[str] = None,
173
175
  *,
176
+ tags: Optional[dict[str, str]] = None, # Additional metadata to set on the App
174
177
  image: Optional[_Image] = None, # Default Image for the App (otherwise default to `modal.Image.debian_slim()`)
175
178
  secrets: Sequence[_Secret] = [], # Secrets to add for all Functions in the App
176
179
  volumes: dict[Union[str, PurePosixPath], _Volume] = {}, # Volume mounts to use for all Functions
@@ -190,6 +193,7 @@ class _App:
190
193
 
191
194
  self._name = name
192
195
  self._description = name
196
+ self._tags = check_tag_dict(tags or {})
193
197
  self._include_source_default = include_source
194
198
 
195
199
  check_sequence(secrets, _Secret, "`secrets=` has to be a list or tuple of `modal.Secret` objects")
@@ -371,8 +375,8 @@ class _App:
371
375
  *,
372
376
  name: Optional[str] = None, # Name for the deployment, overriding any set on the App
373
377
  environment_name: Optional[str] = None, # Environment to deploy the App in
374
- tag: str = "", # Optional metadata that will be visible in the deployment history
375
- client: Optional[_Client] = None, # Alternate client to use for RPCs
378
+ tag: str = "", # Optional metadata that is specific to this deployment
379
+ client: Optional[_Client] = None, # Alternate client to use for communication with the server
376
380
  ) -> typing_extensions.Self:
377
381
  """Deploy the App so that it is available persistently.
378
382
 
@@ -1044,7 +1048,7 @@ class _App:
1044
1048
 
1045
1049
  return wrapper
1046
1050
 
1047
- def include(self, /, other_app: "_App") -> typing_extensions.Self:
1051
+ def include(self, /, other_app: "_App", inherit_tags: bool = True) -> typing_extensions.Self:
1048
1052
  """Include another App's objects in this one.
1049
1053
 
1050
1054
  Useful for splitting up Modal Apps across different self-contained files.
@@ -1067,6 +1071,10 @@ class _App:
1067
1071
  # use function declared on the included app
1068
1072
  bar.remote()
1069
1073
  ```
1074
+
1075
+ When `inherit_tags=True` any tags set on the other App will be inherited by this App
1076
+ (with this App's tags taking precedence in the case of conflicts).
1077
+
1070
1078
  """
1071
1079
  for tag, function in other_app._functions.items():
1072
1080
  self._add_function(function, False) # TODO(erikbern): webhook config?
@@ -1080,6 +1088,10 @@ class _App:
1080
1088
  )
1081
1089
 
1082
1090
  self._add_class(tag, cls)
1091
+
1092
+ if inherit_tags:
1093
+ self._tags = {**other_app._tags, **self._tags}
1094
+
1083
1095
  return self
1084
1096
 
1085
1097
  async def _logs(self, client: Optional[_Client] = None) -> AsyncGenerator[str, None]:
modal/app.pyi CHANGED
@@ -110,6 +110,7 @@ class _App:
110
110
  _container_app: typing.ClassVar[typing.Optional[_App]]
111
111
  _name: typing.Optional[str]
112
112
  _description: typing.Optional[str]
113
+ _tags: dict[str, str]
113
114
  _functions: dict[str, modal._functions._Function]
114
115
  _classes: dict[str, modal.cls._Cls]
115
116
  _image: typing.Optional[modal.image._Image]
@@ -126,6 +127,7 @@ class _App:
126
127
  self,
127
128
  name: typing.Optional[str] = None,
128
129
  *,
130
+ tags: typing.Optional[dict[str, str]] = None,
129
131
  image: typing.Optional[modal.image._Image] = None,
130
132
  secrets: collections.abc.Sequence[modal.secret._Secret] = [],
131
133
  volumes: dict[typing.Union[str, pathlib.PurePosixPath], modal.volume._Volume] = {},
@@ -492,7 +494,7 @@ class _App:
492
494
  """Decorator to register a new Modal [Cls](https://modal.com/docs/reference/modal.Cls) with this App."""
493
495
  ...
494
496
 
495
- def include(self, /, other_app: _App) -> typing_extensions.Self:
497
+ def include(self, /, other_app: _App, inherit_tags: bool = True) -> typing_extensions.Self:
496
498
  """Include another App's objects in this one.
497
499
 
498
500
  Useful for splitting up Modal Apps across different self-contained files.
@@ -515,6 +517,9 @@ class _App:
515
517
  # use function declared on the included app
516
518
  bar.remote()
517
519
  ```
520
+
521
+ When `inherit_tags=True` any tags set on the other App will be inherited by this App
522
+ (with this App's tags taking precedence in the case of conflicts).
518
523
  """
519
524
  ...
520
525
 
@@ -576,6 +581,7 @@ class App:
576
581
  _container_app: typing.ClassVar[typing.Optional[App]]
577
582
  _name: typing.Optional[str]
578
583
  _description: typing.Optional[str]
584
+ _tags: dict[str, str]
579
585
  _functions: dict[str, modal.functions.Function]
580
586
  _classes: dict[str, modal.cls.Cls]
581
587
  _image: typing.Optional[modal.image.Image]
@@ -592,6 +598,7 @@ class App:
592
598
  self,
593
599
  name: typing.Optional[str] = None,
594
600
  *,
601
+ tags: typing.Optional[dict[str, str]] = None,
595
602
  image: typing.Optional[modal.image.Image] = None,
596
603
  secrets: collections.abc.Sequence[modal.secret.Secret] = [],
597
604
  volumes: dict[typing.Union[str, pathlib.PurePosixPath], modal.volume.Volume] = {},
@@ -1101,7 +1108,7 @@ class App:
1101
1108
  """Decorator to register a new Modal [Cls](https://modal.com/docs/reference/modal.Cls) with this App."""
1102
1109
  ...
1103
1110
 
1104
- def include(self, /, other_app: App) -> typing_extensions.Self:
1111
+ def include(self, /, other_app: App, inherit_tags: bool = True) -> typing_extensions.Self:
1105
1112
  """Include another App's objects in this one.
1106
1113
 
1107
1114
  Useful for splitting up Modal Apps across different self-contained files.
@@ -1124,6 +1131,9 @@ class App:
1124
1131
  # use function declared on the included app
1125
1132
  bar.remote()
1126
1133
  ```
1134
+
1135
+ When `inherit_tags=True` any tags set on the other App will be inherited by this App
1136
+ (with this App's tags taking precedence in the case of conflicts).
1127
1137
  """
1128
1138
  ...
1129
1139
 
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.5.dev48",
36
+ version: str = "1.1.5.dev50",
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.5.dev48",
167
+ version: str = "1.1.5.dev50",
168
168
  ):
169
169
  """mdmd:hidden
170
170
  The Modal client object is not intended to be instantiated directly by users.
modal/runner.py CHANGED
@@ -183,8 +183,9 @@ async def _publish_app(
183
183
  app_state: int, # api_pb2.AppState.value
184
184
  functions: dict[str, _Function],
185
185
  classes: dict[str, _Cls],
186
- name: str = "", # Only relevant for deployments
187
- tag: str = "", # Only relevant for deployments
186
+ name: str = "",
187
+ tags: dict[str, str] = {}, # Additional App metadata
188
+ deployment_tag: str = "", # Only relevant for deployments
188
189
  commit_info: Optional[api_pb2.CommitInfo] = None, # Git commit information
189
190
  ) -> tuple[str, list[api_pb2.Warning]]:
190
191
  """Wrapper for AppPublish RPC."""
@@ -194,12 +195,13 @@ async def _publish_app(
194
195
  request = api_pb2.AppPublishRequest(
195
196
  app_id=running_app.app_id,
196
197
  name=name,
197
- deployment_tag=tag,
198
+ tags=tags,
199
+ deployment_tag=deployment_tag,
200
+ commit_info=commit_info,
198
201
  app_state=app_state, # type: ignore : should be a api_pb2.AppState.value
199
202
  function_ids=running_app.function_ids,
200
203
  class_ids=running_app.class_ids,
201
204
  definition_ids=definition_ids,
202
- commit_info=commit_info,
203
205
  )
204
206
 
205
207
  try:
@@ -340,7 +342,7 @@ async def _run_app(
340
342
  await _create_all_objects(client, running_app, app._functions, app._classes, environment_name)
341
343
 
342
344
  # Publish the app
343
- await _publish_app(client, running_app, app_state, app._functions, app._classes)
345
+ await _publish_app(client, running_app, app_state, app._functions, app._classes, tags=app._tags)
344
346
  except asyncio.CancelledError as e:
345
347
  # this typically happens on sigint/ctrl-C during setup (the KeyboardInterrupt happens in the main thread)
346
348
  if output_mgr := _get_output_manager():
@@ -448,7 +450,14 @@ async def _serve_update(
448
450
  )
449
451
 
450
452
  # Publish the updated app
451
- await _publish_app(client, running_app, api_pb2.APP_STATE_UNSPECIFIED, app._functions, app._classes)
453
+ await _publish_app(
454
+ client,
455
+ running_app,
456
+ app_state=api_pb2.APP_STATE_UNSPECIFIED,
457
+ functions=app._functions,
458
+ classes=app._classes,
459
+ tags=app._tags,
460
+ )
452
461
 
453
462
  # Communicate to the parent process
454
463
  is_ready.set()
@@ -497,7 +506,7 @@ async def _deploy_app(
497
506
  else:
498
507
  check_object_name(name, "App")
499
508
 
500
- if tag and not is_valid_tag(tag):
509
+ if tag and not is_valid_tag(tag, max_length=50):
501
510
  raise InvalidError(
502
511
  f"Deployment tag {tag!r} is invalid."
503
512
  "\n\nTags may only contain alphanumeric characters, dashes, periods, and underscores, "
@@ -540,12 +549,13 @@ async def _deploy_app(
540
549
  app_url, warnings = await _publish_app(
541
550
  client,
542
551
  running_app,
543
- api_pb2.APP_STATE_DEPLOYED,
544
- app._functions,
545
- app._classes,
546
- name,
547
- tag,
548
- commit_info,
552
+ app_state=api_pb2.APP_STATE_DEPLOYED,
553
+ functions=app._functions,
554
+ classes=app._classes,
555
+ name=name,
556
+ tags=app._tags,
557
+ deployment_tag=tag,
558
+ commit_info=commit_info,
549
559
  )
550
560
  except Exception as e:
551
561
  # Note that AppClientDisconnect only stops the app if it's still initializing, and is a no-op otherwise.
modal/runner.pyi CHANGED
@@ -43,7 +43,8 @@ async def _publish_app(
43
43
  functions: dict[str, modal._functions._Function],
44
44
  classes: dict[str, modal.cls._Cls],
45
45
  name: str = "",
46
- tag: str = "",
46
+ tags: dict[str, str] = {},
47
+ deployment_tag: str = "",
47
48
  commit_info: typing.Optional[modal_proto.api_pb2.CommitInfo] = None,
48
49
  ) -> tuple[str, list[modal_proto.api_pb2.Warning]]:
49
50
  """Wrapper for AppPublish RPC."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.1.5.dev48
3
+ Version: 1.1.5.dev50
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -7,7 +7,7 @@ modal/_functions.py,sha256=6e4rFdl8thTnRuhUOj_4ehOzC1wdvJHhYSoIwB0LXhU,91783
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=gwsLdXb-Ecd8nH8LVCo8oVZPzzdyo9BrN1DjgQmsSuM,11967
10
- modal/_output.py,sha256=G9CeSQEBzjhveWWEzWmYa5Uwbu4lZf8N8IFH1UM4fU0,25803
10
+ modal/_output.py,sha256=h7wyYPtHdWFgtiWg-5obZI07RaNwivoEiLCUPl8ZOKc,26522
11
11
  modal/_partial_function.py,sha256=Yqk97hLS6vi8nWWVpzS5TSWbndWMdCtkhccdnyDJgBk,37302
12
12
  modal/_pty.py,sha256=E58MQ8d5-wkbMatRKpQR-G9FdbCRcZGiZxOpGy__VuY,1481
13
13
  modal/_resolver.py,sha256=2RWvm34cNSnbv1v7izJMNZgfvpLDD6LzaBlr0lIrLnY,7364
@@ -18,11 +18,11 @@ modal/_tunnel.py,sha256=zTBxBiuH1O22tS1OliAJdIsSmaZS8PlnifS_6S5z-mk,6320
18
18
  modal/_tunnel.pyi,sha256=rvC7USR2BcKkbZIeCJXwf7-UfGE-LPLjKsGNiK7Lxa4,13366
19
19
  modal/_type_manager.py,sha256=DWjgmjYJuOagw2erin506UUbG2H5UzZCFEekS-7hmfA,9087
20
20
  modal/_watcher.py,sha256=K6LYnlmSGQB4tWWI9JADv-tvSvQ1j522FwT71B51CX8,3584
21
- modal/app.py,sha256=Escm3cNiy0cXnVazO85BQgBItGeNXSfxqNEFiqcxqXk,49159
22
- modal/app.pyi,sha256=KzBPGM8nJc-y_79jNYlSXb6iseG0Sn0Mk73Lq5zTlfA,44167
21
+ modal/app.py,sha256=RRUz2NjAWIQLHtU2IEslOlnIOCxPiWts3IP3rTFArkY,49635
22
+ modal/app.pyi,sha256=CDp_rlX3hBuFdv9VRsKvNKCgu_hS2IO2uNU5qhzmXps,44719
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=Zu4jjt2_Ebru0kMYKCVMU3rJ0vI_aeBK4Vplp72OUmQ,15831
25
+ modal/client.pyi,sha256=UEobAPtA7A9nqeyy_CcuxBxwGyEqDlJssPgUhqa9fVo,15831
26
26
  modal/cloud_bucket_mount.py,sha256=I2GRXYhOWLIz2kJZjXu75jAm9EJkBNcutGc6jR2ReUw,5928
27
27
  modal/cloud_bucket_mount.pyi,sha256=VuUOipMIHqFXMkD-3g2bsoqpSxV5qswlFHDOqPQzYAo,7405
28
28
  modal/cls.py,sha256=R1uLQbdqWRRjvxs0I57a4hZZELZkBVCxOKxvKryU5_s,41639
@@ -62,8 +62,8 @@ modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
62
  modal/queue.py,sha256=ooD_-z3gthje_kxBZQ_xDfwyTy_cxtyn5oM9wt2sXTo,27133
63
63
  modal/queue.pyi,sha256=EJ6extEFKclbEUBXk-PuRJ4bkUYRwWgAAUNofQBbBmo,39509
64
64
  modal/retries.py,sha256=IvNLDM0f_GLUDD5VgEDoN09C88yoxSrCquinAuxT1Sc,5205
65
- modal/runner.py,sha256=oYgCbF1HfiV9gOCiwgFkgx9SEBrp0uiPHNpdegIN_j4,24264
66
- modal/runner.pyi,sha256=lbwLljm1cC8d6PcNvmYQhkE8501V9fg0bYqqKX6G4r4,8489
65
+ modal/runner.py,sha256=Yr1qdz4cx7Xb193ywU4_7ahOIolt5To1rNNs2tXk68w,24580
66
+ modal/runner.pyi,sha256=vUDRKqLz09QvZsaCH1gTG_iujewj-eGxxb6-VmN6eAw,8531
67
67
  modal/running_app.py,sha256=v61mapYNV1-O-Uaho5EfJlryMLvIT9We0amUOSvSGx8,1188
68
68
  modal/sandbox.py,sha256=qi_zWDOntB6RSAejCrAAKcW3vZZOkdrBnuic4dBo7NI,45953
69
69
  modal/sandbox.pyi,sha256=Jkmi83cU0YfZTmGbyCiChHPcjpTjsagw4Q50_cowfNQ,50689
@@ -106,7 +106,7 @@ modal/_utils/http_utils.py,sha256=yeTFsXYr0rYMEhB7vBP7audG9Uc7OLhzKBANFDZWVt0,24
106
106
  modal/_utils/jwt_utils.py,sha256=fxH9plyrbAemTbjSsQtzIdDXE9QXxvMC4DiUZ16G0aA,1360
107
107
  modal/_utils/logger.py,sha256=NgbMKFT9chYYt_TU01DdIior5ByYr2gZtrWIk1SFRLc,1782
108
108
  modal/_utils/mount_utils.py,sha256=gGCgIlWwYiJbUtgFY2GJcWYismYvazbMAeUOgf7NhFQ,3205
109
- modal/_utils/name_utils.py,sha256=TW1iyJedvDNPEJ5UVp93u8xuD5J2gQL_CUt1mgov_aI,1939
109
+ modal/_utils/name_utils.py,sha256=ZmO5Mt_GNwswSfK5k799YG_VM6b1sjN8AqEWDNPZAKo,2505
110
110
  modal/_utils/package_utils.py,sha256=LcL2olGN4xaUzu2Tbv-C-Ft9Qp6bsLxEfETOAVd-mjU,2073
111
111
  modal/_utils/pattern_utils.py,sha256=ZUffaECfe2iYBhH6cvCB-0-UWhmEBTZEl_TwG_So3ag,6714
112
112
  modal/_utils/rand_pb_testing.py,sha256=mmVPk1rZldHwHZx0DnHTuHQlRLAiiAYdxjwEJpxvT9c,3900
@@ -153,7 +153,7 @@ modal/experimental/__init__.py,sha256=fCqzo_f3vcY750vHtd7CtLs5dvdM_C0ZLLGb3zXuK9
153
153
  modal/experimental/flash.py,sha256=7qRAL2Nrwbb60YKobcnpM0zJ8vw4xGJqabLPFgEzMZE,28295
154
154
  modal/experimental/flash.pyi,sha256=R9VV0UDotiY9BRUjacB-xI4qhR3yBymAvEZFRFHztLs,15143
155
155
  modal/experimental/ipython.py,sha256=TrCfmol9LGsRZMeDoeMPx3Hv3BFqQhYnmD_iH0pqdhk,2904
156
- modal-1.1.5.dev48.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
156
+ modal-1.1.5.dev50.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
157
157
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
158
158
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
159
159
  modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
@@ -182,10 +182,10 @@ modal_proto/sandbox_router_pb2.py,sha256=INd9izYaIYqllESQt4MSv2Rj9Hf5bMjAvtCc9b4
182
182
  modal_proto/sandbox_router_pb2.pyi,sha256=YCK0WnCgRos3-p7t4USQQ7x6WAuM278yeQX2IeU5mLg,13295
183
183
  modal_proto/sandbox_router_pb2_grpc.py,sha256=zonC5flvCwxeZYJPENj1IJo2Mr0J58DpoC1_8IdPYik,8243
184
184
  modal_proto/sandbox_router_pb2_grpc.pyi,sha256=4QgCB9b7_ykvH8YD-hfnogVH9CLyHVDC5QNb03l4_X8,2735
185
- modal_version/__init__.py,sha256=D4fBvoKYlZJ5e0kQv600BpydA8DisbO74c50p3RbWt4,121
185
+ modal_version/__init__.py,sha256=aNPw1vZGpIJqV9GRWtk-F9ShuP-vWLvnXVSPvI1K6Cg,121
186
186
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
187
- modal-1.1.5.dev48.dist-info/METADATA,sha256=YB3iIMxoM6i-iszUgu4UN-UAb1yLkN7UFAaO5aXUQGE,2481
188
- modal-1.1.5.dev48.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
189
- modal-1.1.5.dev48.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
190
- modal-1.1.5.dev48.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
191
- modal-1.1.5.dev48.dist-info/RECORD,,
187
+ modal-1.1.5.dev50.dist-info/METADATA,sha256=TQAUmpVVV5RAPm_3T3qH0exTG7JlCATd2if1djc9Bxs,2481
188
+ modal-1.1.5.dev50.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
189
+ modal-1.1.5.dev50.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
190
+ modal-1.1.5.dev50.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
191
+ modal-1.1.5.dev50.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.5.dev48"
4
+ __version__ = "1.1.5.dev50"