Skip to content

Commit

Permalink
Merge pull request #2023 from Agenta-AI/feature/age-541-endpoint-for-…
Browse files Browse the repository at this point in the history
…app-last-modified

[Feature]: Added logic for tracking application last modified by
  • Loading branch information
aybruhm committed Aug 29, 2024
2 parents c77beb0 + 88f71af commit e7cd1ff
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Added modified_by_id column to apps_db table
Revision ID: 5c29a64204f4
Revises: b80c708c21bb
Create Date: 2024-08-25 17:56:11.732929
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision: str = "5c29a64204f4"
down_revision: Union[str, None] = "b80c708c21bb"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("app_db", sa.Column("modified_by_id", sa.UUID(), nullable=True))
op.create_foreign_key(None, "app_db", "users", ["modified_by_id"], ["id"])
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, "app_db", type_="foreignkey")
op.drop_constraint(None, "app_db", type_="unique")
op.drop_column("app_db", "modified_by_id")
# ### end Alembic commands ###
1 change: 1 addition & 0 deletions agenta-backend/agenta_backend/models/api/api_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ class URI(BaseModel):
class App(BaseModel):
app_id: str
app_name: str
updated_at: str


class RemoveApp(BaseModel):
Expand Down
6 changes: 5 additions & 1 deletion agenta-backend/agenta_backend/models/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,11 @@ def base_db_to_pydantic(base_db: VariantBaseDB) -> BaseOutput:


def app_db_to_pydantic(app_db: AppDB) -> App:
return App(app_name=app_db.app_name, app_id=str(app_db.id))
return App(
app_name=app_db.app_name,
app_id=str(app_db.id),
updated_at=str(app_db.updated_at),
)


def image_db_to_pydantic(image_db: ImageDB) -> ImageExtended:
Expand Down
4 changes: 3 additions & 1 deletion agenta-backend/agenta_backend/models/db_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,16 @@ class AppDB(Base):
)
app_name = Column(String)
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"))
modified_by_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True)
created_at = Column(
DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)
)
updated_at = Column(
DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)
)

user = relationship("UserDB")
user = relationship("UserDB", foreign_keys=[user_id])
modified_by = relationship("UserDB", foreign_keys=[modified_by_id])
variant = relationship(
"AppVariantDB", cascade="all, delete-orphan", back_populates="app"
)
Expand Down
10 changes: 9 additions & 1 deletion agenta-backend/agenta_backend/routers/environment_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from fastapi.responses import JSONResponse
from fastapi import Request, HTTPException

from agenta_backend.services import db_manager
from agenta_backend.services import db_manager, app_manager
from agenta_backend.utils.common import APIRouter, isCloudEE
from agenta_backend.models.api.api_models import DeployToEnvironmentPayload

Expand Down Expand Up @@ -53,6 +53,14 @@ async def deploy_to_environment(
variant_id=payload.variant_id,
user_uid=request.state.user_id,
)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=payload.variant_id,
object_type="variant",
)
logger.debug("Successfully updated last_modified_by app information")
except Exception as e:
logger.exception(f"An error occurred: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
18 changes: 17 additions & 1 deletion agenta-backend/agenta_backend/routers/evaluation_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from agenta_backend.models import converters
from agenta_backend.tasks.evaluations import evaluate
from agenta_backend.utils.common import APIRouter, isCloudEE
from agenta_backend.services import evaluation_service, db_manager
from agenta_backend.models.api.evaluation_model import (
Evaluation,
EvaluationScenario,
Expand All @@ -18,6 +17,7 @@
from agenta_backend.services.evaluator_manager import (
check_ai_critique_inputs,
)
from agenta_backend.services import evaluation_service, db_manager, app_manager

if isCloudEE():
from agenta_backend.commons.models.shared_models import Permission
Expand Down Expand Up @@ -139,6 +139,14 @@ async def create_evaluation(
)
evaluations.append(evaluation)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=payload.app_id,
object_type="app",
)
logger.debug("Successfully updated last_modified_by app information")

return evaluations
except KeyError:
raise HTTPException(
Expand Down Expand Up @@ -411,6 +419,14 @@ async def delete_evaluations(
status_code=403,
)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=random.choice(payload.evaluations_ids),
object_type="evaluation",
)
logger.debug("Successfully updated last_modified_by app information")

await evaluation_service.delete_evaluations(payload.evaluations_ids)
return Response(status_code=status.HTTP_204_NO_CONTENT)
except Exception as exc:
Expand Down
30 changes: 29 additions & 1 deletion agenta-backend/agenta_backend/routers/evaluators_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from fastapi.responses import JSONResponse

from agenta_backend.utils.common import APIRouter, isCloudEE
from agenta_backend.services import evaluator_manager, db_manager
from agenta_backend.services import evaluator_manager, db_manager, app_manager

from agenta_backend.models.api.evaluation_model import (
Evaluator,
Expand Down Expand Up @@ -150,8 +150,20 @@ async def create_new_evaluator_config(payload: NewEvaluatorConfig, request: Requ
evaluator_key=payload.evaluator_key,
settings_values=payload.settings_values,
)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=payload.app_id,
object_type="app",
)
logger.debug("Successfully updated last_modified_by app information")

return evaluator_config
except Exception as e:
import traceback

traceback.print_exc()
raise HTTPException(
status_code=500, detail=f"Error creating evaluator configuration: {str(e)}"
)
Expand Down Expand Up @@ -186,6 +198,14 @@ async def update_evaluator_config(
evaluators_configs = await evaluator_manager.update_evaluator_config(
evaluator_config_id=evaluator_config_id, updates=payload.dict()
)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=evaluator_config_id,
object_type="evaluator_config",
)
logger.debug("Successfully updated last_modified_by app information")
return evaluators_configs
except Exception as e:
import traceback
Expand Down Expand Up @@ -222,6 +242,14 @@ async def delete_evaluator_config(evaluator_config_id: str, request: Request):
status_code=403,
)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=evaluator_config_id,
object_type="evaluator_config",
)
logger.debug("Successfully updated last_modified_by app information")

success = await evaluator_manager.delete_evaluator_config(evaluator_config_id)
return success
except Exception as e:
Expand Down
50 changes: 48 additions & 2 deletions agenta-backend/agenta_backend/routers/human_evaluation_router.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import random
import logging
from typing import List, Dict
from fastapi import HTTPException, Body, Request, status, Response

from agenta_backend.models import converters
from agenta_backend.services import db_manager
from agenta_backend.services import results_service
from agenta_backend.services import evaluation_service
from agenta_backend.services import db_manager, app_manager
from agenta_backend.utils.common import APIRouter, isCloudEE

from agenta_backend.models.api.evaluation_model import (
Expand Down Expand Up @@ -35,6 +36,8 @@
) # noqa pylint: disable-all

router = APIRouter()
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)


@router.post(
Expand Down Expand Up @@ -72,6 +75,15 @@ async def create_evaluation(
new_human_evaluation_db = await evaluation_service.create_new_human_evaluation(
payload, request.state.user_id
)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=payload.app_id,
object_type="app",
)
logger.debug("Successfully updated last_modified_by app information")

return await converters.human_evaluation_db_to_simple_evaluation_output(
new_human_evaluation_db
)
Expand Down Expand Up @@ -253,6 +265,15 @@ async def update_human_evaluation(
)

await update_human_evaluation_service(human_evaluation, update_data)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=str(human_evaluation.app_id),
object_type="app",
)
logger.debug("Successfully updated last_modified_by app information")

return Response(status_code=status.HTTP_204_NO_CONTENT)

except KeyError:
Expand Down Expand Up @@ -308,6 +329,15 @@ async def update_evaluation_scenario_router(
payload,
evaluation_type,
)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=str(evaluation_scenario_db.evaluation_id),
object_type="human_evaluation",
)
logger.debug("Successfully updated last_modified_by app information")

return Response(status_code=status.HTTP_204_NO_CONTENT)
except UpdateEvaluationScenarioError as e:
import traceback
Expand Down Expand Up @@ -379,7 +409,7 @@ async def update_evaluation_scenario_score_router(
None: 204 No Content status code upon successful update.
"""
try:
evaluation_scenario = db_manager.fetch_evaluation_scenario_by_id(
evaluation_scenario = await db_manager.fetch_evaluation_scenario_by_id(
evaluation_scenario_id
)
if evaluation_scenario is None:
Expand All @@ -406,6 +436,14 @@ async def update_evaluation_scenario_score_router(
values_to_update=payload.dict(),
)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=str(evaluation_scenario.evaluation_id),
object_type="human_evaluation",
)
logger.debug("Successfully updated last_modified_by app information")

return Response(status_code=status.HTTP_204_NO_CONTENT)
except Exception as e:
status_code = e.status_code if hasattr(e, "status_code") else 500 # type: ignore
Expand Down Expand Up @@ -494,6 +532,14 @@ async def delete_evaluations(
status_code=403,
)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=random.choice(delete_evaluations.evaluations_ids),
object_type="human_evaluation",
)
logger.debug("Successfully updated last_modified_by app information")

await evaluation_service.delete_human_evaluations(
delete_evaluations.evaluations_ids
)
Expand Down
33 changes: 33 additions & 0 deletions agenta-backend/agenta_backend/routers/variants_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ async def add_variant_from_base_and_config(
user_uid=request.state.user_id,
)
logger.debug(f"Successfully added new variant: {db_app_variant}")

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=str(db_app_variant.app_id),
object_type="app",
)
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)
)
Expand Down Expand Up @@ -142,6 +151,14 @@ async def remove_variant(
status_code=403,
)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=variant_id,
object_type="variant",
)
logger.debug("Successfully updated last_modified_by app information")

await app_manager.terminate_and_remove_app_variant(app_variant_id=variant_id)
except DockerException as e:
detail = f"Docker error while trying to remove the app variant: {str(e)}"
Expand Down Expand Up @@ -198,6 +215,14 @@ async def update_variant_parameters(
parameters=payload.parameters,
user_uid=request.state.user_id,
)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=variant_id,
object_type="variant",
)
logger.debug("Successfully updated last_modified_by app information")
except ValueError as e:
detail = f"Error while trying to update the app variant: {str(e)}"
raise HTTPException(status_code=500, detail=detail)
Expand Down Expand Up @@ -253,6 +278,14 @@ async def update_variant_image(
await app_manager.update_variant_image(
db_app_variant, image, request.state.user_id
)

# Update last_modified_by app information
await app_manager.update_last_modified_by(
user_uid=request.state.user_id,
object_id=str(db_app_variant.app_id),
object_type="app",
)
logger.debug("Successfully updated last_modified_by app information")
except ValueError as e:
import traceback

Expand Down
Loading

0 comments on commit e7cd1ff

Please sign in to comment.