1111from renku_data_services .base_api .auth import authenticate , only_admins
1212from renku_data_services .base_api .blueprint import BlueprintFactoryResponse , CustomBlueprint
1313from renku_data_services .base_api .misc import validate_db_ids
14+ from renku_data_services .base_models .validation import validated_json
1415from renku_data_services .crc import apispec , models
1516from renku_data_services .crc .db import ResourcePoolRepository , UserRepository
1617from renku_data_services .k8s .quota import QuotaRepository
@@ -35,9 +36,7 @@ async def _get_all(
3536 request : Request , user : base_models .APIUser , query : apispec .ResourcePoolsParams
3637 ) -> HTTPResponse :
3738 rps = await self .rp_repo .filter_resource_pools (api_user = user , ** query .model_dump ())
38- return json (
39- [apispec .ResourcePoolWithIdFiltered .model_validate (r ).model_dump (exclude_none = True ) for r in rps ]
40- )
39+ return validated_json (apispec .ResourcePoolWithIdFiltered , rps )
4140
4241 return "/resource_pools" , ["GET" ], _get_all
4342
@@ -50,7 +49,7 @@ def post(self) -> BlueprintFactoryResponse:
5049 async def _post (_ : Request , user : base_models .APIUser , body : apispec .ResourcePool ) -> HTTPResponse :
5150 rp = models .ResourcePool .from_dict (body .model_dump (exclude_none = True ))
5251 res = await self .rp_repo .insert_resource_pool (api_user = user , resource_pool = rp )
53- return json (apispec .ResourcePoolWithId . model_validate ( res ). model_dump ( exclude_none = True ), 201 )
52+ return validated_json (apispec .ResourcePoolWithId , res , status = 201 )
5453
5554 return "/resource_pools" , ["POST" ], _post
5655
@@ -70,7 +69,7 @@ async def _get_one(
7069 message = f"The resource pool with id { resource_pool_id } cannot be found."
7170 )
7271 rp = rps [0 ]
73- return json (apispec .ResourcePoolWithId . model_validate ( rp ). model_dump ( exclude_none = True ) )
72+ return validated_json (apispec .ResourcePoolWithId , rp )
7473
7574 return "/resource_pools/<resource_pool_id>" , ["GET" ], _get_one
7675
@@ -105,7 +104,7 @@ async def _put(
105104 raise errors .MissingResourceError (
106105 message = f"The resource pool with ID { resource_pool_id } cannot be found."
107106 )
108- return json (apispec .ResourcePoolWithId . model_validate ( res ). model_dump ( exclude_none = True ) )
107+ return validated_json (apispec .ResourcePoolWithId , res )
109108
110109 return "/resource_pools/<resource_pool_id>" , ["PUT" ], _put
111110
@@ -128,7 +127,7 @@ async def _patch(
128127 raise errors .MissingResourceError (
129128 message = f"The resource pool with ID { resource_pool_id } cannot be found."
130129 )
131- return json (apispec .ResourcePoolWithId . model_validate ( res ). model_dump ( exclude_none = True ) )
130+ return validated_json (apispec .ResourcePoolWithId , res )
132131
133132 return "/resource_pools/<resource_pool_id>" , ["PATCH" ], _patch
134133
@@ -149,13 +148,9 @@ def get_all(self) -> BlueprintFactoryResponse:
149148 @validate_db_ids
150149 async def _get_all (_ : Request , user : base_models .APIUser , resource_pool_id : int ) -> HTTPResponse :
151150 res = await self .repo .get_resource_pool_users (api_user = user , resource_pool_id = resource_pool_id )
152- return json (
153- [
154- apispec .PoolUserWithId (id = r .keycloak_id , no_default_access = r .no_default_access ).model_dump (
155- exclude_none = True
156- )
157- for r in res .allowed
158- ]
151+ return validated_json (
152+ apispec .PoolUserWithId ,
153+ [dict (id = r .keycloak_id , no_default_access = r .no_default_access ) for r in res .allowed ],
159154 )
160155
161156 return "/resource_pools/<resource_pool_id>/users" , ["GET" ], _get_all
@@ -201,13 +196,9 @@ async def _put_post(
201196 user_ids = user_ids_to_add ,
202197 append = post ,
203198 )
204- return json (
205- [
206- apispec .PoolUserWithId (id = r .keycloak_id , no_default_access = r .no_default_access ).model_dump (
207- exclude_none = True
208- )
209- for r in updated_users
210- ],
199+ return validated_json (
200+ apispec .PoolUserWithId ,
201+ [dict (id = r .keycloak_id , no_default_access = r .no_default_access ) for r in updated_users ],
211202 status = 201 if post else 200 ,
212203 )
213204
@@ -221,10 +212,9 @@ async def _get(_: Request, user: base_models.APIUser, resource_pool_id: int, use
221212 keycloak_id = user_id , resource_pool_id = resource_pool_id , api_user = user
222213 )
223214 if len (res .allowed ) > 0 :
224- return json (
225- apispec .PoolUserWithId (
226- id = res .allowed [0 ].keycloak_id , no_default_access = res .allowed [0 ].no_default_access
227- ).model_dump (exclude_none = True )
215+ return validated_json (
216+ apispec .PoolUserWithId ,
217+ dict (id = res .allowed [0 ].keycloak_id , no_default_access = res .allowed [0 ].no_default_access ),
228218 )
229219 raise errors .MissingResourceError (
230220 message = f"The user with id { user_id } or resource pool with id { resource_pool_id } cannot be found."
@@ -278,7 +268,7 @@ async def _get_all(
278268 request : Request , user : base_models .APIUser , resource_pool_id : int , query : apispec .ResourceClassParams
279269 ) -> HTTPResponse :
280270 res = await self .repo .get_classes (api_user = user , resource_pool_id = resource_pool_id , name = query .name )
281- return json ([ apispec .ResourceClassWithId . model_validate ( r ). model_dump ( exclude_none = True ) for r in res ] )
271+ return validated_json ( apispec .ResourceClassWithId , res )
282272
283273 return "/resource_pools/<resource_pool_id>/classes" , ["GET" ], _get_all
284274
@@ -296,7 +286,7 @@ async def _post(
296286 res = await self .repo .insert_resource_class (
297287 api_user = user , resource_class = cls , resource_pool_id = resource_pool_id
298288 )
299- return json (apispec .ResourceClassWithId . model_validate ( res ). model_dump ( exclude_none = True ) , 201 )
289+ return validated_json (apispec .ResourceClassWithId , res , 201 )
300290
301291 return "/resource_pools/<resource_pool_id>/classes" , ["POST" ], _post
302292
@@ -311,7 +301,7 @@ async def _get(_: Request, user: base_models.APIUser, resource_pool_id: int, cla
311301 raise errors .MissingResourceError (
312302 message = f"The class with id { class_id } or resource pool with id { resource_pool_id } cannot be found."
313303 )
314- return json (apispec .ResourceClassWithId . model_validate ( res [0 ]). model_dump ( exclude_none = True ) )
304+ return validated_json (apispec .ResourceClassWithId , res [0 ])
315305
316306 return "/resource_pools/<resource_pool_id>/classes/<class_id>" , ["GET" ], _get
317307
@@ -323,7 +313,7 @@ async def _get_no_pool(_: Request, class_id: int) -> HTTPResponse:
323313 res = await self .repo .get_classes (api_user = None , id = class_id )
324314 if len (res ) < 1 :
325315 raise errors .MissingResourceError (message = f"The class with id { class_id } cannot be found." )
326- return json (apispec .ResourceClassWithId . model_validate ( res [0 ]). model_dump ( exclude_none = True ) )
316+ return validated_json (apispec .ResourceClassWithId , res [0 ])
327317
328318 return "/classes/<class_id>" , ["GET" ], _get_no_pool
329319
@@ -346,14 +336,15 @@ def put(self) -> BlueprintFactoryResponse:
346336
347337 @authenticate (self .authenticator )
348338 @only_admins
339+ @validate_db_ids
349340 @validate (json = apispec .ResourceClass )
350341 async def _put (
351342 _ : Request , user : base_models .APIUser , body : apispec .ResourceClass , resource_pool_id : int , class_id : int
352343 ) -> HTTPResponse :
353344 res = await self .repo .update_resource_class (
354345 user , resource_pool_id , class_id , put = True , ** body .model_dump (exclude_none = True )
355346 )
356- return json (apispec .ResourceClassWithId . model_validate ( res ). model_dump ( exclude_none = True ) )
347+ return validated_json (apispec .ResourceClassWithId , res )
357348
358349 return "/resource_pools/<resource_pool_id>/classes/<class_id>" , ["PUT" ], _put
359350
@@ -362,6 +353,7 @@ def patch(self) -> BlueprintFactoryResponse:
362353
363354 @authenticate (self .authenticator )
364355 @only_admins
356+ @validate_db_ids
365357 @validate (json = apispec .ResourceClassPatch )
366358 async def _patch (
367359 _ : Request ,
@@ -373,7 +365,7 @@ async def _patch(
373365 res = await self .repo .update_resource_class (
374366 user , resource_pool_id , class_id , put = False , ** body .model_dump (exclude_none = True )
375367 )
376- return json (apispec .ResourceClassWithId . model_validate ( res ). model_dump ( exclude_none = True ) )
368+ return validated_json (apispec .ResourceClassWithId , res )
377369
378370 return "/resource_pools/<resource_pool_id>/classes/<class_id>" , ["PATCH" ], _patch
379371
@@ -382,6 +374,7 @@ def get_tolerations(self) -> BlueprintFactoryResponse:
382374
383375 @authenticate (self .authenticator )
384376 @only_admins
377+ @validate_db_ids
385378 async def _get_tolerations (
386379 _ : Request , user : base_models .APIUser , resource_pool_id : int , class_id : int
387380 ) -> HTTPResponse :
@@ -395,6 +388,7 @@ def delete_tolerations(self) -> BlueprintFactoryResponse:
395388
396389 @authenticate (self .authenticator )
397390 @only_admins
391+ @validate_db_ids
398392 async def _delete_tolerations (
399393 _ : Request , user : base_models .APIUser , resource_pool_id : int , class_id : int
400394 ) -> HTTPResponse :
@@ -408,11 +402,12 @@ def get_affinities(self) -> BlueprintFactoryResponse:
408402
409403 @authenticate (self .authenticator )
410404 @only_admins
405+ @validate_db_ids
411406 async def _get_affinities (
412407 _ : Request , user : base_models .APIUser , resource_pool_id : int , class_id : int
413408 ) -> HTTPResponse :
414409 res = await self .repo .get_affinities (user , resource_pool_id , class_id )
415- return json ([ apispec .NodeAffinity . model_validate ( i ). model_dump ( exclude_none = True ) for i in res ] )
410+ return validated_json ( apispec .NodeAffinity , res )
416411
417412 return "/resource_pools/<resource_pool_id>/classes/<class_id>/node_affinities" , ["GET" ], _get_affinities
418413
@@ -421,6 +416,7 @@ def delete_affinities(self) -> BlueprintFactoryResponse:
421416
422417 @authenticate (self .authenticator )
423418 @only_admins
419+ @validate_db_ids
424420 async def _delete_affinities (
425421 _ : Request , user : base_models .APIUser , resource_pool_id : int , class_id : int
426422 ) -> HTTPResponse :
@@ -454,7 +450,7 @@ async def _get(_: Request, user: base_models.APIUser, resource_pool_id: int) ->
454450 raise errors .MissingResourceError (
455451 message = f"The resource pool with ID { resource_pool_id } does not have a quota."
456452 )
457- return json (apispec .QuotaWithId . model_validate ( rp .quota ). model_dump ( exclude_none = True ) )
453+ return validated_json (apispec .QuotaWithId , rp .quota )
458454
459455 return "/resource_pools/<resource_pool_id>/quota" , ["GET" ], _get
460456
@@ -463,6 +459,7 @@ def put(self) -> BlueprintFactoryResponse:
463459
464460 @authenticate (self .authenticator )
465461 @only_admins
462+ @validate_db_ids
466463 @validate (json = apispec .QuotaWithId )
467464 async def _put (
468465 _ : Request , user : base_models .APIUser , resource_pool_id : int , body : apispec .QuotaWithId
@@ -476,6 +473,7 @@ def patch(self) -> BlueprintFactoryResponse:
476473
477474 @authenticate (self .authenticator )
478475 @only_admins
476+ @validate_db_ids
479477 @validate (json = apispec .QuotaPatch )
480478 async def _patch (
481479 _ : Request , user : base_models .APIUser , resource_pool_id : int , body : apispec .QuotaPatch
@@ -503,7 +501,7 @@ async def _put_patch(
503501 message = f"The quota { new_quota } is not compatible with the resource class { rc } ."
504502 )
505503 new_quota = self .quota_repo .update_quota (new_quota )
506- return json (apispec .QuotaWithId . model_validate ( new_quota ). model_dump ( exclude_none = True ) )
504+ return validated_json (apispec .QuotaWithId , new_quota )
507505
508506
509507@dataclass (kw_only = True )
@@ -521,7 +519,7 @@ def get(self) -> BlueprintFactoryResponse:
521519 @only_admins
522520 async def _get (_ : Request , user : base_models .APIUser , user_id : str ) -> HTTPResponse :
523521 rps = await self .repo .get_user_resource_pools (keycloak_id = user_id , api_user = user )
524- return json ([ apispec .ResourcePoolWithId . model_validate ( rp ). model_dump ( exclude_none = True ) for rp in rps ] )
522+ return validated_json ( apispec .ResourcePoolWithId , rps )
525523
526524 return "/users/<user_id>/resource_pools" , ["GET" ], _get
527525
@@ -556,7 +554,8 @@ async def _post_put(
556554 rps = await self .repo .update_user_resource_pools (
557555 keycloak_id = user_id , resource_pool_ids = resource_pool_ids .root , append = post , api_user = api_user
558556 )
559- return json (
560- [apispec .ResourcePoolWithId .model_validate (rp ).model_dump (exclude_none = True ) for rp in rps ],
557+ return validated_json (
558+ apispec .ResourcePoolWithId ,
559+ rps ,
561560 status = 201 if post else 200 ,
562561 )
0 commit comments