From 72cbbbbbc95c07de294ee15eec8acfec80d2f05e Mon Sep 17 00:00:00 2001 From: Aarushi <50577581+aarushik93@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:28:01 +0100 Subject: [PATCH] feat(market) Add on delete to market (#8255) * add on delete to market * add migrations * updated schema * add endpint * add migrations * remove transaction --------- Co-authored-by: Zamil Majdy --- autogpt_platform/market/market/db.py | 23 +++++++++++++ .../market/market/routes/admin.py | 32 +++++++++++++++++++ .../migration.sql | 20 ++++++++++++ autogpt_platform/market/schema.prisma | 8 ++--- 4 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 autogpt_platform/market/migrations/20241003134209_update_foreign_key_on_delete/migration.sql diff --git a/autogpt_platform/market/market/db.py b/autogpt_platform/market/market/db.py index 5f0d983891..f6b2abcdc6 100644 --- a/autogpt_platform/market/market/db.py +++ b/autogpt_platform/market/market/db.py @@ -55,6 +55,29 @@ class FeaturedAgentResponse(pydantic.BaseModel): page_size: int total_pages: int +async def delete_agent(agent_id: str) -> prisma.models.Agents | None: + """ + Delete an agent from the database. + + Args: + agent_id (str): The ID of the agent to delete. + + Returns: + prisma.models.Agents | None: The deleted agent if found, None otherwise. + + Raises: + AgentQueryError: If there is an error deleting the agent from the database. + """ + try: + deleted_agent = await prisma.models.Agents.prisma().delete( + where={"id": agent_id} + ) + return deleted_agent + except prisma.errors.PrismaError as e: + raise AgentQueryError(f"Database query failed: {str(e)}") + except Exception as e: + raise AgentQueryError(f"Unexpected error occurred: {str(e)}") + async def create_agent_entry( name: str, diff --git a/autogpt_platform/market/market/routes/admin.py b/autogpt_platform/market/market/routes/admin.py index 19ebe0f3b1..07d7774884 100644 --- a/autogpt_platform/market/market/routes/admin.py +++ b/autogpt_platform/market/market/routes/admin.py @@ -15,6 +15,38 @@ logger = logging.getLogger("marketplace") router = fastapi.APIRouter() +@router.delete("/agent/{agent_id}", response_model=market.model.AgentResponse) +async def delete_agent( + agent_id: str, + user: autogpt_libs.auth.User = fastapi.Depends( + autogpt_libs.auth.requires_admin_user + ), +): + """ + Delete an agent and all related records from the database. + + Args: + agent_id (str): The ID of the agent to delete. + + Returns: + market.model.AgentResponse: The deleted agent's data. + + Raises: + fastapi.HTTPException: If the agent is not found or if there's an error during deletion. + """ + try: + deleted_agent = await market.db.delete_agent(agent_id) + if deleted_agent: + return market.model.AgentResponse(**deleted_agent.dict()) + else: + raise fastapi.HTTPException(status_code=404, detail="Agent not found") + except market.db.AgentQueryError as e: + logger.error(f"Error deleting agent: {e}") + raise fastapi.HTTPException(status_code=500, detail=str(e)) + except Exception as e: + logger.error(f"Unexpected error deleting agent: {e}") + raise fastapi.HTTPException(status_code=500, detail="An unexpected error occurred") + @router.post("/agent", response_model=market.model.AgentResponse) async def create_agent_entry( request: market.model.AddAgentRequest, diff --git a/autogpt_platform/market/migrations/20241003134209_update_foreign_key_on_delete/migration.sql b/autogpt_platform/market/migrations/20241003134209_update_foreign_key_on_delete/migration.sql new file mode 100644 index 0000000000..2e1bdc7b7c --- /dev/null +++ b/autogpt_platform/market/migrations/20241003134209_update_foreign_key_on_delete/migration.sql @@ -0,0 +1,20 @@ +-- DropForeignKey +ALTER TABLE "AnalyticsTracker" DROP CONSTRAINT "AnalyticsTracker_agentId_fkey"; + +-- DropForeignKey +ALTER TABLE "FeaturedAgent" DROP CONSTRAINT "FeaturedAgent_agentId_fkey"; + +-- DropForeignKey +ALTER TABLE "InstallTracker" DROP CONSTRAINT "InstallTracker_marketplaceAgentId_fkey"; + +-- DropIndex +DROP INDEX "AnalyticsTracker_agentId_key"; + +-- AddForeignKey +ALTER TABLE "AnalyticsTracker" ADD CONSTRAINT "AnalyticsTracker_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "Agents"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "InstallTracker" ADD CONSTRAINT "InstallTracker_marketplaceAgentId_fkey" FOREIGN KEY ("marketplaceAgentId") REFERENCES "Agents"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "FeaturedAgent" ADD CONSTRAINT "FeaturedAgent_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "Agents"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/autogpt_platform/market/schema.prisma b/autogpt_platform/market/schema.prisma index f89af707d4..1d3a293385 100644 --- a/autogpt_platform/market/schema.prisma +++ b/autogpt_platform/market/schema.prisma @@ -47,8 +47,8 @@ model Agents { model AnalyticsTracker { id String @id @unique @default(dbgenerated("gen_random_uuid()")) @db.Uuid - agentId String @unique @db.Uuid - agent Agents @relation(fields: [agentId], references: [id]) + agentId String @db.Uuid + agent Agents @relation(fields: [agentId], references: [id], onDelete: Cascade) views Int downloads Int } @@ -61,7 +61,7 @@ enum InstallationLocation { model InstallTracker { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid marketplaceAgentId String @db.Uuid - marketplaceAgent Agents @relation(fields: [marketplaceAgentId], references: [id]) + marketplaceAgent Agents @relation(fields: [marketplaceAgentId], references: [id], onDelete: Cascade) installedAgentId String @db.Uuid installationLocation InstallationLocation createdAt DateTime @default(now()) @@ -72,7 +72,7 @@ model InstallTracker { model FeaturedAgent { id String @id @unique @default(dbgenerated("gen_random_uuid()")) @db.Uuid agentId String @unique @db.Uuid - agent Agents @relation(fields: [agentId], references: [id]) + agent Agents @relation(fields: [agentId], references: [id], onDelete: Cascade) isActive Boolean @default(false) featuredCategories String[] createdAt DateTime @default(now())