2525# Whitelist of allowed sort params. Never pass raw user input to the ORM.
2626ALLOWED_RUN_SORTS = frozenset ([
2727 'created_at' , '-created_at' ,
28- 'started_at' , '-started_at' ,
2928 'run_id' , '-run_id' ,
3029])
3130
3231
3332def validate_body (schema_class ):
34- """Validate the JSON body with a Marshmallow schema, pass result as ``validated_data``."""
33+ """Validate the JSON body with a schema, pass result as ``validated_data``."""
3534 def decorator (f ):
3635 @wraps (f )
3736 def decorated (* args , ** kwargs ):
@@ -66,7 +65,7 @@ def decorated(*args, **kwargs):
6665
6766
6867def validate_pagination (f ):
69- """Extract and validate ``limit`` (1-100) and ``offset`` (>= 0) query params."""
68+ """Extract and validate ``limit`` and ``offset`` query params."""
7069 @wraps (f )
7170 def decorated (* args , ** kwargs ):
7271 try :
@@ -75,7 +74,9 @@ def decorated(*args, **kwargs):
7574 return make_error_response (
7675 'validation_error' ,
7776 'limit must be an integer.' ,
78- details = {'fields' : {'limit' : 'Must be an integer between 1 and 100.' }},
77+ details = {
78+ 'fields' : {
79+ 'limit' : 'Must be an integer between 1 and 100.' }},
7980 http_status = 400 ,
8081 )
8182
@@ -85,7 +86,9 @@ def decorated(*args, **kwargs):
8586 return make_error_response (
8687 'validation_error' ,
8788 'offset must be a non-negative integer.' ,
88- details = {'fields' : {'offset' : 'Must be a non-negative integer.' }},
89+ details = {
90+ 'fields' : {
91+ 'offset' : 'Must be a non-negative integer.' }},
8992 http_status = 400 ,
9093 )
9194
@@ -123,14 +126,20 @@ def decorated(*args, **kwargs):
123126 return make_error_response (
124127 'validation_error' ,
125128 f'{ param_name } must be a positive integer.' ,
126- details = {'fields' : {param_name : 'Must be a positive integer.' }},
129+ details = {
130+ 'fields' : {
131+ param_name : 'Must be a positive integer.' }},
127132 http_status = 400 ,
128133 )
129134 if int_value < 1 :
130135 return make_error_response (
131136 'validation_error' ,
132137 f'{ param_name } must be >= 1.' ,
133- details = {'fields' : {param_name : 'Must be >= 1. Zero and negative IDs are rejected.' }},
138+ details = {
139+ 'fields' : {
140+ param_name : 'Must be >= 1. Zero and negative IDs are rejected.'
141+ }
142+ },
134143 http_status = 400 ,
135144 )
136145 kwargs [param_name ] = int_value
@@ -140,7 +149,7 @@ def decorated(*args, **kwargs):
140149
141150
142151def validate_date_range (f ):
143- """Parse ``created_after``/``created_before`` query params and reject inverted ranges."""
152+ """Parse date query params and reject inverted ranges."""
144153 @wraps (f )
145154 def decorated (* args , ** kwargs ):
146155 from datetime import datetime
@@ -152,23 +161,29 @@ def decorated(*args, **kwargs):
152161
153162 if created_after_str :
154163 try :
155- created_after = datetime .fromisoformat (created_after_str .replace ('Z' , '+00:00' ))
164+ created_after = datetime .fromisoformat (
165+ created_after_str .replace ('Z' , '+00:00' ))
156166 except ValueError :
157167 return make_error_response (
158168 'validation_error' ,
159169 'created_after must be a valid ISO 8601 datetime.' ,
160- details = {'fields' : {'created_after' : 'Invalid ISO 8601 format.' }},
170+ details = {
171+ 'fields' : {
172+ 'created_after' : 'Invalid ISO 8601 format.' }},
161173 http_status = 400 ,
162174 )
163175
164176 if created_before_str :
165177 try :
166- created_before = datetime .fromisoformat (created_before_str .replace ('Z' , '+00:00' ))
178+ created_before = datetime .fromisoformat (
179+ created_before_str .replace ('Z' , '+00:00' ))
167180 except ValueError :
168181 return make_error_response (
169182 'validation_error' ,
170183 'created_before must be a valid ISO 8601 datetime.' ,
171- details = {'fields' : {'created_before' : 'Invalid ISO 8601 format.' }},
184+ details = {
185+ 'fields' : {
186+ 'created_before' : 'Invalid ISO 8601 format.' }},
172187 http_status = 400 ,
173188 )
174189
@@ -202,7 +217,10 @@ def decorated(*args, **kwargs):
202217 return make_error_response (
203218 'validation_error' ,
204219 f'sort must be one of: { ", " .join (sorted (allowed ))} ' ,
205- details = {'fields' : {'sort' : f'Must be one of: { sorted (allowed )} ' }},
220+ details = {
221+ 'fields' : {
222+ 'sort' : f'Must be one of: {
223+ sorted (allowed )} ' }},
206224 http_status = 400 ,
207225 )
208226 kwargs ['sort' ] = sort
0 commit comments