4
4
- Shall be used as entry point for all the queries to the database regarding projects
5
5
6
6
"""
7
-
7
+ import asyncio
8
8
import logging
9
9
import textwrap
10
10
import uuid as uuidlib
22
22
from aiopg .sa .connection import SAConnection
23
23
from aiopg .sa .result import ResultProxy , RowProxy
24
24
from change_case import ChangeCase
25
+ from jsonschema .exceptions import ValidationError
26
+ from models_library .projects import ProjectAtDB
25
27
from servicelib .application_keys import APP_DB_ENGINE_KEY
26
28
from simcore_postgres_database .webserver_models import ProjectType , projects
27
29
from sqlalchemy import literal_column
37
39
ProjectsException ,
38
40
)
39
41
from .projects_fakes import Fake
42
+ from .projects_utils import project_uses_available_services
40
43
41
44
log = logging .getLogger (__name__ )
42
45
@@ -307,7 +310,11 @@ async def add_project(
307
310
prj ["tags" ] = []
308
311
return prj
309
312
310
- async def load_user_projects (self , user_id : int ) -> List [Dict ]:
313
+ async def load_user_projects (
314
+ self ,
315
+ user_id : int ,
316
+ filter_by_services : Optional [List [Dict ]] = None ,
317
+ ) -> List [Dict ]:
311
318
log .info ("Loading projects for user %s" , user_id )
312
319
async with self .engine .acquire () as conn :
313
320
user_groups : List [RowProxy ] = await self .__load_user_groups (conn , user_id )
@@ -330,13 +337,17 @@ async def load_user_projects(self, user_id: int) -> List[Dict]:
330
337
"""
331
338
)
332
339
projects_list = await self .__load_projects (
333
- conn , query , user_id , user_groups
340
+ conn , query , user_id , user_groups , filter_by_services = filter_by_services
334
341
)
335
342
336
343
return projects_list
337
344
338
345
async def load_template_projects (
339
- self , user_id : int , * , only_published = False
346
+ self ,
347
+ user_id : int ,
348
+ * ,
349
+ only_published = False ,
350
+ filter_by_services : Optional [List [Dict ]] = None ,
340
351
) -> List [Dict ]:
341
352
log .info ("Loading public template projects" )
342
353
@@ -358,7 +369,9 @@ async def load_template_projects(
358
369
"""
359
370
)
360
371
361
- db_projects = await self .__load_projects (conn , query , user_id , user_groups )
372
+ db_projects = await self .__load_projects (
373
+ conn , query , user_id , user_groups , filter_by_services
374
+ )
362
375
363
376
projects_list .extend (db_projects )
364
377
@@ -378,7 +391,12 @@ async def __load_user_groups(
378
391
return user_groups
379
392
380
393
async def __load_projects (
381
- self , conn : SAConnection , query : str , user_id : int , user_groups : List [RowProxy ]
394
+ self ,
395
+ conn : SAConnection ,
396
+ query : str ,
397
+ user_id : int ,
398
+ user_groups : List [RowProxy ],
399
+ filter_by_services : Optional [List [Dict ]] = None ,
382
400
) -> List [Dict ]:
383
401
api_projects : List [Dict ] = [] # API model-compatible projects
384
402
db_projects : List [Dict ] = [] # DB model-compatible projects
@@ -387,7 +405,21 @@ async def __load_projects(
387
405
_check_project_permissions (row , user_id , user_groups , "read" )
388
406
except ProjectInvalidRightsError :
389
407
continue
408
+ try :
409
+ import concurrent .futures
410
+
411
+ with concurrent .futures .ThreadPoolExecutor () as pool :
412
+ await asyncio .get_event_loop ().run_in_executor (
413
+ pool , ProjectAtDB .from_orm , row
414
+ )
415
+ # ProjectAtDB.from_orm(row)
416
+ except ValidationError as exc :
417
+ log .warning ("project failed validation: %s" , exc )
418
+ continue
390
419
prj = dict (row .items ())
420
+ if filter_by_services :
421
+ if not await project_uses_available_services (prj , filter_by_services ):
422
+ continue
391
423
db_projects .append (prj )
392
424
393
425
# NOTE: DO NOT nest _get_tags_by_project in async loop above !!!
0 commit comments