@@ -320,6 +320,7 @@ def __init__(
320
320
openapi_extensions : dict [str , Any ] | None = None ,
321
321
deprecated : bool = False ,
322
322
middlewares : list [Callable [..., Response ]] | None = None ,
323
+ custom_response_validation_http_code : int | HTTPStatus | None = None ,
323
324
):
324
325
"""
325
326
Internally used Route Configuration
@@ -362,6 +363,7 @@ def __init__(
362
363
Whether or not to mark this route as deprecated in the OpenAPI schema
363
364
middlewares: list[Callable[..., Response]] | None
364
365
The list of route middlewares to be called in order.
366
+ # TODO
365
367
"""
366
368
self .method = method .upper ()
367
369
self .path = "/" if path .strip () == "" else path
@@ -397,6 +399,8 @@ def __init__(
397
399
# _body_field is used to cache the dependant model for the body field
398
400
self ._body_field : ModelField | None = None
399
401
402
+ self .custom_response_validation_http_code : int | HTTPStatus | None = custom_response_validation_http_code
403
+
400
404
def __call__ (
401
405
self ,
402
406
router_middlewares : list [Callable ],
@@ -565,6 +569,8 @@ def _get_openapi_path(
565
569
},
566
570
}
567
571
572
+ # TODO update responses
573
+
568
574
# Add the response to the OpenAPI operation
569
575
if self .responses :
570
576
for status_code in list (self .responses ):
@@ -943,6 +949,7 @@ def route(
943
949
openapi_extensions : dict [str , Any ] | None = None ,
944
950
deprecated : bool = False ,
945
951
middlewares : list [Callable [..., Any ]] | None = None ,
952
+ custom_response_validation_http_code : int | HTTPStatus | None = None ,
946
953
) -> Callable [[AnyCallableT ], AnyCallableT ]:
947
954
raise NotImplementedError ()
948
955
@@ -1004,6 +1011,7 @@ def get(
1004
1011
openapi_extensions : dict [str , Any ] | None = None ,
1005
1012
deprecated : bool = False ,
1006
1013
middlewares : list [Callable [..., Any ]] | None = None ,
1014
+ custom_response_validation_http_code : int | HTTPStatus | None = None ,
1007
1015
) -> Callable [[AnyCallableT ], AnyCallableT ]:
1008
1016
"""Get route decorator with GET `method`
1009
1017
@@ -1044,6 +1052,7 @@ def lambda_handler(event, context):
1044
1052
openapi_extensions ,
1045
1053
deprecated ,
1046
1054
middlewares ,
1055
+ custom_response_validation_http_code ,
1047
1056
)
1048
1057
1049
1058
def post (
@@ -1063,6 +1072,7 @@ def post(
1063
1072
openapi_extensions : dict [str , Any ] | None = None ,
1064
1073
deprecated : bool = False ,
1065
1074
middlewares : list [Callable [..., Any ]] | None = None ,
1075
+ custom_response_validation_http_code : int | HTTPStatus | None = None ,
1066
1076
) -> Callable [[AnyCallableT ], AnyCallableT ]:
1067
1077
"""Post route decorator with POST `method`
1068
1078
@@ -1104,6 +1114,7 @@ def lambda_handler(event, context):
1104
1114
openapi_extensions ,
1105
1115
deprecated ,
1106
1116
middlewares ,
1117
+ custom_response_validation_http_code ,
1107
1118
)
1108
1119
1109
1120
def put (
@@ -1123,6 +1134,7 @@ def put(
1123
1134
openapi_extensions : dict [str , Any ] | None = None ,
1124
1135
deprecated : bool = False ,
1125
1136
middlewares : list [Callable [..., Any ]] | None = None ,
1137
+ custom_response_validation_http_code : int | HTTPStatus | None = None ,
1126
1138
) -> Callable [[AnyCallableT ], AnyCallableT ]:
1127
1139
"""Put route decorator with PUT `method`
1128
1140
@@ -1164,6 +1176,7 @@ def lambda_handler(event, context):
1164
1176
openapi_extensions ,
1165
1177
deprecated ,
1166
1178
middlewares ,
1179
+ custom_response_validation_http_code ,
1167
1180
)
1168
1181
1169
1182
def delete (
@@ -1183,6 +1196,7 @@ def delete(
1183
1196
openapi_extensions : dict [str , Any ] | None = None ,
1184
1197
deprecated : bool = False ,
1185
1198
middlewares : list [Callable [..., Any ]] | None = None ,
1199
+ custom_response_validation_http_code : int | HTTPStatus | None = None ,
1186
1200
) -> Callable [[AnyCallableT ], AnyCallableT ]:
1187
1201
"""Delete route decorator with DELETE `method`
1188
1202
@@ -1223,6 +1237,7 @@ def lambda_handler(event, context):
1223
1237
openapi_extensions ,
1224
1238
deprecated ,
1225
1239
middlewares ,
1240
+ custom_response_validation_http_code ,
1226
1241
)
1227
1242
1228
1243
def patch (
@@ -1242,6 +1257,7 @@ def patch(
1242
1257
openapi_extensions : dict [str , Any ] | None = None ,
1243
1258
deprecated : bool = False ,
1244
1259
middlewares : list [Callable ] | None = None ,
1260
+ custom_response_validation_http_code : int | HTTPStatus | None = None ,
1245
1261
) -> Callable [[AnyCallableT ], AnyCallableT ]:
1246
1262
"""Patch route decorator with PATCH `method`
1247
1263
@@ -1285,6 +1301,7 @@ def lambda_handler(event, context):
1285
1301
openapi_extensions ,
1286
1302
deprecated ,
1287
1303
middlewares ,
1304
+ custom_response_validation_http_code ,
1288
1305
)
1289
1306
1290
1307
def head (
@@ -1304,6 +1321,7 @@ def head(
1304
1321
openapi_extensions : dict [str , Any ] | None = None ,
1305
1322
deprecated : bool = False ,
1306
1323
middlewares : list [Callable ] | None = None ,
1324
+ custom_response_validation_http_code : int | HTTPStatus | None = None ,
1307
1325
) -> Callable [[AnyCallableT ], AnyCallableT ]:
1308
1326
"""Head route decorator with HEAD `method`
1309
1327
@@ -1346,6 +1364,7 @@ def lambda_handler(event, context):
1346
1364
openapi_extensions ,
1347
1365
deprecated ,
1348
1366
middlewares ,
1367
+ custom_response_validation_http_code ,
1349
1368
)
1350
1369
1351
1370
def _push_processed_stack_frame (self , frame : str ):
@@ -2126,9 +2145,14 @@ def route(
2126
2145
openapi_extensions : dict [str , Any ] | None = None ,
2127
2146
deprecated : bool = False ,
2128
2147
middlewares : list [Callable [..., Any ]] | None = None ,
2148
+ custom_response_validation_http_code : int | HTTPStatus | None = None ,
2129
2149
) -> Callable [[AnyCallableT ], AnyCallableT ]:
2130
2150
"""Route decorator includes parameter `method`"""
2131
2151
2152
+ custom_response_validation_http_code = self ._validate_route_response_validation_error_http_code (
2153
+ custom_response_validation_http_code ,
2154
+ )
2155
+
2132
2156
def register_resolver (func : AnyCallableT ) -> AnyCallableT :
2133
2157
methods = (method ,) if isinstance (method , str ) else method
2134
2158
logger .debug (f"Adding route using rule { rule } and methods: { ',' .join (m .upper () for m in methods )} " )
@@ -2155,6 +2179,7 @@ def register_resolver(func: AnyCallableT) -> AnyCallableT:
2155
2179
openapi_extensions ,
2156
2180
deprecated ,
2157
2181
middlewares ,
2182
+ custom_response_validation_http_code ,
2158
2183
)
2159
2184
2160
2185
# The more specific route wins.
@@ -2523,15 +2548,20 @@ def _call_exception_handler(self, exp: Exception, route: Route) -> ResponseBuild
2523
2548
)
2524
2549
2525
2550
# OpenAPIValidationMiddleware will only raise ResponseValidationError when
2526
- # 'self._response_validation_error_http_code' is not None
2551
+ # 'self._response_validation_error_http_code' is not None or
2552
+ # when route has custom_response_validation_http_code
2527
2553
if isinstance (exp , ResponseValidationError ):
2528
- http_code = self ._response_validation_error_http_code
2554
+ http_code = (
2555
+ self ._response_validation_error_http_code
2556
+ if exp .source == "app"
2557
+ else route .custom_response_validation_http_code
2558
+ )
2529
2559
errors = [{"loc" : e ["loc" ], "type" : e ["type" ]} for e in exp .errors ()]
2530
2560
return self ._response_builder_class (
2531
2561
response = Response (
2532
2562
status_code = http_code .value ,
2533
2563
content_type = content_types .APPLICATION_JSON ,
2534
- body = {"statusCode" : self . _response_validation_error_http_code , "detail" : errors },
2564
+ body = {"statusCode" : http_code , "detail" : errors },
2535
2565
),
2536
2566
serializer = self ._serializer ,
2537
2567
route = route ,
@@ -2683,6 +2713,7 @@ def route(
2683
2713
openapi_extensions : dict [str , Any ] | None = None ,
2684
2714
deprecated : bool = False ,
2685
2715
middlewares : list [Callable [..., Any ]] | None = None ,
2716
+ custom_response_validation_http_code : int | HTTPStatus | None = None ,
2686
2717
) -> Callable [[AnyCallableT ], AnyCallableT ]:
2687
2718
def register_route (func : AnyCallableT ) -> AnyCallableT :
2688
2719
# All dict keys needs to be hashable. So we'll need to do some conversions:
@@ -2708,6 +2739,7 @@ def register_route(func: AnyCallableT) -> AnyCallableT:
2708
2739
frozen_security ,
2709
2740
frozen_openapi_extensions ,
2710
2741
deprecated ,
2742
+ custom_response_validation_http_code ,
2711
2743
)
2712
2744
2713
2745
# Collate Middleware for routes
@@ -2795,6 +2827,7 @@ def route(
2795
2827
openapi_extensions : dict [str , Any ] | None = None ,
2796
2828
deprecated : bool = False ,
2797
2829
middlewares : list [Callable [..., Any ]] | None = None ,
2830
+ custom_response_validation_http_code : int | HTTPStatus | None = None ,
2798
2831
) -> Callable [[AnyCallableT ], AnyCallableT ]:
2799
2832
# NOTE: see #1552 for more context.
2800
2833
return super ().route (
@@ -2814,6 +2847,7 @@ def route(
2814
2847
openapi_extensions ,
2815
2848
deprecated ,
2816
2849
middlewares ,
2850
+ custom_response_validation_http_code ,
2817
2851
)
2818
2852
2819
2853
# Override _compile_regex to exclude trailing slashes for route resolution
0 commit comments