From 1027d1886c63ca202529111727cc72869a14102b Mon Sep 17 00:00:00 2001 From: Abram Date: Tue, 24 Sep 2024 21:23:31 +0100 Subject: [PATCH] refactor (backend): update use of project_id for rbac --- .../agenta_backend/models/api/api_models.py | 4 + .../agenta_backend/routers/app_router.py | 51 ++--- .../agenta_backend/routers/bases_router.py | 3 +- .../agenta_backend/routers/configs_router.py | 23 +-- .../routers/container_router.py | 24 +-- .../routers/environment_router.py | 8 +- .../routers/evaluation_router.py | 60 +++--- .../routers/evaluators_router.py | 25 ++- .../routers/human_evaluation_router.py | 60 +++--- .../agenta_backend/routers/testset_router.py | 72 +++---- .../agenta_backend/routers/variants_router.py | 58 +++--- .../agenta_backend/services/app_manager.py | 25 +-- .../agenta_backend/services/db_manager.py | 190 +++++++----------- .../services/evaluation_service.py | 18 +- .../agenta_backend/tasks/evaluations.py | 15 +- 15 files changed, 278 insertions(+), 358 deletions(-) diff --git a/agenta-backend/agenta_backend/models/api/api_models.py b/agenta-backend/agenta_backend/models/api/api_models.py index df9dd1797..472734c9c 100644 --- a/agenta-backend/agenta_backend/models/api/api_models.py +++ b/agenta-backend/agenta_backend/models/api/api_models.py @@ -58,6 +58,8 @@ class VariantAction(BaseModel): class CreateApp(BaseModel): app_name: str + project_id: Optional[str] = None + workspace_id: Optional[str] = None class CreateAppOutput(BaseModel): @@ -239,6 +241,8 @@ class DockerEnvVars(BaseModel): class CreateAppVariant(BaseModel): app_name: str template_id: str + project_id: Optional[str] = None + workspace_id: Optional[str] = None env_vars: Dict[str, str] diff --git a/agenta-backend/agenta_backend/routers/app_router.py b/agenta-backend/agenta_backend/routers/app_router.py index ee38dfce4..e2885ac5a 100644 --- a/agenta-backend/agenta_backend/routers/app_router.py +++ b/agenta-backend/agenta_backend/routers/app_router.py @@ -102,10 +102,11 @@ async def list_app_variants( List[AppVariantResponse]: A list of app variants for the given app ID. """ try: + app = await db_manager.get_app_instance_by_id(app_id=app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.VIEW_APPLICATION, ) logger.debug(f"User has Permission to list app variants: {has_permission}") @@ -116,9 +117,7 @@ async def list_app_variants( status_code=403, ) - app_variants = await db_manager.list_app_variants( - app_id=app_id, project_id=request.state.project_id - ) + app_variants = await db_manager.list_app_variants(app_id=app_id) return [ await converters.app_variant_db_to_output(app_variant) for app_variant in app_variants @@ -156,10 +155,11 @@ async def get_variant_by_env( AppVariantResponse: The retrieved app variant. """ try: + app = await db_manager.get_app_instance_by_id(app_id=app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.VIEW_APPLICATION, ) logger.debug( @@ -231,7 +231,7 @@ async def create_app( has_permission = await check_rbac_permission( user_org_workspace_data=user_org_workspace_data, - project_id=request.state.project_id, + project_id=payload.project_id or request.state.project_id, permission=Permission.CREATE_APPLICATION, ) logger.debug( @@ -247,7 +247,9 @@ async def create_app( raise HTTPException(status_code=500, detail=str(e)) app_db = await db_manager.create_app_and_envs( - payload.app_name, request.state.project_id + payload.app_name, + project_id=payload.project_id or request.state.project_id, + workspace_id=payload.workspace_id, ) return CreateAppOutput(app_id=str(app_db.id), app_name=str(app_db.app_name)) except Exception as e: @@ -277,11 +279,11 @@ async def update_app( """ try: - app = await db_manager.fetch_app_by_id(app_id, request.state.project_id) + app = await db_manager.fetch_app_by_id(app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.EDIT_APPLICATION, ) logger.debug(f"User has Permission to update app: {has_permission}") @@ -369,12 +371,11 @@ async def add_variant_from_image( raise HTTPException(status_code=404, detail="Image not found") try: - app = await db_manager.fetch_app_by_id(app_id, request.state.project_id) - + app = await db_manager.fetch_app_by_id(app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.CREATE_APPLICATION, ) logger.debug( @@ -389,7 +390,7 @@ async def add_variant_from_image( variant_db = await app_manager.add_variant_based_on_image( app=app, - project_id=request.state.project_id, + project_id=str(app.project_id), variant_name=payload.variant_name, docker_id_or_template_uri=payload.docker_id, tags=payload.tags, @@ -398,13 +399,11 @@ async def add_variant_from_image( is_template_image=False, user_uid=request.state.user_id, ) - app_variant_db = await db_manager.fetch_app_variant_by_id( - str(variant_db.id), request.state.project_id - ) + app_variant_db = await db_manager.fetch_app_variant_by_id(str(variant_db.id)) logger.debug("Step 8: We create ready-to use evaluators") await evaluator_manager.create_ready_to_use_evaluators( - app_name=app.app_name, project_id=request.state.project_id + app_name=app.app_name, project_id=str(app.project_id) ) return await converters.app_variant_db_to_output(app_variant_db) @@ -424,12 +423,11 @@ async def remove_app( app -- App to remove """ try: - app = await db_manager.fetch_app_by_id(app_id, request.state.project_id) - + app = await db_manager.fetch_app_by_id(app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.DELETE_APPLICATION, ) logger.debug(f"User has Permission to delete app: {has_permission}") @@ -440,7 +438,7 @@ async def remove_app( status_code=403, ) - await app_manager.remove_app(app, request.state.project_id) + await app_manager.remove_app(app) except DockerException as e: detail = f"Docker error while trying to remove the app: {str(e)}" logger.exception(f"Docker error while trying to remove the app: {str(e)}") @@ -489,9 +487,12 @@ async def create_app_and_variant_from_template( ) logger.debug("Step 3: Checking user has permission to create app") + project = await db_manager_ee.get_project_by_workspace( + workspace_id=payload.workspace_id + ) has_permission = await check_rbac_permission( user_org_workspace_data=user_org_workspace_data, - project_id=request.state.project_id, + project_id=str(project.id), permission=Permission.CREATE_APPLICATION, ) logger.debug( @@ -512,7 +513,7 @@ async def create_app_and_variant_from_template( ) app_name = payload.app_name.lower() app = await db_manager.fetch_app_by_name_and_parameters( - app_name, request.state.project_id + app_name, payload.workspace_id ) if app is not None: raise Exception( @@ -526,7 +527,9 @@ async def create_app_and_variant_from_template( ) if app is None: app = await db_manager.create_app_and_envs( - app_name, request.state.project_id + app_name, + project_id=payload.project_id or request.state.project_id, + workspace_id=payload.workspace_id, ) logger.debug( diff --git a/agenta-backend/agenta_backend/routers/bases_router.py b/agenta-backend/agenta_backend/routers/bases_router.py index 936b84d4e..e698f9e6f 100644 --- a/agenta-backend/agenta_backend/routers/bases_router.py +++ b/agenta-backend/agenta_backend/routers/bases_router.py @@ -40,10 +40,11 @@ async def list_bases( HTTPException: If there was an error retrieving the bases. """ try: + app = await db_manager.fetch_app_by_id(app_id=app_id) if isCloudEE() and app_id is not None: has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_i), permission=Permission.VIEW_APPLICATION, ) if not has_permission: diff --git a/agenta-backend/agenta_backend/routers/configs_router.py b/agenta-backend/agenta_backend/routers/configs_router.py index 467fd72d5..e79cdb0c5 100644 --- a/agenta-backend/agenta_backend/routers/configs_router.py +++ b/agenta-backend/agenta_backend/routers/configs_router.py @@ -31,14 +31,12 @@ async def save_config( request: Request, ): try: - base_db = await db_manager.fetch_base_by_id( - payload.base_id, request.state.project_id - ) + base_db = await db_manager.fetch_base_by_id(payload.base_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(base_db.project_id), permission=Permission.MODIFY_VARIANT_CONFIGURATIONS, ) if not has_permission: @@ -50,7 +48,7 @@ async def save_config( ) variants_db = await db_manager.list_variants_for_base( - base_db, request.state.project_id + base_db, str(base_db.project_id) ) variant_to_overwrite = None for variant_db in variants_db: @@ -65,14 +63,14 @@ async def save_config( app_variant_id=str(variant_to_overwrite.id), parameters=payload.parameters, user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(base_db.project_id), ) logger.debug("Deploying to production environment") await db_manager.deploy_to_environment( environment_name="production", variant_id=str(variant_to_overwrite.id), - project_id=request.state.project_id, + project_id=str(base_db.project_id), user_uid=request.state.user_id, ) else: @@ -89,7 +87,7 @@ async def save_config( new_config_name=payload.config_name, parameters=payload.parameters, user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(base_db.project_id), ) except HTTPException as e: @@ -118,7 +116,7 @@ async def get_config( if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(base_db.project_id), permission=Permission.MODIFY_VARIANT_CONFIGURATIONS, ) if not has_permission: @@ -133,7 +131,6 @@ async def get_config( if environment_name: app_environments = await db_manager.list_environments( app_id=str(base_db.app_id), # type: ignore - project_id=request.state.project_id, ) found_variant_revision = next( ( @@ -160,9 +157,7 @@ async def get_config( "parameters": found_variant_revision.config_parameters, } elif config_name: - variants_db = await db_manager.list_variants_for_base( - base_db, request.state.project_id - ) + variants_db = await db_manager.list_variants_for_base(base_db) found_variant = next( ( variant_db @@ -261,7 +256,7 @@ async def revert_deployment_revision( if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(environment_revision.project_id), permission=Permission.EDIT_APP_ENVIRONMENT_DEPLOYMENT, ) if not has_permission: diff --git a/agenta-backend/agenta_backend/routers/container_router.py b/agenta-backend/agenta_backend/routers/container_router.py index 973463297..77fed296b 100644 --- a/agenta-backend/agenta_backend/routers/container_router.py +++ b/agenta-backend/agenta_backend/routers/container_router.py @@ -65,13 +65,11 @@ async def build_image( Image: The Docker image that was built. """ try: - app_db = await db_manager.fetch_app_by_id(app_id, request.state.project_id) - - # Check app access + app_db = await db_manager.fetch_app_by_id(app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app_db.project_id), permission=Permission.CREATE_APPLICATION, ) if not has_permission: @@ -105,12 +103,10 @@ async def restart_docker_container( """ logger.debug(f"Restarting container for variant {payload.variant_id}") - app_variant_db = await db_manager.fetch_app_variant_by_id( - payload.variant_id, request.state.project_id - ) + app_variant_db = await db_manager.fetch_app_variant_by_id(payload.variant_id) try: deployment = await db_manager.get_deployment_by_id( - app_variant_db.base.deployment, request.state.project_id + app_variant_db.base.deployment ) container_id = deployment.container_id @@ -166,7 +162,7 @@ async def construct_app_container_url( assert base_id or variant_id, "Please provide either base_id or variant_id" if base_id: - object_db = await db_manager.fetch_base_by_id(base_id, request.state.project_id) + object_db = await db_manager.fetch_base_by_id(base_id) elif variant_id and variant_id != "None": # NOTE: Backward Compatibility # --------------------------- @@ -177,9 +173,7 @@ async def construct_app_container_url( # This change ensures that users can still view their evaluations; however, # they will no longer be able to access a deployment URL for the deleted variant. # Therefore, we ensure that variant_id is not "None". - object_db = await db_manager.fetch_app_variant_by_id( - variant_id, request.state.project_id - ) + object_db = await db_manager.fetch_app_variant_by_id(variant_id) else: # NOTE: required for backward compatibility object_db = None @@ -188,7 +182,7 @@ async def construct_app_container_url( if isCloudEE() and object_db is not None: has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(object_db.project_id), permission=Permission.VIEW_APPLICATION, ) if not has_permission: @@ -199,11 +193,11 @@ async def construct_app_container_url( try: if getattr(object_db, "deployment_id", None): # this is a base deployment = await db_manager.get_deployment_by_id( - str(object_db.deployment_id), request.state.project_id # type: ignore + str(object_db.deployment_id) # type: ignore ) elif getattr(object_db, "base_id", None): # this is a variant deployment = await db_manager.get_deployment_by_id( - str(object_db.base.deployment_id), request.state.project_id # type: ignore + str(object_db.base.deployment_id) # type: ignore ) else: raise HTTPException( diff --git a/agenta-backend/agenta_backend/routers/environment_router.py b/agenta-backend/agenta_backend/routers/environment_router.py index 573b268c3..554ffec22 100644 --- a/agenta-backend/agenta_backend/routers/environment_router.py +++ b/agenta-backend/agenta_backend/routers/environment_router.py @@ -34,10 +34,13 @@ async def deploy_to_environment( HTTPException: If the deployment fails. """ try: + variant = await db_manager.fetch_app_variant_by_id( + app_variant_id=payload.variant_id + ) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(variant.project_id), permission=Permission.DEPLOY_APPLICATION, ) logger.debug(f"User has permission deploy to environment: {has_permission}") @@ -52,7 +55,6 @@ async def deploy_to_environment( await db_manager.deploy_to_environment( environment_name=payload.environment_name, variant_id=payload.variant_id, - project_id=request.state.project_id, user_uid=request.state.user_id, ) @@ -61,7 +63,7 @@ async def deploy_to_environment( user_uid=request.state.user_id, object_id=payload.variant_id, object_type="variant", - project_id=request.state.project_id, + project_id=str(variant.project_id), ) logger.debug("Successfully updated last_modified_by app information") except Exception as e: diff --git a/agenta-backend/agenta_backend/routers/evaluation_router.py b/agenta-backend/agenta_backend/routers/evaluation_router.py index 84936d322..2cb33bc55 100644 --- a/agenta-backend/agenta_backend/routers/evaluation_router.py +++ b/agenta-backend/agenta_backend/routers/evaluation_router.py @@ -54,10 +54,11 @@ async def fetch_evaluation_ids( List[str]: A list of evaluation ids. """ try: + app = await db_manager.fetch_app_by_id(app_id=app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.VIEW_EVALUATION, ) logger.debug( @@ -71,7 +72,7 @@ async def fetch_evaluation_ids( status_code=403, ) evaluations = await db_manager.fetch_evaluations_by_resource( - resource_type, request.state.project_id, resource_ids + resource_type, str(app.project_id), resource_ids ) return list(map(lambda x: str(x.id), evaluations)) except Exception as exc: @@ -93,16 +94,14 @@ async def create_evaluation( _description_ """ try: - app = await db_manager.fetch_app_by_id( - app_id=payload.app_id, project_id=request.state.project_id - ) + app = await db_manager.fetch_app_by_id(app_id=payload.app_id) if app is None: raise HTTPException(status_code=404, detail="App not found") if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.CREATE_EVALUATION, ) logger.debug(f"User has permission to create evaluation: {has_permission}") @@ -125,14 +124,14 @@ async def create_evaluation( for variant_id in payload.variant_ids: evaluation = await evaluation_service.create_new_evaluation( app_id=payload.app_id, - project_id=request.state.project_id, + project_id=str(app.project_id), variant_id=variant_id, testset_id=payload.testset_id, ) evaluate.delay( app_id=payload.app_id, - project_id=request.state.project_id, + project_id=str(app.project_id), variant_id=variant_id, evaluators_config_ids=payload.evaluators_configs, testset_id=payload.testset_id, @@ -147,7 +146,7 @@ async def create_evaluation( user_uid=request.state.user_id, object_id=payload.app_id, object_type="app", - project_id=request.state.project_id, + project_id=str(app.project_id), ) logger.debug("Successfully updated last_modified_by app information") @@ -181,13 +180,11 @@ async def fetch_evaluation_status( """ try: - evaluation = await db_manager.fetch_evaluation_by_id( - evaluation_id, request.state.project_id - ) + evaluation = await db_manager.fetch_evaluation_by_id(evaluation_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluation.project_id), permission=Permission.VIEW_EVALUATION, ) logger.debug( @@ -228,7 +225,7 @@ async def fetch_evaluation_results( if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluation.project_id), permission=Permission.VIEW_EVALUATION, ) logger.debug( @@ -272,9 +269,7 @@ async def fetch_evaluation_scenarios( """ try: - evaluation = await db_manager.fetch_evaluation_by_id( - evaluation_id, request.state.project_id - ) + evaluation = await db_manager.fetch_evaluation_by_id(evaluation_id) if not evaluation: raise HTTPException( status_code=404, detail=f"Evaluation with id {evaluation_id} not found" @@ -283,7 +278,7 @@ async def fetch_evaluation_scenarios( if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluation.project_id), permission=Permission.VIEW_EVALUATION, ) logger.debug( @@ -299,7 +294,7 @@ async def fetch_evaluation_scenarios( eval_scenarios = ( await evaluation_service.fetch_evaluation_scenarios_for_evaluation( - evaluation_id=str(evaluation.id), project_id=request.state.project_id + evaluation_id=str(evaluation.id), project_id=str(evaluation.project_id) ) ) return eval_scenarios @@ -326,11 +321,11 @@ async def fetch_list_evaluations( List[Evaluation]: A list of evaluations. """ try: - app = await db_manager.fetch_app_by_id(app_id, request.state.project_id) + app = await db_manager.fetch_app_by_id(app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.VIEW_EVALUATION, ) logger.debug( @@ -344,9 +339,7 @@ async def fetch_list_evaluations( status_code=403, ) - return await evaluation_service.fetch_list_evaluations( - app, request.state.project_id - ) + return await evaluation_service.fetch_list_evaluations(app, str(app.project_id)) except Exception as exc: import traceback @@ -374,9 +367,7 @@ async def fetch_evaluation( Evaluation: The fetched evaluation. """ try: - evaluation = await db_manager.fetch_evaluation_by_id( - evaluation_id, request.state.project_id - ) + evaluation = await db_manager.fetch_evaluation_by_id(evaluation_id) if not evaluation: raise HTTPException( status_code=404, detail=f"Evaluation with id {evaluation_id} not found" @@ -385,7 +376,7 @@ async def fetch_evaluation( if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluation.project_id), permission=Permission.VIEW_EVALUATION, ) logger.debug( @@ -421,10 +412,11 @@ async def delete_evaluations( """ try: + evaluation = await db_manager.fetch_evaluation_by_id(payload.evaluations_ids[0]) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluation.project), permission=Permission.DELETE_EVALUATION, ) logger.debug(f"User has permission to delete evaluation: {has_permission}") @@ -441,12 +433,12 @@ async def delete_evaluations( user_uid=request.state.user_id, object_id=random.choice(payload.evaluations_ids), object_type="evaluation", - project_id=request.state.project_id, + project_id=str(evaluation.project_id), ) logger.debug("Successfully updated last_modified_by app information") await evaluation_service.delete_evaluations( - payload.evaluations_ids, request.state.project_id + payload.evaluations_ids, str(evaluation.project_id) ) return Response(status_code=status.HTTP_204_NO_CONTENT) except Exception as exc: @@ -474,11 +466,11 @@ async def fetch_evaluation_scenarios( """ try: evaluations_ids_list = evaluations_ids.split(",") - + evaluation = await db_manager.fetch_evaluation_by_id(evaluations_ids_list[0]) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluation.project_id), permission=Permission.VIEW_EVALUATION, ) logger.debug( @@ -493,7 +485,7 @@ async def fetch_evaluation_scenarios( ) eval_scenarios = await evaluation_service.compare_evaluations_scenarios( - evaluations_ids_list, request.state.project_id + evaluations_ids_list, str(evaluation.project_id) ) return eval_scenarios diff --git a/agenta-backend/agenta_backend/routers/evaluators_router.py b/agenta-backend/agenta_backend/routers/evaluators_router.py index 80b610abf..7729c97ab 100644 --- a/agenta-backend/agenta_backend/routers/evaluators_router.py +++ b/agenta-backend/agenta_backend/routers/evaluators_router.py @@ -63,10 +63,11 @@ async def get_evaluator_configs( """ try: + app_db = await db_manager.fetch_app_by_id(app_id=app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app_db.project_id), permission=Permission.VIEW_EVALUATION, ) if not has_permission: @@ -78,7 +79,7 @@ async def get_evaluator_configs( ) evaluators_configs = await evaluator_manager.get_evaluators_configs( - request.state.project_id + str(app_db.project_id) ) return evaluators_configs except Exception as e: @@ -105,7 +106,7 @@ async def get_evaluator_config( if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluator_config_db.project_id), permission=Permission.VIEW_EVALUATION, ) if not has_permission: @@ -140,13 +141,11 @@ async def create_new_evaluator_config( EvaluatorConfigDB: Evaluator configuration api model. """ try: - app_db = await db_manager.get_app_instance_by_id( - app_id=payload.app_id, project_id=request.state.project_id - ) + app_db = await db_manager.get_app_instance_by_id(app_id=payload.app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app_db.project_id), permission=Permission.CREATE_EVALUATION, ) if not has_permission: @@ -158,7 +157,7 @@ async def create_new_evaluator_config( ) evaluator_config = await evaluator_manager.create_evaluator_config( - project_id=request.state.project_id, + project_id=str(app_db.project_id), app_name=app_db.app_name, name=payload.name, evaluator_key=payload.evaluator_key, @@ -187,10 +186,13 @@ async def update_evaluator_config( """ try: + evaluator_config = await db_manager.fetch_evaluator_config( + evaluator_config_id=evaluator_config_id + ) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluator_config.project_id), permission=Permission.EDIT_EVALUATION, ) if not has_permission: @@ -228,10 +230,13 @@ async def delete_evaluator_config( bool: True if deletion was successful, False otherwise. """ try: + evaluator_config = await db_manager.fetch_evaluator_config( + evaluator_config_id=evaluator_config_id + ) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluator_config.project_id), permission=Permission.DELETE_EVALUATION, ) if not has_permission: diff --git a/agenta-backend/agenta_backend/routers/human_evaluation_router.py b/agenta-backend/agenta_backend/routers/human_evaluation_router.py index e0733b542..846c551ee 100644 --- a/agenta-backend/agenta_backend/routers/human_evaluation_router.py +++ b/agenta-backend/agenta_backend/routers/human_evaluation_router.py @@ -55,16 +55,14 @@ async def create_evaluation( _description_ """ try: - app = await db_manager.fetch_app_by_id( - app_id=payload.app_id, project_id=request.state.project_id - ) + app = await db_manager.fetch_app_by_id(app_id=payload.app_id) if app is None: raise HTTPException(status_code=404, detail="App not found") if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.CREATE_EVALUATION, ) if not has_permission: @@ -75,7 +73,7 @@ async def create_evaluation( ) new_human_evaluation_db = await evaluation_service.create_new_human_evaluation( - payload, request.state.user_id, request.state.project_id + payload ) return await converters.human_evaluation_db_to_simple_evaluation_output( new_human_evaluation_db @@ -108,10 +106,11 @@ async def fetch_list_human_evaluations( """ try: + app = await db_manager.fetch_app_by_id(app_id=app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.VIEW_EVALUATION, ) if not has_permission: @@ -122,7 +121,7 @@ async def fetch_list_human_evaluations( ) return await evaluation_service.fetch_list_human_evaluations( - app_id, request.state.project_id + app_id, str(app.project_id) ) except Exception as e: status_code = e.status_code if hasattr(e, "status_code") else 500 # type: ignore @@ -143,16 +142,14 @@ async def fetch_human_evaluation( HumanEvaluation: The fetched evaluation. """ try: - human_evaluation = await db_manager.fetch_human_evaluation_by_id( - evaluation_id, request.state.project_id - ) + human_evaluation = await db_manager.fetch_human_evaluation_by_id(evaluation_id) if not human_evaluation: raise HTTPException(status_code=404, detail="Evaluation not found") if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(human_evaluation.project_id), permission=Permission.VIEW_EVALUATION, ) if not has_permission: @@ -190,9 +187,7 @@ async def fetch_evaluation_scenarios( """ try: - human_evaluation = await db_manager.fetch_human_evaluation_by_id( - evaluation_id, request.state.project_id - ) + human_evaluation = await db_manager.fetch_human_evaluation_by_id(evaluation_id) if human_evaluation is None: raise HTTPException( status_code=404, @@ -202,7 +197,7 @@ async def fetch_evaluation_scenarios( if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(human_evaluation.project_id), permission=Permission.VIEW_EVALUATION, ) if not has_permission: @@ -243,16 +238,14 @@ async def update_human_evaluation( """ try: - human_evaluation = await db_manager.fetch_human_evaluation_by_id( - evaluation_id, request.state.project_id - ) + human_evaluation = await db_manager.fetch_human_evaluation_by_id(evaluation_id) if not human_evaluation: raise HTTPException(status_code=404, detail="Evaluation not found") if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(human_evaluation.project_id), permission=Permission.EDIT_EVALUATION, ) if not has_permission: @@ -292,7 +285,7 @@ async def update_evaluation_scenario_router( """ try: evaluation_scenario_db = await db_manager.fetch_human_evaluation_scenario_by_id( - evaluation_scenario_id, request.state.project_id + evaluation_scenario_id ) if evaluation_scenario_db is None: raise HTTPException( @@ -303,7 +296,7 @@ async def update_evaluation_scenario_router( if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluation_scenario_db.project_id), permission=Permission.EDIT_EVALUATION, ) if not has_permission: @@ -344,7 +337,7 @@ async def get_evaluation_scenario_score_router( """ try: evaluation_scenario = db_manager.fetch_evaluation_scenario_by_id( - evaluation_scenario_id, request.state.project_id + evaluation_scenario_id ) if evaluation_scenario is None: raise HTTPException( @@ -355,7 +348,7 @@ async def get_evaluation_scenario_score_router( if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluation_scenario.project_id), permission=Permission.VIEW_EVALUATION, ) if not has_permission: @@ -390,7 +383,7 @@ async def update_evaluation_scenario_score_router( """ try: evaluation_scenario = await db_manager.fetch_evaluation_scenario_by_id( - evaluation_scenario_id, request.state.project_id + evaluation_scenario_id ) if evaluation_scenario is None: raise HTTPException( @@ -401,7 +394,7 @@ async def update_evaluation_scenario_score_router( if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluation_scenario.project_id), permission=Permission.VIEW_EVALUATION, ) if not has_permission: @@ -436,9 +429,7 @@ async def fetch_results( """ try: - evaluation = await db_manager.fetch_human_evaluation_by_id( - evaluation_id, request.state.project_id - ) + evaluation = await db_manager.fetch_human_evaluation_by_id(evaluation_id) if evaluation is None: raise HTTPException( status_code=404, @@ -447,7 +438,7 @@ async def fetch_results( if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluation.project_id), permission=Permission.VIEW_EVALUATION, ) if not has_permission: @@ -476,24 +467,25 @@ async def fetch_results( @router.delete("/", response_model=List[str]) async def delete_evaluations( - delete_evaluations: DeleteEvaluation, + payload: DeleteEvaluation, request: Request, ): """ Delete specific comparison tables based on their unique IDs. Args: - delete_evaluations (List[str]): The unique identifiers of the comparison tables to delete. + payload (List[str]): The unique identifiers of the comparison tables to delete. Returns: A list of the deleted comparison tables' IDs. """ try: + evaluation = await db_manager.fetch_evaluation_by_id(payload.evaluations_ids[0]) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(evaluation.project_id), permission=Permission.DELETE_EVALUATION, ) if not has_permission: @@ -503,9 +495,7 @@ async def delete_evaluations( status_code=403, ) - await evaluation_service.delete_human_evaluations( - delete_evaluations.evaluations_ids, request.state.project_id - ) + await evaluation_service.delete_human_evaluations(payload.evaluations_ids) return Response(status_code=status.HTTP_204_NO_CONTENT) except Exception as e: import traceback diff --git a/agenta-backend/agenta_backend/routers/testset_router.py b/agenta-backend/agenta_backend/routers/testset_router.py index afa55a93f..ddd39bcc2 100644 --- a/agenta-backend/agenta_backend/routers/testset_router.py +++ b/agenta-backend/agenta_backend/routers/testset_router.py @@ -67,13 +67,11 @@ async def upload_file( dict: The result of the upload process. """ - app = await db_manager.fetch_app_by_id( - app_id=app_id, project_id=request.state.project_id - ) + app = await db_manager.fetch_app_by_id(app_id=app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.CREATE_TESTSET, ) logger.debug(f"User has Permission to upload Testset: {has_permission}") @@ -116,7 +114,7 @@ async def upload_file( try: testset = await db_manager.create_testset( - app=app, project_id=request.state.project_id, testset_data=document + app=app, project_id=str(app.project_id), testset_data=document ) return TestSetSimpleResponse( id=str(testset.id), @@ -147,13 +145,11 @@ async def import_testset( dict: The result of the import process. """ - app = await db_manager.fetch_app_by_id( - app_id=app_id, project_id=request.state.project_id - ) + app = await db_manager.fetch_app_by_id(app_id=app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.CREATE_TESTSET, ) logger.debug(f"User has Permission to import Testset: {has_permission}") @@ -184,7 +180,7 @@ async def import_testset( document["csvdata"].append(row) testset = await db_manager.create_testset( - app=app, project_id=request.state.project_id, testset_data=document + app=app, project_id=str(app.project_id), testset_data=document ) return TestSetSimpleResponse( id=str(testset.id), @@ -227,13 +223,11 @@ async def create_testset( str: The id of the test set created. """ - app = await db_manager.fetch_app_by_id( - app_id=app_id, project_id=request.state.project_id - ) + app = await db_manager.fetch_app_by_id(app_id=app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.CREATE_TESTSET, ) logger.debug(f"User has Permission to create Testset: {has_permission}") @@ -251,7 +245,7 @@ async def create_testset( "csvdata": csvdata.csvdata, } testset_instance = await db_manager.create_testset( - app=app, project_id=request.state.project_id, testset_data=testset_data + app=app, project_id=str(app.project_id), testset_data=testset_data ) if testset_instance is not None: return TestSetSimpleResponse( @@ -281,16 +275,14 @@ async def update_testset( str: The id of the test set updated. """ - testset = await db_manager.fetch_testset_by_id( - testset_id=testset_id, project_id=request.state.project_id - ) + testset = await db_manager.fetch_testset_by_id(testset_id=testset_id) if testset is None: raise HTTPException(status_code=404, detail="testset not found") if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(testset.project_id), permission=Permission.EDIT_TESTSET, ) logger.debug(f"User has Permission to update Testset: {has_permission}") @@ -335,13 +327,11 @@ async def get_testsets( - `HTTPException` with status code 404 if no testsets are found. """ - app = await db_manager.fetch_app_by_id( - app_id=app_id, project_id=request.state.project_id - ) + app = await db_manager.fetch_app_by_id(app_id=app_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app.project_id), permission=Permission.VIEW_TESTSET, ) logger.debug(f"User has Permission to view Testsets: {has_permission}") @@ -353,8 +343,8 @@ async def get_testsets( status_code=403, ) - testsets = await db_manager.fetch_testsets_by_app_id( - project_id=request.state.project_id + testsets = await db_manager.fetch_testsets_by_project_id( + project_id=str(app.project_id) ) return [ TestSetOutputResponse( @@ -382,13 +372,11 @@ async def get_single_testset( """ try: - test_set = await db_manager.fetch_testset_by_id( - testset_id=testset_id, project_id=request.state.project_id - ) + test_set = await db_manager.fetch_testset_by_id(testset_id=testset_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(test_set.project_id), permission=Permission.VIEW_TESTSET, ) logger.debug(f"User has Permission to view Testset: {has_permission}") @@ -424,19 +412,21 @@ async def delete_testsets( """ if isCloudEE(): - has_permission = await check_action_access( - user_uid=request.state.user_id, - project_id=request.state.project_id, - permission=Permission.DELETE_TESTSET, - ) - logger.debug(f"User has Permission to delete Testset: {has_permission}") - if not has_permission: - error_msg = f"You do not have permission to perform this action. Please contact your organization admin." - logger.error(error_msg) - return JSONResponse( - {"detail": error_msg}, - status_code=403, + for testset_id in payload.testset_ids: + testset = await db_manager.fetch_testset_by_id(testset_id=testset_id) + has_permission = await check_action_access( + user_uid=request.state.user_id, + project_id=str(testset.project_id), + permission=Permission.DELETE_TESTSET, ) + logger.debug(f"User has Permission to delete Testset: {has_permission}") + if not has_permission: + error_msg = f"You do not have permission to perform this action. Please contact your organization admin." + logger.error(error_msg) + return JSONResponse( + {"detail": error_msg}, + status_code=403, + ) await db_manager.remove_testsets(testset_ids=payload.testset_ids) return payload.testset_ids diff --git a/agenta-backend/agenta_backend/routers/variants_router.py b/agenta-backend/agenta_backend/routers/variants_router.py index 0d242910a..3cbfc3fd1 100644 --- a/agenta-backend/agenta_backend/routers/variants_router.py +++ b/agenta-backend/agenta_backend/routers/variants_router.py @@ -69,15 +69,13 @@ async def add_variant_from_base_and_config( logger.debug("Initiating process to add a variant based on a previous one.") logger.debug(f"Received payload: {payload}") - base_db = await db_manager.fetch_base_by_id( - payload.base_id, request.state.project_id - ) + base_db = await db_manager.fetch_base_by_id(payload.base_id) # Check user has permission to add variant if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(base_db.project_id), permission=Permission.CREATE_APPLICATION, ) logger.debug( @@ -97,7 +95,7 @@ async def add_variant_from_base_and_config( new_config_name=payload.new_config_name, parameters=payload.parameters, user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(base_db.project_id), ) logger.debug(f"Successfully added new variant: {db_app_variant}") @@ -106,12 +104,12 @@ async def add_variant_from_base_and_config( user_uid=request.state.user_id, object_id=str(db_app_variant.app_id), object_type="app", - project_id=request.state.project_id, + project_id=str(base_db.project_id), ) logger.debug("Successfully updated last_modified_by app information") app_variant_db = await db_manager.get_app_variant_instance_by_id( - str(db_app_variant.id), request.state.project_id + str(db_app_variant.id) ) return await converters.app_variant_db_to_output(app_variant_db) @@ -139,10 +137,11 @@ async def remove_variant( """ try: + variant = await db_manager.fetch_app_variant_by_id(variant_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(variant.project_id), permission=Permission.DELETE_APPLICATION_VARIANT, ) logger.debug(f"User has Permission to delete app variant: {has_permission}") @@ -159,12 +158,12 @@ async def remove_variant( user_uid=request.state.user_id, object_id=variant_id, object_type="variant", - project_id=request.state.project_id, + project_id=str(variant.project_id), ) logger.debug("Successfully updated last_modified_by app information") await app_manager.terminate_and_remove_app_variant( - project_id=request.state.project_id, app_variant_id=variant_id + project_id=str(variant.project_id), app_variant_id=variant_id ) except DockerException as e: detail = f"Docker error while trying to remove the app variant: {str(e)}" @@ -198,10 +197,11 @@ async def update_variant_parameters( JSONResponse: A JSON response containing the updated app variant parameters. """ try: + variant_db = await db_manager.fetch_app_variant_by_id(variant_id) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(variant_db.project_id), permission=Permission.MODIFY_VARIANT_CONFIGURATIONS, ) logger.debug( @@ -219,7 +219,7 @@ async def update_variant_parameters( app_variant_id=variant_id, parameters=payload.parameters, user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(variant_db.project_id), ) # Update last_modified_by app information @@ -227,7 +227,7 @@ async def update_variant_parameters( user_uid=request.state.user_id, object_id=variant_id, object_type="variant", - project_id=request.state.project_id, + project_id=str(variant_db.project_id), ) logger.debug("Successfully updated last_modified_by app information") except ValueError as e: @@ -262,13 +262,13 @@ async def update_variant_image( """ try: db_app_variant = await db_manager.fetch_app_variant_by_id( - app_variant_id=variant_id, project_id=request.state.project_id + app_variant_id=variant_id ) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(db_app_variant.project_id), permission=Permission.CREATE_APPLICATION, ) logger.debug( @@ -283,7 +283,7 @@ async def update_variant_image( ) await app_manager.update_variant_image( - db_app_variant, request.state.project_id, image, request.state.user_id + db_app_variant, str(db_app_variant.project_id), image, request.state.user_id ) # Update last_modified_by app information @@ -291,7 +291,7 @@ async def update_variant_image( user_uid=request.state.user_id, object_id=str(db_app_variant.app_id), object_type="app", - project_id=request.state.project_id, + project_id=str(db_app_variant.project_id), ) logger.debug("Successfully updated last_modified_by app information") except ValueError as e: @@ -337,15 +337,13 @@ async def start_variant( HTTPException: If the app container cannot be started. """ - app_variant_db = await db_manager.fetch_app_variant_by_id( - app_variant_id=variant_id, project_id=request.state.project_id - ) + app_variant_db = await db_manager.fetch_app_variant_by_id(app_variant_id=variant_id) # Check user has permission to start variant if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app_variant_db.project_id), permission=Permission.CREATE_APPLICATION, ) logger.debug(f"User has Permission to start variant: {has_permission}") @@ -364,14 +362,14 @@ async def start_variant( if action.action == VariantActionEnum.START: url: URI = await app_manager.start_variant( - app_variant_db, request.state.project_id, envvars + app_variant_db, str(app_variant_db.project_id), envvars ) # Deploy to production await db_manager.deploy_to_environment( environment_name="production", variant_id=str(app_variant_db.id), - project_id=request.state.project_id, + project_id=str(app_variant_db.project_id), user_uid=request.state.user_id, ) return url @@ -404,13 +402,13 @@ async def get_variant( logger.debug("getting variant " + variant_id) try: app_variant = await db_manager.fetch_app_variant_by_id( - app_variant_id=variant_id, project_id=request.state.project_id + app_variant_id=variant_id ) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app_variant.project_id), permission=Permission.VIEW_APPLICATION, ) logger.debug(f"User has Permission to get variant: {has_permission}") @@ -440,13 +438,13 @@ async def get_variant_revisions( logger.debug("getting variant revisions: ", variant_id) try: app_variant = await db_manager.fetch_app_variant_by_id( - app_variant_id=variant_id, project_id=request.state.project_id + app_variant_id=variant_id ) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app_variant.project_id), permission=Permission.VIEW_APPLICATION, ) logger.debug(f"User has Permission to get variant: {has_permission}") @@ -459,7 +457,7 @@ async def get_variant_revisions( ) app_variant_revisions = await db_manager.list_app_variant_revisions_by_variant( - app_variant=app_variant, project_id=request.state.project_id + app_variant=app_variant, project_id=str(app_variant.project_id) ) return await converters.app_variant_db_revisions_to_output( app_variant_revisions @@ -485,13 +483,13 @@ async def get_variant_revision( variant_id != "undefined" ), "Variant id is required to retrieve variant revision" app_variant = await db_manager.fetch_app_variant_by_id( - app_variant_id=variant_id, project_id=request.state.project_id + app_variant_id=variant_id ) if isCloudEE(): has_permission = await check_action_access( user_uid=request.state.user_id, - project_id=request.state.project_id, + project_id=str(app_variant.project_id), permission=Permission.VIEW_APPLICATION, ) logger.debug(f"User has Permission to get variant: {has_permission}") diff --git a/agenta-backend/agenta_backend/services/app_manager.py b/agenta-backend/agenta_backend/services/app_manager.py index e59a78e56..09ea01d02 100644 --- a/agenta-backend/agenta_backend/services/app_manager.py +++ b/agenta-backend/agenta_backend/services/app_manager.py @@ -152,7 +152,7 @@ async def update_variant_image( if not valid_image: raise ValueError("Image could not be found in registry.") - base = await db_manager.fetch_base_by_id(str(app_variant_db.base_id), project_id) + base = await db_manager.fetch_base_by_id(str(app_variant_db.base_id)) deployment = await db_manager.get_deployment_by_id( str(base.deployment_id), project_id ) @@ -204,9 +204,7 @@ async def get_appdb_str_by_id(object_id: str, object_type: str) -> str: if object_type == "app": return object_id elif object_type == "variant": - app_variant_db = await db_manager.fetch_app_variant_by_id( - object_id, project_id - ) + app_variant_db = await db_manager.fetch_app_variant_by_id(object_id) if app_variant_db is None: raise db_manager.NoResultFound(f"Variant with id {object_id} not found") return str(app_variant_db.app_id) @@ -257,9 +255,7 @@ async def terminate_and_remove_app_variant( ), "Only one of app_variant_id or app_variant_db must be provided" if app_variant_id: - app_variant_db = await db_manager.fetch_app_variant_by_id( - app_variant_id, project_id - ) + app_variant_db = await db_manager.fetch_app_variant_by_id(app_variant_id) logger.debug(f"Fetched app variant {app_variant_db}") app_id = str(app_variant_db.app_id) # type: ignore @@ -274,7 +270,7 @@ async def terminate_and_remove_app_variant( ) if is_last_variant_for_image: base_db = await db_manager.fetch_base_by_id( - base_id=str(app_variant_db.base_id), project_id=project_id + base_id=str(app_variant_db.base_id) ) if not base_db: raise db_manager.NoResultFound( @@ -323,7 +319,7 @@ async def terminate_and_remove_app_variant( logger.debug("remove_app_variant_from_db") await db_manager.remove_app_variant_from_db(app_variant_db, project_id) - app_variants = await db_manager.list_app_variants(app_id, project_id) + app_variants = await db_manager.list_app_variants(app_id) logger.debug(f"Count of app variants available: {len(app_variants)}") if ( len(app_variants) == 0 @@ -358,14 +354,13 @@ async def remove_app_related_resources(app_id: str, project_id: str): raise e from None -async def remove_app(app: AppDB, project_id: str): +async def remove_app(app: AppDB): """Removes all app variants from db, if it is the last one using an image, then deletes the image from the db, shutdowns the container, deletes it and remove the image from the registry Args: app (AppDB): The application instance to remove from database. - project_id (str): The ID of the project. """ if app is None: @@ -373,11 +368,11 @@ async def remove_app(app: AppDB, project_id: str): logger.error(error_msg) raise ValueError(error_msg) - app_variants = await db_manager.list_app_variants(str(app.id), project_id) + app_variants = await db_manager.list_app_variants(str(app.id)) try: for app_variant_db in app_variants: await terminate_and_remove_app_variant( - project_id=project_id, app_variant_db=app_variant_db + project_id=str(app_variant_db.project_id), app_variant_db=app_variant_db ) logger.info( f"Successfully deleted app variant {app_variant_db.app.app_name}/{app_variant_db.variant_name}." @@ -385,14 +380,14 @@ async def remove_app(app: AppDB, project_id: str): if len(app_variants) == 0: logger.debug("remove_app_related_resources") - await remove_app_related_resources(str(app.id), project_id) + await remove_app_related_resources(str(app.id), str(app.project_id)) except Exception as e: # Failsafe: in case something went wrong, # delete app and its related resources try: logger.debug("remove_app_related_resources") - await remove_app_related_resources(str(app.id), project_id) + await remove_app_related_resources(str(app.id), str(app.project_id)) except Exception as e: logger.error( f"An error occurred while deleting app {app.id} and its associated resources: {str(e)}" diff --git a/agenta-backend/agenta_backend/services/db_manager.py b/agenta-backend/agenta_backend/services/db_manager.py index 7f62a68e3..c6554dd6c 100644 --- a/agenta-backend/agenta_backend/services/db_manager.py +++ b/agenta-backend/agenta_backend/services/db_manager.py @@ -151,7 +151,7 @@ async def get_image_by_id(image_id: str) -> ImageDB: return image -async def fetch_app_by_id(app_id: str, project_id: str) -> AppDB: +async def fetch_app_by_id(app_id: str) -> AppDB: """Fetches an app by its ID. Args: @@ -161,23 +161,18 @@ async def fetch_app_by_id(app_id: str, project_id: str) -> AppDB: assert app_id is not None, "app_id cannot be None" app_uuid = await get_object_uuid(object_id=app_id, table_name="app_db") async with db_engine.get_session() as session: - base_query = select(AppDB).filter_by( - id=uuid.UUID(app_uuid), project_id=uuid.UUID(project_id) - ) + base_query = select(AppDB).filter_by(id=uuid.UUID(app_uuid)) result = await session.execute(base_query) app = result.unique().scalars().first() return app -async def fetch_app_variant_by_id( - app_variant_id: str, project_id: str -) -> Optional[AppVariantDB]: +async def fetch_app_variant_by_id(app_variant_id: str) -> Optional[AppVariantDB]: """ Fetches an app variant by its ID. Args: app_variant_id (str): The ID of the app variant to fetch. - project_id (str): The ID of the project the app variant belongs to. Returns: AppVariantDB: The fetched app variant, or None if no app variant was found. @@ -198,11 +193,7 @@ async def fetch_app_variant_by_id( joinedload(AppVariantDB.image).load_only(ImageDB.docker_id, ImageDB.tags), # type: ignore ) - result = await session.execute( - query.filter_by( - id=uuid.UUID(app_variant_id), project_id=uuid.UUID(project_id) - ) - ) + result = await session.execute(query.filter_by(id=uuid.UUID(app_variant_id))) app_variant = result.scalars().first() return app_variant @@ -285,13 +276,12 @@ async def fetch_app_variant_revision_by_variant( return app_variant_revision -async def fetch_base_by_id(base_id: str, project_id: str) -> Optional[VariantBaseDB]: +async def fetch_base_by_id(base_id: str) -> Optional[VariantBaseDB]: """ Fetches a base by its ID. Args: base_id (str): The ID of the base to fetch. - project_id (str): The ID of the project. Returns: VariantBaseDB: The fetched base, or None if no base was found. @@ -305,7 +295,7 @@ async def fetch_base_by_id(base_id: str, project_id: str) -> Optional[VariantBas .options( joinedload(VariantBaseDB.image), joinedload(VariantBaseDB.deployment) ) - .filter_by(id=uuid.UUID(base_uuid), project_id=uuid.UUID(project_id)) + .filter_by(id=uuid.UUID(base_uuid)) ) base = result.scalars().first() return base @@ -560,7 +550,9 @@ async def create_deployment( raise Exception(f"Error while creating deployment: {e}") -async def create_app_and_envs(app_name: str, project_id: str) -> AppDB: +async def create_app_and_envs( + app_name: str, project_id: Optional[str] = None, workspace_id: Optional[str] = None +) -> AppDB: """ Create a new app with the given name and organization ID. @@ -575,10 +567,14 @@ async def create_app_and_envs(app_name: str, project_id: str) -> AppDB: ValueError: If an app with the same name already exists. """ - app = await fetch_app_by_name_and_parameters(app_name, project_id) + app = await fetch_app_by_name_and_parameters(app_name) if app is not None: raise ValueError("App with the same name already exists") + if isCloudEE(): + project = await db_manager_ee.get_project_by_workspace(workspace_id) + project_id = str(project.id) + async with db_engine.get_session() as session: app = AppDB(app_name=app_name, project_id=uuid.UUID(project_id)) @@ -586,9 +582,7 @@ async def create_app_and_envs(app_name: str, project_id: str) -> AppDB: await session.commit() await session.refresh(app) - await initialize_environments( - session=session, app_db=app, project_id=project_id - ) + await initialize_environments(session=session, app_db=app) return app @@ -613,12 +607,11 @@ async def update_app(app_id: str, values_to_update: dict) -> None: await session.commit() -async def get_deployment_by_id(deployment_id: str, project_id: str) -> DeploymentDB: +async def get_deployment_by_id(deployment_id: str) -> DeploymentDB: """Get the deployment object from the database with the provided id. Arguments: deployment_id (str): The deployment id - project_id (str): The ID of the project Returns: DeploymentDB: instance of deployment object @@ -626,9 +619,7 @@ async def get_deployment_by_id(deployment_id: str, project_id: str) -> Deploymen async with db_engine.get_session() as session: result = await session.execute( - select(DeploymentDB).filter_by( - id=uuid.UUID(deployment_id), project_id=uuid.UUID(project_id) - ) + select(DeploymentDB).filter_by(id=uuid.UUID(deployment_id)) ) deployment = result.scalars().first() return deployment @@ -698,13 +689,12 @@ async def list_bases_for_app_id(app_id: str, base_name: Optional[str] = None): return bases -async def list_variants_for_base(base: VariantBaseDB, project_id: str): +async def list_variants_for_base(base: VariantBaseDB): """ Lists all the app variants from the db for a base Args: base (VariantBaseDB): if specified, only returns the variants for the base - project_id (str): The ID of the project Returns: List[AppVariant]: List of AppVariant objects @@ -714,7 +704,7 @@ async def list_variants_for_base(base: VariantBaseDB, project_id: str): async with db_engine.get_session() as session: result = await session.execute( select(AppVariantDB) - .filter_by(base_id=base.id, project_id=uuid.UUID(project_id)) + .filter_by(base_id=base.id) .order_by(AppVariantDB.variant_name.asc()) ) app_variants = result.scalars().all() @@ -869,7 +859,7 @@ async def get_orga_image_instance_by_uri(template_uri: str) -> ImageDB: return image -async def get_app_instance_by_id(app_id: str, project_id: str) -> AppDB: +async def get_app_instance_by_id(app_id: str) -> AppDB: """Get the app object from the database with the provided id. Arguments: @@ -880,11 +870,7 @@ async def get_app_instance_by_id(app_id: str, project_id: str) -> AppDB: """ async with db_engine.get_session() as session: - result = await session.execute( - select(AppDB).filter_by( - id=uuid.UUID(app_id), project_id=uuid.UUID(project_id) - ) - ) + result = await session.execute(select(AppDB).filter_by(id=uuid.UUID(app_id))) app = result.scalars().first() return app @@ -919,7 +905,7 @@ async def add_variant_from_base_and_config( raise HTTPException(status_code=404, detail="Previous app variant not found") logger.debug(f"Located previous variant: {previous_app_variant_db}") - app_variant_for_base = await list_variants_for_base(base_db, project_id) + app_variant_for_base = await list_variants_for_base(base_db) already_exists = any( av for av in app_variant_for_base if av.config_name == new_config_name # type: ignore @@ -980,17 +966,18 @@ async def list_apps( """ if app_name is not None: - app_db = await fetch_app_by_name_and_parameters( - app_name=app_name, project_id=project_id - ) + app_db = await fetch_app_by_name_and_parameters(app_name=app_name) return [converters.app_db_to_pydantic(app_db)] elif isCloudEE(): if isCloudEE(): + project = await db_manager_ee.get_project_by_workspace( + workspace_id=workspace_id + ) user_org_workspace_data = await get_user_org_and_workspace_id(user_uid) # type: ignore has_permission = await check_rbac_permission( # type: ignore user_org_workspace_data=user_org_workspace_data, - project_id=project_id, + project_id=str(project.id), permission=Permission.VIEW_APPLICATION, # type: ignore ) logger.debug(f"User has Permission to list apps: {has_permission}") @@ -1000,9 +987,6 @@ async def list_apps( detail="You do not have access to perform this action. Please contact your organization admin.", ) - project = await db_manager_ee.get_project_by_workspace( - workspace_id=workspace_id - ) async with db_engine.get_session() as session: result = await session.execute( select(AppDB).filter_by(project_id=project.id) @@ -1019,7 +1003,7 @@ async def list_apps( return [converters.app_db_to_pydantic(app) for app in apps] -async def list_app_variants(app_id: str, project_id: str): +async def list_app_variants(app_id: str): """ Lists all the app variants from the db @@ -1039,7 +1023,7 @@ async def list_app_variants(app_id: str, project_id: str): joinedload(AppVariantDB.app.of_type(AppDB)).load_only(AppDB.id, AppDB.app_name), # type: ignore joinedload(AppVariantDB.base.of_type(VariantBaseDB)).joinedload(VariantBaseDB.deployment.of_type(DeploymentDB)).load_only(DeploymentDB.uri), # type: ignore ) - .filter_by(app_id=uuid.UUID(app_uuid), project_id=uuid.UUID(project_id)) + .filter_by(app_id=uuid.UUID(app_uuid)) ) app_variants = result.scalars().all() return app_variants @@ -1138,7 +1122,7 @@ async def remove_app_variant_from_db(app_variant_db: AppVariantDB, project_id: s async def deploy_to_environment( - environment_name: str, variant_id: str, project_id: str, **user_org_data + environment_name: str, variant_id: str, **user_org_data ): """ Deploys an app variant to a specified environment. @@ -1146,7 +1130,6 @@ async def deploy_to_environment( Args: environment_name (str): The name of the environment to deploy the app variant to. variant_id (str): The ID of the app variant to deploy. - project_id (str): The ID of the project. Raises: ValueError: If the app variant is not found or if the environment is not found or if the app variant is already @@ -1155,9 +1138,9 @@ async def deploy_to_environment( None """ - app_variant_db = await fetch_app_variant_by_id(variant_id, project_id) + app_variant_db = await fetch_app_variant_by_id(variant_id) app_variant_revision_db = await fetch_app_variant_revision_by_variant( - app_variant_id=variant_id, project_id=project_id, revision=app_variant_db.revision # type: ignore + app_variant_id=variant_id, project_id=str(app_variant_db.project_id), revision=app_variant_db.revision # type: ignore ) if app_variant_db is None: raise ValueError("App variant not found") @@ -1174,7 +1157,7 @@ async def deploy_to_environment( result = await session.execute( select(AppEnvironmentDB).filter_by( app_id=app_variant_db.app_id, - project_id=uuid.UUID(project_id), + project_id=app_variant_db.project_id, name=environment_name, ) ) @@ -1193,7 +1176,7 @@ async def deploy_to_environment( session, environment_db, user, - project_id, + str(app_variant_db.project_id), deployed_app_variant_revision=app_variant_revision_db, deployment=deployment, ) @@ -1339,20 +1322,19 @@ async def update_app_environment_deployed_variant_revision( await session.refresh(app_environment) -async def list_environments(app_id: str, project_id: str, **kwargs: dict): +async def list_environments(app_id: str, **kwargs: dict): """ List all environments for a given app ID. Args: app_id (str): The ID of the app to list environments for. - project_id (str): The ID of the project to list environments for. Returns: List[AppEnvironmentDB]: A list of AppEnvironmentDB objects representing the environments for the given app ID. """ logging.debug("Listing environments for app %s", app_id) - app_instance = await fetch_app_by_id(app_id=app_id, project_id=project_id) + app_instance = await fetch_app_by_id(app_id=app_id) if app_instance is None: logging.error(f"App with id {app_id} not found") raise ValueError("App not found") @@ -1368,21 +1350,20 @@ async def list_environments(app_id: str, project_id: str, **kwargs: dict): AppVariantRevisionsDB.config_parameters, # type: ignore ) ) - .filter_by(app_id=uuid.UUID(app_id), project_id=uuid.UUID(project_id)) + .filter_by(app_id=uuid.UUID(app_id), project_id=app_instance.project_id) ) environments_db = result.scalars().all() return environments_db async def initialize_environments( - session: AsyncSession, app_db: AppDB, project_id: str + session: AsyncSession, app_db: AppDB ) -> List[AppEnvironmentDB]: """ Initializes the environments for the app with the given database. Args: app_db (AppDB): The database for the app. - project_id (str): The ID of the project. Returns: List[AppEnvironmentDB]: A list of the initialized environments. @@ -1390,15 +1371,13 @@ async def initialize_environments( environments = [] for env_name in ["development", "staging", "production"]: - env = await create_environment( - session=session, name=env_name, app_db=app_db, project_id=project_id - ) + env = await create_environment(session=session, name=env_name, app_db=app_db) environments.append(env) return environments async def create_environment( - session: AsyncSession, name: str, app_db: AppDB, project_id: str + session: AsyncSession, name: str, app_db: AppDB ) -> AppEnvironmentDB: """ Creates a new environment in the database. @@ -1406,14 +1385,13 @@ async def create_environment( Args: name (str): The name of the environment. app_db (AppDB): The AppDB object representing the app that the environment belongs to. - project_id (str): The ID of the project. Returns: AppEnvironmentDB: The newly created AppEnvironmentDB object. """ environment_db = AppEnvironmentDB( - app_id=app_db.id, name=name, project_id=uuid.UUID(project_id), revision=0 + app_id=app_db.id, name=name, project_id=app_db.project_id, revision=0 ) session.add(environment_db) @@ -1770,7 +1748,7 @@ async def get_app_variant_instance_by_id( return app_variant_db -async def fetch_testset_by_id(testset_id: str, project_id: str) -> Optional[TestSetDB]: +async def fetch_testset_by_id(testset_id: str) -> Optional[TestSetDB]: """Fetches a testset by its ID. Args: testset_id (str): The ID of the testset to fetch. @@ -1787,11 +1765,7 @@ async def fetch_testset_by_id(testset_id: str, project_id: str) -> Optional[Test raise ValueError(f"testset_id {testset_id} is not a valid UUID") from e async with db_engine.get_session() as session: - result = await session.execute( - select(TestSetDB).filter_by( - id=testset_uuid, project_id=uuid.UUID(project_id) - ) - ) + result = await session.execute(select(TestSetDB).filter_by(id=testset_uuid)) testset = result.scalars().first() return testset @@ -1842,8 +1816,8 @@ async def update_testset(testset_id: str, values_to_update: dict) -> None: await session.refresh(testset) -async def fetch_testsets_by_app_id(project_id: str): - """Fetches all testsets for a given app. +async def fetch_testsets_by_project_id(project_id: str): + """Fetches all testsets for a given project. Args: project_id (str): The ID of the project. @@ -1860,9 +1834,7 @@ async def fetch_testsets_by_app_id(project_id: str): return testsets -async def fetch_evaluation_by_id( - evaluation_id: str, project_id: str -) -> Optional[EvaluationDB]: +async def fetch_evaluation_by_id(evaluation_id: str) -> Optional[EvaluationDB]: """Fetches a evaluation by its ID. Args: @@ -1874,9 +1846,7 @@ async def fetch_evaluation_by_id( assert evaluation_id is not None, "evaluation_id cannot be None" async with db_engine.get_session() as session: - base_query = select(EvaluationDB).filter_by( - id=uuid.UUID(evaluation_id), project_id=uuid.UUID(project_id) - ) + base_query = select(EvaluationDB).filter_by(id=uuid.UUID(evaluation_id)) if isCloudEE(): query = base_query.options( joinedload(EvaluationDB.testset.of_type(TestSetDB)).load_only(TestSetDB.id, TestSetDB.name), # type: ignore @@ -1930,7 +1900,6 @@ async def list_human_evaluations(app_id: str, project_id: str): async def create_human_evaluation( app: AppDB, - project_id: str, status: str, evaluation_type: str, testset_id: str, @@ -1941,7 +1910,6 @@ async def create_human_evaluation( Args: app (AppDB: The app object - project_id (str): The ID of the project status (str): The status of the evaluation evaluation_type (str): The evaluation type testset_id (str): The ID of the evaluation testset @@ -1951,7 +1919,7 @@ async def create_human_evaluation( async with db_engine.get_session() as session: human_evaluation = HumanEvaluationDB( app_id=app.id, - project_id=uuid.UUID(project_id), + project_id=app.project_id, status=status, evaluation_type=evaluation_type, testset_id=testset_id, @@ -1965,7 +1933,6 @@ async def create_human_evaluation( await create_human_evaluation_variants( human_evaluation_id=str(human_evaluation.id), variants_ids=variants_ids, - project_id=project_id, ) return human_evaluation @@ -2005,7 +1972,7 @@ async def fetch_human_evaluation_variants(human_evaluation_id: str): async def create_human_evaluation_variants( - human_evaluation_id: str, variants_ids: List[str], project_id: str + human_evaluation_id: str, variants_ids: List[str] ): """ Creates human evaluation variants. @@ -2018,16 +1985,14 @@ async def create_human_evaluation_variants( variants_dict = {} for variant_id in variants_ids: - variant = await fetch_app_variant_by_id( - app_variant_id=variant_id, project_id=project_id - ) + variant = await fetch_app_variant_by_id(app_variant_id=variant_id) if variant: variants_dict[variant_id] = variant variants_revisions_dict = {} for variant_id, variant in variants_dict.items(): variant_revision = await fetch_app_variant_revision_by_variant( - app_variant_id=str(variant.id), project_id=project_id, revision=variant.revision # type: ignore + app_variant_id=str(variant.id), project_id=str(variant.project_id), revision=variant.revision # type: ignore ) if variant_revision: variants_revisions_dict[variant_id] = variant_revision @@ -2050,20 +2015,21 @@ async def create_human_evaluation_variants( async def fetch_human_evaluation_by_id( - evaluation_id: str, project_id: str + evaluation_id: str, ) -> Optional[HumanEvaluationDB]: - """Fetches a evaluation by its ID. + """ + Fetches a evaluation by its ID. + Args: evaluation_id (str): The ID of the evaluation to fetch. + Returns: EvaluationDB: The fetched evaluation, or None if no evaluation was found. """ assert evaluation_id is not None, "evaluation_id cannot be None" async with db_engine.get_session() as session: - base_query = select(HumanEvaluationDB).filter_by( - id=uuid.UUID(evaluation_id), project_id=uuid.UUID(project_id) - ) + base_query = select(HumanEvaluationDB).filter_by(id=uuid.UUID(evaluation_id)) if isCloudEE(): query = base_query.options( joinedload(HumanEvaluationDB.testset.of_type(TestSetDB)).load_only(TestSetDB.id, TestSetDB.name), # type: ignore @@ -2104,7 +2070,7 @@ async def update_human_evaluation(evaluation_id: str, values_to_update: dict): await session.refresh(human_evaluation) -async def delete_human_evaluation(evaluation_id: str, project_id: str): +async def delete_human_evaluation(evaluation_id: str): """Delete the evaluation by its ID. Args: @@ -2114,9 +2080,7 @@ async def delete_human_evaluation(evaluation_id: str, project_id: str): assert evaluation_id is not None, "evaluation_id cannot be None" async with db_engine.get_session() as session: result = await session.execute( - select(HumanEvaluationDB).filter_by( - id=uuid.UUID(evaluation_id), project_id=uuid.UUID(project_id) - ) + select(HumanEvaluationDB).filter_by(id=uuid.UUID(evaluation_id)) ) evaluation = result.scalars().first() if not evaluation: @@ -2233,13 +2197,12 @@ async def fetch_evaluation_scenarios(evaluation_id: str, project_id: str): async def fetch_evaluation_scenario_by_id( - evaluation_scenario_id: str, project_id: str + evaluation_scenario_id: str, ) -> Optional[EvaluationScenarioDB]: """Fetches and evaluation scenario by its ID. Args: evaluation_scenario_id (str): The ID of the evaluation scenario to fetch. - project_id (str): The project ID to use in fetching the evaluation scenario. Returns: EvaluationScenarioDB: The fetched evaluation scenario, or None if no evaluation scenario was found. @@ -2248,22 +2211,19 @@ async def fetch_evaluation_scenario_by_id( assert evaluation_scenario_id is not None, "evaluation_scenario_id cannot be None" async with db_engine.get_session() as session: result = await session.execute( - select(EvaluationScenarioDB).filter_by( - id=uuid.UUID(evaluation_scenario_id), project_id=uuid.UUID(project_id) - ) + select(EvaluationScenarioDB).filter_by(id=uuid.UUID(evaluation_scenario_id)) ) evaluation_scenario = result.scalars().first() return evaluation_scenario async def fetch_human_evaluation_scenario_by_id( - evaluation_scenario_id: str, project_id: str + evaluation_scenario_id: str, ) -> Optional[HumanEvaluationScenarioDB]: """Fetches and evaluation scenario by its ID. Args: evaluation_scenario_id (str): The ID of the evaluation scenario to fetch. - project_id (str): The project ID to use in fetching the human evaluation. Returns: EvaluationScenarioDB: The fetched evaluation scenario, or None if no evaluation scenario was found. @@ -2273,7 +2233,7 @@ async def fetch_human_evaluation_scenario_by_id( async with db_engine.get_session() as session: result = await session.execute( select(HumanEvaluationScenarioDB).filter_by( - id=uuid.UUID(evaluation_scenario_id), project_id=uuid.UUID(project_id) + id=uuid.UUID(evaluation_scenario_id) ) ) evaluation_scenario = result.scalars().first() @@ -2539,21 +2499,28 @@ async def update_app_variant( return app_variant -async def fetch_app_by_name_and_parameters(app_name: str, project_id: str): +async def fetch_app_by_name_and_parameters( + app_name: str, workspace_id: Optional[str] = None +): """Fetch an app by its name and project identifier. Args: app_name (str): The name of the app - project_id (str): The ID of the project + workspace_id (str, optional): The ID of the workspace. Defaults to None. Returns: AppDB: the instance of the app """ - async with db_engine.get_session() as session: - query = select(AppDB).filter_by( - app_name=app_name, project_id=uuid.UUID(project_id) + if isCloudEE() and workspace_id is not None: + project = await db_manager_ee.get_project_by_workspace( + workspace_id=workspace_id ) + query = select(AppDB).filter_by(app_name=app_name, project_id=project.id) + else: + query = select(AppDB).filter_by(app_name=app_name) + + async with db_engine.get_session() as session: result = await session.execute(query) app_db = result.unique().scalars().first() return app_db @@ -2866,12 +2833,11 @@ async def fetch_evaluators_configs(project_id: str): return evaluators_configs -async def fetch_evaluator_config(evaluator_config_id: str, project_id: str): +async def fetch_evaluator_config(evaluator_config_id: str): """Fetch evaluator configurations from the database. Args: evaluator_config_id (str): The ID of the evaluator configuration. - project_id (str): The ID of the project. Returns: EvaluatorConfigDB: the evaluator configuration object. @@ -2879,9 +2845,7 @@ async def fetch_evaluator_config(evaluator_config_id: str, project_id: str): async with db_engine.get_session() as session: result = await session.execute( - select(EvaluatorConfigDB).filter_by( - id=uuid.UUID(evaluator_config_id), project_id=uuid.UUID(project_id) - ) + select(EvaluatorConfigDB).filter_by(id=uuid.UUID(evaluator_config_id)) ) evaluator_config = result.scalars().first() return evaluator_config diff --git a/agenta-backend/agenta_backend/services/evaluation_service.py b/agenta-backend/agenta_backend/services/evaluation_service.py index 9b98e3be4..70d2ee3da 100644 --- a/agenta-backend/agenta_backend/services/evaluation_service.py +++ b/agenta-backend/agenta_backend/services/evaluation_service.py @@ -331,7 +331,7 @@ async def fetch_human_evaluation(human_evaluation_db) -> HumanEvaluation: return await converters.human_evaluation_db_to_pydantic(human_evaluation_db) -async def delete_human_evaluations(evaluation_ids: List[str], project_id: str) -> None: +async def delete_human_evaluations(evaluation_ids: List[str]) -> None: """ Delete evaluations by their IDs. @@ -344,9 +344,7 @@ async def delete_human_evaluations(evaluation_ids: List[str], project_id: str) - """ for evaluation_id in evaluation_ids: - await db_manager.delete_human_evaluation( - evaluation_id=evaluation_id, project_id=project_id - ) + await db_manager.delete_human_evaluation(evaluation_id=evaluation_id) async def delete_evaluations(evaluation_ids: List[str]) -> None: @@ -363,23 +361,18 @@ async def delete_evaluations(evaluation_ids: List[str]) -> None: await db_manager.delete_evaluations(evaluation_ids=evaluation_ids) -async def create_new_human_evaluation( - payload: NewHumanEvaluation, user_uid: str, project_id: str -) -> HumanEvaluationDB: +async def create_new_human_evaluation(payload: NewHumanEvaluation) -> HumanEvaluationDB: """ Create a new evaluation based on the provided payload and additional arguments. Args: payload (NewEvaluation): The evaluation payload. - user_uid (str): The user_uid of the user - project_id (str): The ID of the project Returns: HumanEvaluationDB """ - user = await db_manager.get_user(user_uid) - app = await db_manager.fetch_app_by_id(app_id=payload.app_id, project_id=project_id) + app = await db_manager.fetch_app_by_id(app_id=payload.app_id) if app is None: raise HTTPException( status_code=404, @@ -388,7 +381,6 @@ async def create_new_human_evaluation( human_evaluation = await db_manager.create_human_evaluation( app=app, - project_id=project_id, status=payload.status, evaluation_type=payload.evaluation_type, testset_id=payload.testset_id, @@ -402,7 +394,7 @@ async def create_new_human_evaluation( await prepare_csvdata_and_create_evaluation_scenario( human_evaluation.testset.csvdata, payload.inputs, - project_id, + str(app.project_id), payload.evaluation_type, human_evaluation, ) diff --git a/agenta-backend/agenta_backend/tasks/evaluations.py b/agenta-backend/agenta_backend/tasks/evaluations.py index 10619ea8b..9d0dd14e8 100644 --- a/agenta-backend/agenta_backend/tasks/evaluations.py +++ b/agenta-backend/agenta_backend/tasks/evaluations.py @@ -27,7 +27,6 @@ create_new_evaluation_scenario, fetch_app_by_id, fetch_app_variant_by_id, - fetch_evaluation_by_id, fetch_evaluator_config, fetch_testset_by_id, get_deployment_by_id, @@ -102,26 +101,22 @@ def evaluate( ) # 1. Fetch data from the database - app = loop.run_until_complete(fetch_app_by_id(app_id, project_id)) - app_variant_db = loop.run_until_complete( - fetch_app_variant_by_id(variant_id, project_id) - ) + app = loop.run_until_complete(fetch_app_by_id(app_id)) + app_variant_db = loop.run_until_complete(fetch_app_variant_by_id(variant_id)) assert ( app_variant_db is not None ), f"App variant with id {variant_id} not found!" app_variant_parameters = app_variant_db.config_parameters - testset_db = loop.run_until_complete( - fetch_testset_by_id(testset_id, project_id) - ) + testset_db = loop.run_until_complete(fetch_testset_by_id(testset_id)) evaluator_config_dbs = [] for evaluator_config_id in evaluators_config_ids: evaluator_config = loop.run_until_complete( - fetch_evaluator_config(evaluator_config_id, project_id) + fetch_evaluator_config(evaluator_config_id) ) evaluator_config_dbs.append(evaluator_config) deployment_db = loop.run_until_complete( - get_deployment_by_id(str(app_variant_db.base.deployment_id), project_id) + get_deployment_by_id(str(app_variant_db.base.deployment_id)) ) uri = deployment_manager.get_deployment_uri(uri=deployment_db.uri) # type: ignore