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 .apispec_base import ResourceClassesFilter
1617from renku_data_services .crc .db import ResourcePoolRepository , UserRepository
@@ -34,9 +35,7 @@ def get_all(self) -> BlueprintFactoryResponse:
3435 async def _get_all (request : Request , user : base_models .APIUser ) -> HTTPResponse :
3536 res_filter = ResourceClassesFilter .model_validate (dict (request .query_args ))
3637 rps = await self .rp_repo .filter_resource_pools (api_user = user , ** res_filter .dict ())
37- return json (
38- [apispec .ResourcePoolWithIdFiltered .model_validate (r ).model_dump (exclude_none = True ) for r in rps ]
39- )
38+ return validated_json (apispec .ResourcePoolWithIdFiltered , rps )
4039
4140 return "/resource_pools" , ["GET" ], _get_all
4241
@@ -49,7 +48,7 @@ def post(self) -> BlueprintFactoryResponse:
4948 async def _post (_ : Request , user : base_models .APIUser , body : apispec .ResourcePool ) -> HTTPResponse :
5049 rp = models .ResourcePool .from_dict (body .model_dump (exclude_none = True ))
5150 res = await self .rp_repo .insert_resource_pool (api_user = user , resource_pool = rp )
52- return json (apispec .ResourcePoolWithId . model_validate ( res ). model_dump ( exclude_none = True ), 201 )
51+ return validated_json (apispec .ResourcePoolWithId , res , status = 201 )
5352
5453 return "/resource_pools" , ["POST" ], _post
5554
@@ -68,7 +67,7 @@ async def _get_one(request: Request, user: base_models.APIUser, resource_pool_id
6867 message = f"The resource pool with id { resource_pool_id } cannot be found."
6968 )
7069 rp = rps [0 ]
71- return json (apispec .ResourcePoolWithId . model_validate ( rp ). model_dump ( exclude_none = True ) )
70+ return validated_json (apispec .ResourcePoolWithId , rp )
7271
7372 return "/resource_pools/<resource_pool_id>" , ["GET" ], _get_one
7473
@@ -103,7 +102,7 @@ async def _put(
103102 raise errors .MissingResourceError (
104103 message = f"The resource pool with ID { resource_pool_id } cannot be found."
105104 )
106- return json (apispec .ResourcePoolWithId . model_validate ( res ). model_dump ( exclude_none = True ) )
105+ return validated_json (apispec .ResourcePoolWithId , res )
107106
108107 return "/resource_pools/<resource_pool_id>" , ["PUT" ], _put
109108
@@ -126,7 +125,7 @@ async def _patch(
126125 raise errors .MissingResourceError (
127126 message = f"The resource pool with ID { resource_pool_id } cannot be found."
128127 )
129- return json (apispec .ResourcePoolWithId . model_validate ( res ). model_dump ( exclude_none = True ) )
128+ return validated_json (apispec .ResourcePoolWithId , res )
130129
131130 return "/resource_pools/<resource_pool_id>" , ["PATCH" ], _patch
132131
@@ -147,13 +146,9 @@ def get_all(self) -> BlueprintFactoryResponse:
147146 @validate_db_ids
148147 async def _get_all (_ : Request , user : base_models .APIUser , resource_pool_id : int ) -> HTTPResponse :
149148 res = await self .repo .get_resource_pool_users (api_user = user , resource_pool_id = resource_pool_id )
150- return json (
151- [
152- apispec .PoolUserWithId (id = r .keycloak_id , no_default_access = r .no_default_access ).model_dump (
153- exclude_none = True
154- )
155- for r in res .allowed
156- ]
149+ return validated_json (
150+ apispec .PoolUserWithId ,
151+ [dict (id = r .keycloak_id , no_default_access = r .no_default_access ) for r in res .allowed ],
157152 )
158153
159154 return "/resource_pools/<resource_pool_id>/users" , ["GET" ], _get_all
@@ -199,13 +194,9 @@ async def _put_post(
199194 user_ids = user_ids_to_add ,
200195 append = post ,
201196 )
202- return json (
203- [
204- apispec .PoolUserWithId (id = r .keycloak_id , no_default_access = r .no_default_access ).model_dump (
205- exclude_none = True
206- )
207- for r in updated_users
208- ],
197+ return validated_json (
198+ apispec .PoolUserWithId ,
199+ [dict (id = r .keycloak_id , no_default_access = r .no_default_access ) for r in updated_users ],
209200 status = 201 if post else 200 ,
210201 )
211202
@@ -219,10 +210,9 @@ async def _get(_: Request, user: base_models.APIUser, resource_pool_id: int, use
219210 keycloak_id = user_id , resource_pool_id = resource_pool_id , api_user = user
220211 )
221212 if len (res .allowed ) > 0 :
222- return json (
223- apispec .PoolUserWithId (
224- id = res .allowed [0 ].keycloak_id , no_default_access = res .allowed [0 ].no_default_access
225- ).model_dump (exclude_none = True )
213+ return validated_json (
214+ apispec .PoolUserWithId ,
215+ dict (id = res .allowed [0 ].keycloak_id , no_default_access = res .allowed [0 ].no_default_access ),
226216 )
227217 raise errors .MissingResourceError (
228218 message = f"The user with id { user_id } or resource pool with id { resource_pool_id } cannot be found."
@@ -275,7 +265,7 @@ async def _get_all(request: Request, user: base_models.APIUser, resource_pool_id
275265 res = await self .repo .get_classes (
276266 api_user = user , resource_pool_id = resource_pool_id , name = request .args .get ("name" )
277267 )
278- return json ([ apispec .ResourceClassWithId . model_validate ( r ). model_dump ( exclude_none = True ) for r in res ] )
268+ return validated_json ( apispec .ResourceClassWithId , res )
279269
280270 return "/resource_pools/<resource_pool_id>/classes" , ["GET" ], _get_all
281271
@@ -293,7 +283,7 @@ async def _post(
293283 res = await self .repo .insert_resource_class (
294284 api_user = user , resource_class = cls , resource_pool_id = resource_pool_id
295285 )
296- return json (apispec .ResourceClassWithId . model_validate ( res ). model_dump ( exclude_none = True ) , 201 )
286+ return validated_json (apispec .ResourceClassWithId , res , 201 )
297287
298288 return "/resource_pools/<resource_pool_id>/classes" , ["POST" ], _post
299289
@@ -308,7 +298,7 @@ async def _get(_: Request, user: base_models.APIUser, resource_pool_id: int, cla
308298 raise errors .MissingResourceError (
309299 message = f"The class with id { class_id } or resource pool with id { resource_pool_id } cannot be found."
310300 )
311- return json (apispec .ResourceClassWithId . model_validate ( res [0 ]). model_dump ( exclude_none = True ) )
301+ return validated_json (apispec .ResourceClassWithId , res [0 ])
312302
313303 return "/resource_pools/<resource_pool_id>/classes/<class_id>" , ["GET" ], _get
314304
@@ -320,7 +310,7 @@ async def _get_no_pool(_: Request, class_id: int) -> HTTPResponse:
320310 res = await self .repo .get_classes (api_user = None , id = class_id )
321311 if len (res ) < 1 :
322312 raise errors .MissingResourceError (message = f"The class with id { class_id } cannot be found." )
323- return json (apispec .ResourceClassWithId . model_validate ( res [0 ]). model_dump ( exclude_none = True ) )
313+ return validated_json (apispec .ResourceClassWithId , res [0 ])
324314
325315 return "/classes/<class_id>" , ["GET" ], _get_no_pool
326316
@@ -343,14 +333,15 @@ def put(self) -> BlueprintFactoryResponse:
343333
344334 @authenticate (self .authenticator )
345335 @only_admins
336+ @validate_db_ids
346337 @validate (json = apispec .ResourceClass )
347338 async def _put (
348339 _ : Request , user : base_models .APIUser , body : apispec .ResourceClass , resource_pool_id : int , class_id : int
349340 ) -> HTTPResponse :
350341 res = await self .repo .update_resource_class (
351342 user , resource_pool_id , class_id , put = True , ** body .model_dump (exclude_none = True )
352343 )
353- return json (apispec .ResourceClassWithId . model_validate ( res ). model_dump ( exclude_none = True ) )
344+ return validated_json (apispec .ResourceClassWithId , res )
354345
355346 return "/resource_pools/<resource_pool_id>/classes/<class_id>" , ["PUT" ], _put
356347
@@ -359,6 +350,7 @@ def patch(self) -> BlueprintFactoryResponse:
359350
360351 @authenticate (self .authenticator )
361352 @only_admins
353+ @validate_db_ids
362354 @validate (json = apispec .ResourceClassPatch )
363355 async def _patch (
364356 _ : Request ,
@@ -370,7 +362,7 @@ async def _patch(
370362 res = await self .repo .update_resource_class (
371363 user , resource_pool_id , class_id , put = False , ** body .model_dump (exclude_none = True )
372364 )
373- return json (apispec .ResourceClassWithId . model_validate ( res ). model_dump ( exclude_none = True ) )
365+ return validated_json (apispec .ResourceClassWithId , res )
374366
375367 return "/resource_pools/<resource_pool_id>/classes/<class_id>" , ["PATCH" ], _patch
376368
@@ -379,6 +371,7 @@ def get_tolerations(self) -> BlueprintFactoryResponse:
379371
380372 @authenticate (self .authenticator )
381373 @only_admins
374+ @validate_db_ids
382375 async def _get_tolerations (
383376 _ : Request , user : base_models .APIUser , resource_pool_id : int , class_id : int
384377 ) -> HTTPResponse :
@@ -392,6 +385,7 @@ def delete_tolerations(self) -> BlueprintFactoryResponse:
392385
393386 @authenticate (self .authenticator )
394387 @only_admins
388+ @validate_db_ids
395389 async def _delete_tolerations (
396390 _ : Request , user : base_models .APIUser , resource_pool_id : int , class_id : int
397391 ) -> HTTPResponse :
@@ -405,11 +399,12 @@ def get_affinities(self) -> BlueprintFactoryResponse:
405399
406400 @authenticate (self .authenticator )
407401 @only_admins
402+ @validate_db_ids
408403 async def _get_affinities (
409404 _ : Request , user : base_models .APIUser , resource_pool_id : int , class_id : int
410405 ) -> HTTPResponse :
411406 res = await self .repo .get_affinities (user , resource_pool_id , class_id )
412- return json ([ apispec .NodeAffinity . model_validate ( i ). model_dump ( exclude_none = True ) for i in res ] )
407+ return validated_json ( apispec .NodeAffinity , res )
413408
414409 return "/resource_pools/<resource_pool_id>/classes/<class_id>/node_affinities" , ["GET" ], _get_affinities
415410
@@ -418,6 +413,7 @@ def delete_affinities(self) -> BlueprintFactoryResponse:
418413
419414 @authenticate (self .authenticator )
420415 @only_admins
416+ @validate_db_ids
421417 async def _delete_affinities (
422418 _ : Request , user : base_models .APIUser , resource_pool_id : int , class_id : int
423419 ) -> HTTPResponse :
@@ -451,7 +447,7 @@ async def _get(_: Request, user: base_models.APIUser, resource_pool_id: int) ->
451447 raise errors .MissingResourceError (
452448 message = f"The resource pool with ID { resource_pool_id } does not have a quota."
453449 )
454- return json (apispec .QuotaWithId . model_validate ( rp .quota ). model_dump ( exclude_none = True ) )
450+ return validated_json (apispec .QuotaWithId , rp .quota )
455451
456452 return "/resource_pools/<resource_pool_id>/quota" , ["GET" ], _get
457453
@@ -460,6 +456,7 @@ def put(self) -> BlueprintFactoryResponse:
460456
461457 @authenticate (self .authenticator )
462458 @only_admins
459+ @validate_db_ids
463460 @validate (json = apispec .QuotaWithId )
464461 async def _put (
465462 _ : Request , user : base_models .APIUser , resource_pool_id : int , body : apispec .QuotaWithId
@@ -473,6 +470,7 @@ def patch(self) -> BlueprintFactoryResponse:
473470
474471 @authenticate (self .authenticator )
475472 @only_admins
473+ @validate_db_ids
476474 @validate (json = apispec .QuotaPatch )
477475 async def _patch (
478476 _ : Request , user : base_models .APIUser , resource_pool_id : int , body : apispec .QuotaPatch
@@ -500,7 +498,7 @@ async def _put_patch(
500498 message = f"The quota { new_quota } is not compatible with the resource class { rc } ."
501499 )
502500 new_quota = self .quota_repo .update_quota (new_quota )
503- return json (apispec .QuotaWithId . model_validate ( new_quota ). model_dump ( exclude_none = True ) )
501+ return validated_json (apispec .QuotaWithId , new_quota )
504502
505503
506504@dataclass (kw_only = True )
@@ -518,7 +516,7 @@ def get(self) -> BlueprintFactoryResponse:
518516 @only_admins
519517 async def _get (_ : Request , user : base_models .APIUser , user_id : str ) -> HTTPResponse :
520518 rps = await self .repo .get_user_resource_pools (keycloak_id = user_id , api_user = user )
521- return json ([ apispec .ResourcePoolWithId . model_validate ( rp ). model_dump ( exclude_none = True ) for rp in rps ] )
519+ return validated_json ( apispec .ResourcePoolWithId , rps )
522520
523521 return "/users/<user_id>/resource_pools" , ["GET" ], _get
524522
@@ -553,7 +551,8 @@ async def _post_put(
553551 rps = await self .repo .update_user_resource_pools (
554552 keycloak_id = user_id , resource_pool_ids = resource_pool_ids .root , append = post , api_user = api_user
555553 )
556- return json (
557- [apispec .ResourcePoolWithId .model_validate (rp ).model_dump (exclude_none = True ) for rp in rps ],
554+ return validated_json (
555+ apispec .ResourcePoolWithId ,
556+ rps ,
558557 status = 201 if post else 200 ,
559558 )
0 commit comments