modal 1.1.5.dev66__py3-none-any.whl → 1.3.1.dev8__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.

Files changed (143) hide show
  1. modal/__init__.py +4 -4
  2. modal/__main__.py +4 -29
  3. modal/_billing.py +84 -0
  4. modal/_clustered_functions.py +1 -3
  5. modal/_container_entrypoint.py +33 -208
  6. modal/_functions.py +171 -138
  7. modal/_grpc_client.py +191 -0
  8. modal/_ipython.py +16 -6
  9. modal/_load_context.py +106 -0
  10. modal/_object.py +72 -21
  11. modal/_output.py +12 -14
  12. modal/_partial_function.py +31 -4
  13. modal/_resolver.py +44 -57
  14. modal/_runtime/container_io_manager.py +30 -28
  15. modal/_runtime/container_io_manager.pyi +42 -44
  16. modal/_runtime/gpu_memory_snapshot.py +9 -7
  17. modal/_runtime/user_code_event_loop.py +80 -0
  18. modal/_runtime/user_code_imports.py +236 -10
  19. modal/_serialization.py +2 -1
  20. modal/_traceback.py +4 -13
  21. modal/_tunnel.py +16 -11
  22. modal/_tunnel.pyi +25 -3
  23. modal/_utils/async_utils.py +337 -10
  24. modal/_utils/auth_token_manager.py +1 -4
  25. modal/_utils/blob_utils.py +29 -22
  26. modal/_utils/function_utils.py +20 -21
  27. modal/_utils/grpc_testing.py +6 -3
  28. modal/_utils/grpc_utils.py +223 -64
  29. modal/_utils/mount_utils.py +26 -1
  30. modal/_utils/name_utils.py +2 -3
  31. modal/_utils/package_utils.py +0 -1
  32. modal/_utils/rand_pb_testing.py +8 -1
  33. modal/_utils/task_command_router_client.py +524 -0
  34. modal/_vendor/cloudpickle.py +144 -48
  35. modal/app.py +285 -105
  36. modal/app.pyi +216 -53
  37. modal/billing.py +5 -0
  38. modal/builder/2025.06.txt +6 -3
  39. modal/builder/PREVIEW.txt +2 -1
  40. modal/builder/base-images.json +4 -2
  41. modal/cli/_download.py +19 -3
  42. modal/cli/cluster.py +4 -2
  43. modal/cli/config.py +3 -1
  44. modal/cli/container.py +5 -4
  45. modal/cli/dict.py +5 -2
  46. modal/cli/entry_point.py +26 -2
  47. modal/cli/environment.py +2 -16
  48. modal/cli/launch.py +1 -76
  49. modal/cli/network_file_system.py +5 -20
  50. modal/cli/programs/run_jupyter.py +1 -1
  51. modal/cli/programs/vscode.py +1 -1
  52. modal/cli/queues.py +5 -4
  53. modal/cli/run.py +24 -204
  54. modal/cli/secret.py +1 -2
  55. modal/cli/shell.py +375 -0
  56. modal/cli/utils.py +1 -13
  57. modal/cli/volume.py +11 -17
  58. modal/client.py +16 -125
  59. modal/client.pyi +94 -144
  60. modal/cloud_bucket_mount.py +3 -1
  61. modal/cloud_bucket_mount.pyi +4 -0
  62. modal/cls.py +101 -64
  63. modal/cls.pyi +9 -8
  64. modal/config.py +21 -1
  65. modal/container_process.py +288 -12
  66. modal/container_process.pyi +99 -38
  67. modal/dict.py +72 -33
  68. modal/dict.pyi +88 -57
  69. modal/environments.py +16 -8
  70. modal/environments.pyi +6 -2
  71. modal/exception.py +154 -16
  72. modal/experimental/__init__.py +24 -53
  73. modal/experimental/flash.py +161 -74
  74. modal/experimental/flash.pyi +97 -49
  75. modal/file_io.py +50 -92
  76. modal/file_io.pyi +117 -89
  77. modal/functions.pyi +70 -87
  78. modal/image.py +82 -47
  79. modal/image.pyi +51 -30
  80. modal/io_streams.py +500 -149
  81. modal/io_streams.pyi +279 -189
  82. modal/mount.py +60 -46
  83. modal/mount.pyi +41 -17
  84. modal/network_file_system.py +19 -11
  85. modal/network_file_system.pyi +72 -39
  86. modal/object.pyi +114 -22
  87. modal/parallel_map.py +42 -44
  88. modal/parallel_map.pyi +9 -17
  89. modal/partial_function.pyi +4 -2
  90. modal/proxy.py +14 -6
  91. modal/proxy.pyi +10 -2
  92. modal/queue.py +45 -38
  93. modal/queue.pyi +88 -52
  94. modal/runner.py +96 -96
  95. modal/runner.pyi +44 -27
  96. modal/sandbox.py +225 -107
  97. modal/sandbox.pyi +226 -60
  98. modal/secret.py +58 -56
  99. modal/secret.pyi +28 -13
  100. modal/serving.py +7 -11
  101. modal/serving.pyi +7 -8
  102. modal/snapshot.py +29 -15
  103. modal/snapshot.pyi +18 -10
  104. modal/token_flow.py +1 -1
  105. modal/token_flow.pyi +4 -6
  106. modal/volume.py +102 -55
  107. modal/volume.pyi +125 -66
  108. {modal-1.1.5.dev66.dist-info → modal-1.3.1.dev8.dist-info}/METADATA +10 -9
  109. modal-1.3.1.dev8.dist-info/RECORD +189 -0
  110. modal_proto/api.proto +141 -70
  111. modal_proto/api_grpc.py +42 -26
  112. modal_proto/api_pb2.py +1123 -1103
  113. modal_proto/api_pb2.pyi +331 -83
  114. modal_proto/api_pb2_grpc.py +80 -48
  115. modal_proto/api_pb2_grpc.pyi +26 -18
  116. modal_proto/modal_api_grpc.py +175 -174
  117. modal_proto/task_command_router.proto +164 -0
  118. modal_proto/task_command_router_grpc.py +138 -0
  119. modal_proto/task_command_router_pb2.py +180 -0
  120. modal_proto/{sandbox_router_pb2.pyi → task_command_router_pb2.pyi} +148 -57
  121. modal_proto/task_command_router_pb2_grpc.py +272 -0
  122. modal_proto/task_command_router_pb2_grpc.pyi +100 -0
  123. modal_version/__init__.py +1 -1
  124. modal_version/__main__.py +1 -1
  125. modal/cli/programs/launch_instance_ssh.py +0 -94
  126. modal/cli/programs/run_marimo.py +0 -95
  127. modal-1.1.5.dev66.dist-info/RECORD +0 -191
  128. modal_proto/modal_options_grpc.py +0 -3
  129. modal_proto/options.proto +0 -19
  130. modal_proto/options_grpc.py +0 -3
  131. modal_proto/options_pb2.py +0 -35
  132. modal_proto/options_pb2.pyi +0 -20
  133. modal_proto/options_pb2_grpc.py +0 -4
  134. modal_proto/options_pb2_grpc.pyi +0 -7
  135. modal_proto/sandbox_router.proto +0 -125
  136. modal_proto/sandbox_router_grpc.py +0 -89
  137. modal_proto/sandbox_router_pb2.py +0 -128
  138. modal_proto/sandbox_router_pb2_grpc.py +0 -169
  139. modal_proto/sandbox_router_pb2_grpc.pyi +0 -63
  140. {modal-1.1.5.dev66.dist-info → modal-1.3.1.dev8.dist-info}/WHEEL +0 -0
  141. {modal-1.1.5.dev66.dist-info → modal-1.3.1.dev8.dist-info}/entry_points.txt +0 -0
  142. {modal-1.1.5.dev66.dist-info → modal-1.3.1.dev8.dist-info}/licenses/LICENSE +0 -0
  143. {modal-1.1.5.dev66.dist-info → modal-1.3.1.dev8.dist-info}/top_level.txt +0 -0
modal_proto/api.proto CHANGED
@@ -4,7 +4,7 @@ option go_package = "github.com/modal-labs/modal/go/proto";
4
4
 
5
5
  package modal.client;
6
6
 
7
- import "modal_proto/options.proto";
7
+ import "google/protobuf/any.proto";
8
8
  import "google/protobuf/empty.proto";
9
9
  import "google/protobuf/struct.proto";
10
10
  import "google/protobuf/timestamp.proto";
@@ -298,10 +298,11 @@ message AppClientDisconnectRequest {
298
298
  }
299
299
 
300
300
  message AppCreateRequest {
301
- string client_id = 1 [ (modal.options.audit_target_attr) = true ];
301
+ string client_id = 1;
302
302
  string description = 2; // Human readable label for the app
303
303
  string environment_name = 5;
304
304
  AppState app_state = 6;
305
+ map<string, string> tags = 7; // Additional metadata to attach to the App
305
306
  }
306
307
 
307
308
  message AppCreateResponse {
@@ -311,7 +312,7 @@ message AppCreateResponse {
311
312
  }
312
313
 
313
314
  message AppDeployRequest {
314
- string app_id = 1 [ (modal.options.audit_target_attr) = true ];
315
+ string app_id = 1;
315
316
  reserved 2; // namespace
316
317
  string name = 3;
317
318
  string object_entity = 4;
@@ -367,6 +368,7 @@ message AppGetLogsRequest {
367
368
  float timeout = 2;
368
369
  string last_entry_id = 4;
369
370
  string function_id = 5;
371
+ string parametrized_function_id = 11;
370
372
  string input_id = 6;
371
373
  string task_id = 7;
372
374
  string function_call_id = 9;
@@ -399,6 +401,14 @@ message AppGetOrCreateResponse {
399
401
  string app_id = 1;
400
402
  }
401
403
 
404
+ message AppGetTagsRequest {
405
+ string app_id = 1;
406
+ }
407
+
408
+ message AppGetTagsResponse {
409
+ map<string, string> tags = 1;
410
+ }
411
+
402
412
  message AppHeartbeatRequest {
403
413
  string app_id = 1;
404
414
  }
@@ -436,7 +446,7 @@ message AppLookupResponse {
436
446
  }
437
447
 
438
448
  message AppPublishRequest {
439
- string app_id = 1 [ (modal.options.audit_target_attr) = true ];
449
+ string app_id = 1;
440
450
  string name = 2;
441
451
  string deployment_tag = 3; // Additional metadata to identify a deployment
442
452
  AppState app_state = 4; // Published app will be in this state
@@ -468,8 +478,14 @@ message AppSetObjectsRequest {
468
478
  reserved 6;
469
479
  }
470
480
 
481
+ message AppSetTagsRequest {
482
+ string app_id = 1;
483
+ map<string, string> tags = 2;
484
+ }
485
+
486
+
471
487
  message AppStopRequest {
472
- string app_id = 1 [ (modal.options.audit_target_attr) = true ];
488
+ string app_id = 1;
473
489
  AppStopSource source = 2;
474
490
  }
475
491
 
@@ -715,6 +731,7 @@ message BuildFunction {
715
731
  message CancelInputEvent {
716
732
  repeated string input_ids = 1;
717
733
  bool terminate_containers = 2;
734
+ string cancellation_reason = 3;
718
735
  }
719
736
 
720
737
  message CheckpointInfo {
@@ -730,7 +747,7 @@ message CheckpointInfo {
730
747
  }
731
748
 
732
749
  message ClassCreateRequest {
733
- string app_id = 1 [ (modal.options.audit_target_attr) = true ];
750
+ string app_id = 1 ;
734
751
  string existing_class_id = 2;
735
752
  repeated ClassMethod methods = 3;
736
753
  reserved 4; // removed class_function_id
@@ -835,6 +852,12 @@ message CloudBucketMount {
835
852
  GCP = 3;
836
853
  }
837
854
 
855
+ enum MetadataTTLType {
856
+ METADATA_TTL_TYPE_UNSPECIFIED = 0;
857
+ METADATA_TTL_TYPE_MINIMAL = 1;
858
+ METADATA_TTL_TYPE_INDEFINITE = 2;
859
+ }
860
+
838
861
  string bucket_name = 1;
839
862
  string mount_path = 2;
840
863
  string credentials_secret_id = 3;
@@ -844,6 +867,11 @@ message CloudBucketMount {
844
867
  optional string bucket_endpoint_url = 7;
845
868
  optional string key_prefix = 8;
846
869
  optional string oidc_auth_role_arn = 9;
870
+ bool force_path_style = 10;
871
+ oneof metadata_ttl_oneof {
872
+ MetadataTTLType metadata_ttl_type = 11;
873
+ uint64 metadata_ttl_seconds = 12;
874
+ }
847
875
  }
848
876
 
849
877
  message ClusterGetRequest {
@@ -1064,7 +1092,7 @@ message ContainerReloadVolumesRequest {
1064
1092
  message ContainerReloadVolumesResponse { }
1065
1093
 
1066
1094
  message ContainerStopRequest {
1067
- string task_id = 1 [ (modal.options.audit_target_attr) = true ];
1095
+ string task_id = 1;
1068
1096
  }
1069
1097
 
1070
1098
  message ContainerStopResponse {
@@ -1132,7 +1160,7 @@ message DictEntry {
1132
1160
  }
1133
1161
 
1134
1162
  message DictGetOrCreateRequest {
1135
- string deployment_name = 1 [ (modal.options.audit_target_attr) = true ];
1163
+ string deployment_name = 1;
1136
1164
  reserved 2; // removed namespace
1137
1165
  string environment_name = 3;
1138
1166
  ObjectCreationType object_creation_type = 4;
@@ -1199,7 +1227,7 @@ message DictPopResponse {
1199
1227
  }
1200
1228
 
1201
1229
  message DictUpdateRequest {
1202
- string dict_id = 1 [ (modal.options.audit_target_attr) = true ];
1230
+ string dict_id = 1;
1203
1231
  repeated DictEntry updates = 2;
1204
1232
  bool if_not_exists = 3;
1205
1233
  }
@@ -1225,7 +1253,7 @@ message DomainCertificateVerifyResponse {
1225
1253
  }
1226
1254
 
1227
1255
  message DomainCreateRequest {
1228
- string domain_name = 1 [ (modal.options.audit_target_attr) = true ];
1256
+ string domain_name = 1 ;
1229
1257
  }
1230
1258
 
1231
1259
  message DomainCreateResponse {
@@ -1241,14 +1269,14 @@ message DomainListResponse {
1241
1269
  }
1242
1270
 
1243
1271
  message EnvironmentCreateRequest {
1244
- string name = 1 [ (modal.options.audit_target_attr) = true ];
1272
+ string name = 1;
1245
1273
  }
1246
1274
 
1247
1275
  message EnvironmentDeleteRequest {
1248
- string name = 1 [ (modal.options.audit_target_attr) = true ];
1276
+ string name = 1;
1249
1277
  }
1250
1278
  message EnvironmentGetOrCreateRequest {
1251
- string deployment_name = 1 [ (modal.options.audit_target_attr) = true ];
1279
+ string deployment_name = 1;
1252
1280
  ObjectCreationType object_creation_type = 2;
1253
1281
  }
1254
1282
 
@@ -1264,6 +1292,10 @@ message EnvironmentListItem {
1264
1292
  bool default = 4;
1265
1293
  bool is_managed = 5;
1266
1294
  string environment_id = 6;
1295
+ optional int32 max_concurrent_tasks = 7;
1296
+ optional int32 max_concurrent_gpus = 8;
1297
+ int32 current_concurrent_tasks = 9;
1298
+ int32 current_concurrent_gpus = 10;
1267
1299
  }
1268
1300
 
1269
1301
  message EnvironmentListResponse {
@@ -1284,9 +1316,11 @@ message EnvironmentSettings {
1284
1316
  }
1285
1317
 
1286
1318
  message EnvironmentUpdateRequest {
1287
- string current_name = 1 [ (modal.options.audit_target_attr) = true ];
1319
+ string current_name = 1;
1288
1320
  google.protobuf.StringValue name = 2;
1289
1321
  google.protobuf.StringValue web_suffix = 3;
1322
+ optional int32 max_concurrent_tasks = 4;
1323
+ optional int32 max_concurrent_gpus = 5;
1290
1324
  }
1291
1325
 
1292
1326
  // A file entry when listing files in a volume or network file system.
@@ -1343,7 +1377,7 @@ message FlashContainerRegisterResponse {
1343
1377
 
1344
1378
  message FlashProxyUpstreamRequest {
1345
1379
  uint32 upstream_requests = 1;
1346
- double timestamp = 2;
1380
+ double timestamp = 2;
1347
1381
  }
1348
1382
 
1349
1383
  message FlashSetTargetSlotsMetricsRequest {
@@ -1435,6 +1469,8 @@ message Function {
1435
1469
 
1436
1470
  bool block_network = 44;
1437
1471
 
1472
+ // In the SDK, we've deprecated `max_inputs` (which only every implemented `max_inputs=1`)
1473
+ // in favor of a boolean `single_use_containers` parameter.
1438
1474
  uint32 max_inputs = 46;
1439
1475
 
1440
1476
  repeated S3Mount s3_mounts = 47;
@@ -1517,6 +1553,14 @@ message Function {
1517
1553
  uint32 startup_timeout_secs = 86;
1518
1554
  repeated DataFormat supported_input_formats = 87; // can be used as inputs
1519
1555
  repeated DataFormat supported_output_formats = 88;
1556
+ optional HTTPConfig http_config = 89;
1557
+
1558
+ // Attribute on the module with the implementation, which may differ from function_name
1559
+ // when the user provided a custom name= for the Function inside the Application namespace
1560
+ string implementation_name = 90;
1561
+
1562
+ bool single_use_containers = 91; // When True, containers will shut down after handling a single input
1563
+
1520
1564
  }
1521
1565
 
1522
1566
  message FunctionAsyncInvokeRequest {
@@ -1572,6 +1616,7 @@ message FunctionCallGetDataRequest {
1572
1616
  string attempt_token = 3;
1573
1617
  }
1574
1618
  uint64 last_index = 2;
1619
+ bool use_gapless_read = 4;
1575
1620
  }
1576
1621
 
1577
1622
  message FunctionCallInfo {
@@ -1607,7 +1652,7 @@ message FunctionCallPutDataRequest {
1607
1652
 
1608
1653
  message FunctionCreateRequest {
1609
1654
  Function function = 1;
1610
- string app_id = 2 [ (modal.options.audit_target_attr) = true ];
1655
+ string app_id = 2 ;
1611
1656
  Schedule schedule = 6 [deprecated=true]; // Deprecated: now passed in the Function definition
1612
1657
  string existing_function_id = 7;
1613
1658
  reserved 8; // defer_updates
@@ -1694,6 +1739,11 @@ message FunctionData {
1694
1739
  uint32 startup_timeout_secs = 36;
1695
1740
  repeated DataFormat supported_input_formats = 37;
1696
1741
  repeated DataFormat supported_output_formats = 38;
1742
+ optional HTTPConfig http_config = 39;
1743
+
1744
+ // Attribute on the module with the implementation, which may differ from function_name
1745
+ // when the user provided a custom name= for the Function inside the Application namespace
1746
+ string implementation_name = 40;
1697
1747
  }
1698
1748
 
1699
1749
  message FunctionExtended {
@@ -1902,7 +1952,7 @@ message FunctionOptions {
1902
1952
 
1903
1953
  message FunctionPrecreateRequest {
1904
1954
  string app_id = 1;
1905
- string function_name = 2 [ (modal.options.audit_target_attr) = true ];
1955
+ string function_name = 2 ;
1906
1956
  string existing_function_id = 3;
1907
1957
  Function.FunctionType function_type = 4;
1908
1958
  WebhookConfig webhook_config = 5;
@@ -1951,8 +2001,8 @@ message FunctionPutOutputsItem {
1951
2001
  double output_created_at = 4;
1952
2002
  DataFormat data_format = 7; // for result.data_oneof
1953
2003
  uint32 retry_count = 8;
1954
- string function_call_id = 9; // injected by the worker
1955
- optional int32 function_map_idx = 10; // injected by the worker
2004
+ string function_call_id = 9; // injected by the worker
2005
+ optional int32 function_map_idx = 10; // injected by the worker
1956
2006
  }
1957
2007
 
1958
2008
  message FunctionPutOutputsRequest {
@@ -2012,6 +2062,7 @@ message GPUConfig {
2012
2062
  string gpu_type = 4;
2013
2063
  }
2014
2064
 
2065
+
2015
2066
  message GeneratorDone { // Sent as the output when a generator finishes running.
2016
2067
  uint64 items_total = 1;
2017
2068
  }
@@ -2053,6 +2104,14 @@ message GenericResult { // Used for both tasks and function outputs
2053
2104
  string propagation_reason = 13; // (?)
2054
2105
  }
2055
2106
 
2107
+ message HTTPConfig {
2108
+ uint32 port = 1;
2109
+ repeated string proxy_regions = 2;
2110
+ uint32 startup_timeout = 3;
2111
+ uint32 exit_grace_period = 4;
2112
+ bool h2_enabled = 5;
2113
+ }
2114
+
2056
2115
  message Image {
2057
2116
  repeated BaseImage base_images = 5;
2058
2117
  repeated string dockerfile_commands = 6;
@@ -2102,7 +2161,7 @@ message ImageFromIdResponse {
2102
2161
 
2103
2162
  message ImageGetOrCreateRequest {
2104
2163
  Image image = 2;
2105
- string app_id = 4 [ (modal.options.audit_target_attr) = true ];
2164
+ string app_id = 4;
2106
2165
  string existing_image_id = 5; // ignored
2107
2166
  string build_function_id = 6;
2108
2167
  bool force_build = 7;
@@ -2212,7 +2271,7 @@ message MapAwaitResponse {
2212
2271
  message MapCheckInputsRequest {
2213
2272
  string last_entry_id = 1;
2214
2273
  float timeout = 2;
2215
- repeated string attempt_tokens = 3;
2274
+ repeated string attempt_tokens = 3;
2216
2275
  }
2217
2276
 
2218
2277
  message MapCheckInputsResponse {
@@ -2433,12 +2492,13 @@ message Proxy {
2433
2492
  string name = 1;
2434
2493
  double created_at = 2;
2435
2494
  string environment_name = 3;
2436
- string proxy_id = 5;
2437
2495
  repeated ProxyIp proxy_ips = 4;
2496
+ string proxy_id = 5;
2497
+ string region = 6;
2438
2498
  }
2439
2499
 
2440
2500
  message ProxyAddIpRequest {
2441
- string proxy_id = 1 [ (modal.options.audit_target_attr) = true ];
2501
+ string proxy_id = 1;
2442
2502
  }
2443
2503
 
2444
2504
  message ProxyAddIpResponse {
@@ -2446,8 +2506,9 @@ message ProxyAddIpResponse {
2446
2506
  }
2447
2507
 
2448
2508
  message ProxyCreateRequest {
2449
- string name = 1 [ (modal.options.audit_target_attr) = true ];
2509
+ string name = 1;
2450
2510
  string environment_name = 2;
2511
+ string region = 3;
2451
2512
  }
2452
2513
 
2453
2514
  message ProxyCreateResponse {
@@ -2455,11 +2516,11 @@ message ProxyCreateResponse {
2455
2516
  }
2456
2517
 
2457
2518
  message ProxyDeleteRequest {
2458
- string proxy_id = 1 [ (modal.options.audit_target_attr) = true ];
2519
+ string proxy_id = 1;
2459
2520
  }
2460
2521
 
2461
2522
  message ProxyGetOrCreateRequest {
2462
- string deployment_name = 1 [ (modal.options.audit_target_attr) = true ];
2523
+ string deployment_name = 1;
2463
2524
  reserved 2; // namespace
2464
2525
  string environment_name = 3;
2465
2526
  ObjectCreationType object_creation_type = 4; // must be UNSPECIFIED
@@ -2470,7 +2531,7 @@ message ProxyGetOrCreateResponse {
2470
2531
  }
2471
2532
 
2472
2533
  message ProxyGetRequest {
2473
- string name = 1 [ (modal.options.audit_target_attr) = true ];
2534
+ string name = 1;
2474
2535
  string environment_name = 2;
2475
2536
  }
2476
2537
 
@@ -2498,7 +2559,7 @@ message ProxyListResponse {
2498
2559
  }
2499
2560
 
2500
2561
  message ProxyRemoveIpRequest {
2501
- string proxy_ip = 1 [ (modal.options.audit_target_attr) = true ];
2562
+ string proxy_ip = 1;
2502
2563
  }
2503
2564
 
2504
2565
  message QueueClearRequest {
@@ -2508,7 +2569,7 @@ message QueueClearRequest {
2508
2569
  }
2509
2570
 
2510
2571
  message QueueDeleteRequest {
2511
- string queue_id = 1 [ (modal.options.audit_target_attr) = true ];
2572
+ string queue_id = 1;
2512
2573
  }
2513
2574
 
2514
2575
  message QueueGetOrCreateRequest {
@@ -2596,6 +2657,22 @@ message QueuePutRequest {
2596
2657
  int32 partition_ttl_seconds = 6;
2597
2658
  }
2598
2659
 
2660
+ // Retry repolicy used by GRPCError.details for the server to give instructions
2661
+ // for the client to retry.
2662
+ message RPCRetryPolicy {
2663
+ float retry_after_secs = 1;
2664
+ }
2665
+
2666
+ // A copy google.rpc.Status for GRPCError.details:
2667
+ // https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto
2668
+ // RPCStatus is compatible with google.rpc.Status, so one can encode messages using
2669
+ // google.rpc.Status. The `details` field can be a list of any message, but for client
2670
+ // to decode it, the messages should be defined here (`modal_proto`).
2671
+ message RPCStatus {
2672
+ int32 code = 1;
2673
+ string message = 2;
2674
+ repeated google.protobuf.Any details = 3;
2675
+ }
2599
2676
 
2600
2677
  message RateLimit {
2601
2678
  int32 limit = 1;
@@ -2722,6 +2799,11 @@ message Sandbox {
2722
2799
  // Exec commands for the sandbox will be issued directly to the sandbox
2723
2800
  // command router running on the Modal worker.
2724
2801
  bool direct_sandbox_commands_enabled = 34;
2802
+
2803
+ // Internal: restricts sandbox to run on this specific instance type.
2804
+ // Set by server during SandboxRestore to ensure the restored sandbox runs
2805
+ // on the same instance type as the original snapshot.
2806
+ string _restore_instance_type = 35;
2725
2807
  }
2726
2808
 
2727
2809
  message SandboxCreateConnectTokenRequest {
@@ -2735,7 +2817,7 @@ message SandboxCreateConnectTokenResponse {
2735
2817
  }
2736
2818
 
2737
2819
  message SandboxCreateRequest {
2738
- string app_id = 1 [ (modal.options.audit_target_attr) = true ];
2820
+ string app_id = 1;
2739
2821
  Sandbox definition = 2;
2740
2822
  string environment_name = 3; // *DEPRECATED* 7/16/2025
2741
2823
  }
@@ -2744,18 +2826,6 @@ message SandboxCreateResponse {
2744
2826
  string sandbox_id = 1;
2745
2827
  }
2746
2828
 
2747
- // Used to get a JWT and URL for direct access to a sandbox router server
2748
- // running on the modal-worker, so the client can issue exec commands (and other
2749
- // operations as they become available) directly to the worker.
2750
- message SandboxGetCommandRouterAccessRequest {
2751
- string sandbox_id = 1;
2752
- }
2753
-
2754
- message SandboxGetCommandRouterAccessResponse {
2755
- string jwt = 1;
2756
- string url = 2;
2757
- }
2758
-
2759
2829
  message SandboxGetFromNameRequest {
2760
2830
  string sandbox_name = 1;
2761
2831
  string environment_name = 2;
@@ -2816,7 +2886,7 @@ message SandboxInfo {
2816
2886
  string app_id = 5;
2817
2887
  repeated SandboxTag tags = 6; // TODO: Not yet exposed in client library.
2818
2888
  string name = 7;
2819
-
2889
+ string image_id = 8;
2820
2890
  reserved 2; // modal.client.Sandbox definition
2821
2891
  }
2822
2892
 
@@ -2964,24 +3034,20 @@ message Schedule {
2964
3034
  }
2965
3035
  }
2966
3036
 
3037
+ // Scheduling constraints for Functions and Sandboxes.
2967
3038
  message SchedulerPlacement {
2968
- // TODO(irfansharif):
2969
- // - Fold in cloud, resource needs here too.
2970
- // - Allow specifying list of zones, cloud, fallback and alternative
2971
- // GPU types.
2972
-
2973
3039
  repeated string regions = 4;
2974
- // TODO(irfansharif): Make these two repeated.
2975
- optional string _zone = 2; // admin-only
2976
- optional string _lifecycle = 3; // admin-only, "on-demand" or "spot", else ignored
2977
- repeated string _instance_types = 5; // admin-only
3040
+ optional string _zone = 2 [deprecated = true];
3041
+ optional string _lifecycle = 3 [deprecated = true];
3042
+ repeated string _instance_types = 5 [deprecated = true];
3043
+ bool nonpreemptible = 6; // Functions only
2978
3044
 
2979
3045
  reserved 1;
2980
3046
  }
2981
3047
 
2982
3048
  message SecretCreateRequest { // Not used by client anymore
2983
3049
  map<string, string> env_dict = 1;
2984
- string app_id = 2 [ (modal.options.audit_target_attr) = true ];
3050
+ string app_id = 2;
2985
3051
  string template_type = 3; // todo: not used?
2986
3052
  string existing_secret_id = 4;
2987
3053
  }
@@ -2995,7 +3061,7 @@ message SecretDeleteRequest {
2995
3061
  }
2996
3062
 
2997
3063
  message SecretGetOrCreateRequest {
2998
- string deployment_name = 1 [ (modal.options.audit_target_attr) = true ];
3064
+ string deployment_name = 1;
2999
3065
  reserved 2; // removed namespace
3000
3066
  string environment_name = 3;
3001
3067
  ObjectCreationType object_creation_type = 4; // Not used atm
@@ -3052,7 +3118,7 @@ message SharedVolumeGetFileResponse {
3052
3118
  }
3053
3119
 
3054
3120
  message SharedVolumeGetOrCreateRequest {
3055
- string deployment_name = 1 [ (modal.options.audit_target_attr) = true ];
3121
+ string deployment_name = 1;
3056
3122
  reserved 2; // removed namespace
3057
3123
  string environment_name = 3;
3058
3124
  ObjectCreationType object_creation_type = 4;
@@ -3096,11 +3162,11 @@ message SharedVolumeMount {
3096
3162
  string mount_path = 1;
3097
3163
  string shared_volume_id = 2;
3098
3164
  CloudProvider cloud_provider = 3;
3099
- bool allow_cross_region = 4;
3165
+ reserved 4; // allow_cross_region
3100
3166
  }
3101
3167
 
3102
3168
  message SharedVolumePutFileRequest {
3103
- string shared_volume_id = 1 [ (modal.options.audit_target_attr) = true ];
3169
+ string shared_volume_id = 1;
3104
3170
  string path = 2;
3105
3171
  string sha256_hex = 3;
3106
3172
  oneof data_oneof {
@@ -3115,7 +3181,7 @@ message SharedVolumePutFileResponse {
3115
3181
  }
3116
3182
 
3117
3183
  message SharedVolumeRemoveFileRequest {
3118
- string shared_volume_id = 1 [ (modal.options.audit_target_attr) = true ];
3184
+ string shared_volume_id = 1;
3119
3185
  string path = 2;
3120
3186
  bool recursive = 3;
3121
3187
  }
@@ -3142,12 +3208,16 @@ message TaskCurrentInputsResponse {
3142
3208
  repeated string input_ids = 1;
3143
3209
  }
3144
3210
 
3145
- message TaskGetAutoscalingMetricsRequest {
3211
+ // Used to get a JWT and URL for direct access to a task command router
3212
+ // running on the modal-worker, so the client can issue exec commands (and other
3213
+ // operations as they become available) directly to the worker.
3214
+ message TaskGetCommandRouterAccessRequest {
3146
3215
  string task_id = 1;
3147
3216
  }
3148
3217
 
3149
- message TaskGetAutoscalingMetricsResponse {
3150
- AutoscalingMetrics metrics = 1;
3218
+ message TaskGetCommandRouterAccessResponse {
3219
+ string jwt = 1;
3220
+ string url = 2;
3151
3221
  }
3152
3222
 
3153
3223
  message TaskInfo {
@@ -3292,7 +3362,7 @@ message UserActionInfo {
3292
3362
  message VolumeCommitRequest {
3293
3363
  // NOTE(staffan): Mounting a volume in multiple locations is not supported, so volume_id alone uniquely identifies
3294
3364
  // a volume mount.
3295
- string volume_id = 1 [ (modal.options.audit_target_attr) = true ];
3365
+ string volume_id = 1;
3296
3366
  }
3297
3367
 
3298
3368
  message VolumeCommitResponse {
@@ -3350,7 +3420,7 @@ message VolumeGetFileResponse {
3350
3420
  }
3351
3421
 
3352
3422
  message VolumeGetOrCreateRequest {
3353
- string deployment_name = 1 [ (modal.options.audit_target_attr) = true ];
3423
+ string deployment_name = 1;
3354
3424
  reserved 2; // removed namespace
3355
3425
  string environment_name = 3;
3356
3426
  ObjectCreationType object_creation_type = 4;
@@ -3502,19 +3572,19 @@ message VolumeReloadRequest {
3502
3572
  }
3503
3573
 
3504
3574
  message VolumeRemoveFile2Request {
3505
- string volume_id = 1 [ (modal.options.audit_target_attr) = true ];
3575
+ string volume_id = 1;
3506
3576
  string path = 2;
3507
3577
  bool recursive = 3;
3508
3578
  }
3509
3579
 
3510
3580
  message VolumeRemoveFileRequest {
3511
- string volume_id = 1 [ (modal.options.audit_target_attr) = true ];
3581
+ string volume_id = 1;
3512
3582
  string path = 2;
3513
3583
  bool recursive = 3;
3514
3584
  }
3515
3585
 
3516
3586
  message VolumeRenameRequest {
3517
- string volume_id = 1 [ (modal.options.audit_target_attr) = true ];
3587
+ string volume_id = 1;
3518
3588
  string name = 2;
3519
3589
  }
3520
3590
 
@@ -3538,16 +3608,16 @@ message WebUrlInfo {
3538
3608
  message WebhookConfig {
3539
3609
  WebhookType type = 1;
3540
3610
  string method = 2;
3541
- string requested_suffix = 4;
3611
+ string requested_suffix = 4; // User-supplied "label" component of URL
3542
3612
  WebhookAsyncMode async_mode = 5;
3543
3613
  repeated CustomDomainConfig custom_domains = 6;
3544
3614
  uint32 web_server_port = 7;
3545
3615
  float web_server_startup_timeout = 8;
3546
3616
  bool web_endpoint_docs = 9;
3547
3617
  bool requires_proxy_auth = 10;
3618
+ string ephemeral_suffix = 11; // Additional URL suffix added for ephemeral Apps
3548
3619
  }
3549
3620
 
3550
-
3551
3621
  message WorkspaceBillingReportItem {
3552
3622
  string object_id = 1;
3553
3623
  string description = 2;
@@ -3582,12 +3652,14 @@ service ModalClient {
3582
3652
  rpc AppGetLogs(AppGetLogsRequest) returns (stream TaskLogsBatch);
3583
3653
  rpc AppGetObjects(AppGetObjectsRequest) returns (AppGetObjectsResponse);
3584
3654
  rpc AppGetOrCreate(AppGetOrCreateRequest) returns (AppGetOrCreateResponse);
3655
+ rpc AppGetTags(AppGetTagsRequest) returns (AppGetTagsResponse);
3585
3656
  rpc AppHeartbeat(AppHeartbeatRequest) returns (google.protobuf.Empty);
3586
3657
  rpc AppList(AppListRequest) returns (AppListResponse);
3587
3658
  rpc AppLookup(AppLookupRequest) returns (AppLookupResponse);
3588
3659
  rpc AppPublish(AppPublishRequest) returns (AppPublishResponse);
3589
3660
  rpc AppRollback(AppRollbackRequest) returns (google.protobuf.Empty);
3590
3661
  rpc AppSetObjects(AppSetObjectsRequest) returns (google.protobuf.Empty);
3662
+ rpc AppSetTags(AppSetTagsRequest) returns (google.protobuf.Empty);
3591
3663
  rpc AppStop(AppStopRequest) returns (google.protobuf.Empty);
3592
3664
 
3593
3665
  // Input Plane
@@ -3725,7 +3797,6 @@ service ModalClient {
3725
3797
  // Sandboxes
3726
3798
  rpc SandboxCreate(SandboxCreateRequest) returns (SandboxCreateResponse);
3727
3799
  rpc SandboxCreateConnectToken(SandboxCreateConnectTokenRequest) returns (SandboxCreateConnectTokenResponse);
3728
- rpc SandboxGetCommandRouterAccess(SandboxGetCommandRouterAccessRequest) returns (SandboxGetCommandRouterAccessResponse);
3729
3800
  rpc SandboxGetFromName(SandboxGetFromNameRequest) returns (SandboxGetFromNameResponse);
3730
3801
  rpc SandboxGetLogs(SandboxGetLogsRequest) returns (stream TaskLogsBatch);
3731
3802
  rpc SandboxGetResourceUsage(SandboxGetResourceUsageRequest) returns (SandboxGetResourceUsageResponse);
@@ -3764,7 +3835,7 @@ service ModalClient {
3764
3835
  // Tasks
3765
3836
  rpc TaskClusterHello(TaskClusterHelloRequest) returns (TaskClusterHelloResponse);
3766
3837
  rpc TaskCurrentInputs(google.protobuf.Empty) returns (TaskCurrentInputsResponse);
3767
- rpc TaskGetAutoscalingMetrics(TaskGetAutoscalingMetricsRequest) returns (TaskGetAutoscalingMetricsResponse); // Used for flash autoscaling
3838
+ rpc TaskGetCommandRouterAccess(TaskGetCommandRouterAccessRequest) returns (TaskGetCommandRouterAccessResponse);
3768
3839
  rpc TaskList(TaskListRequest) returns (TaskListResponse);
3769
3840
  rpc TaskResult(TaskResultRequest) returns (google.protobuf.Empty);
3770
3841