Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement]: Add 'app_type' column for AppDB model with updated API responses #1994

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e5b331e
feat (backend): created AppType enum and introduce new column 'app_ty…
aybruhm Aug 14, 2024
501841d
feat (migration): generate and apply schema migration script with Ale…
aybruhm Aug 14, 2024
474e534
feat (backend): specify enum type for 'app_type' column, extend AppTy…
aybruhm Aug 15, 2024
4296c8d
feat (backend): implement the following:
aybruhm Aug 16, 2024
a41d3d9
style (backend): format code with [email protected]
aybruhm Aug 16, 2024
7397d06
Merge branch 'main' into feature/age-540-endpoint-for-app-type
aybruhm Aug 22, 2024
ad41e91
chore (backend): rename function 'get_app_type_from_template' to 'get…
aybruhm Aug 22, 2024
61ad8c6
refactor (backend): update AppType enum to use opaque template string…
aybruhm Aug 22, 2024
5161ccc
chore (style): format cookbook with [email protected]
aybruhm Aug 22, 2024
cae8a98
refactor (backend): improve migration handling by checking only the l…
aybruhm Aug 22, 2024
1a51c59
refactor (backend): update AppType and enums in migration script
aybruhm Aug 22, 2024
3235f33
Merge branch 'feature/age-540-endpoint-for-app-type' into enhancement…
aybruhm Aug 22, 2024
c29c90f
refactor (web): add app_type to ListAppsItem interface and AppCard co…
aybruhm Aug 26, 2024
2644220
refactor (backend): simplify AppType enums
aybruhm Aug 26, 2024
0b70852
minor refactor (backend): ensure that app_type field in ListAppsItem …
aybruhm Aug 26, 2024
8736de4
Merge pull request #2013 from Agenta-AI/enhancement/refactor-migratio…
aybruhm Aug 29, 2024
1c40fc2
feat (backend): add class method for mapping AppType enum to user-fri…
aybruhm Aug 29, 2024
acdc6ad
minor refactor (backend): rename AppType class method to 'friendly_tag'
aybruhm Aug 29, 2024
fa9f607
Merge branch 'main' into feature/age-540-endpoint-for-app-type
aybruhm Aug 29, 2024
ab4c637
feat (backend): generate alembic migration script to resolve conflict…
aybruhm Aug 29, 2024
c41b713
Merge branch 'main' into feature/age-540-endpoint-for-app-type
aybruhm Sep 9, 2024
f956e40
refactor (backend): remove RAG_TEMPLATE from application types
aybruhm Sep 9, 2024
4d8b5dc
refactor (migration): regenerate alembic migration to add app_type co…
aybruhm Sep 9, 2024
436f85a
refactor (backend): remove conflicting head that is now redundant
aybruhm Sep 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""Added the 'app_type' column to the 'app_db' table

Revision ID: 1abfef8ed0ef
Revises: b80c708c21bb
Create Date: 2024-08-14 19:44:23.707519

"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "1abfef8ed0ef"
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! ###

# Create the enum type first
app_enumtype = sa.Enum(
"CHAT_PROMPT", "SINGLE_PROMPT", "RAG", "CUSTOM", name="app_enumtype"
mmabrouk marked this conversation as resolved.
Show resolved Hide resolved
)
app_enumtype.create(op.get_bind(), checkfirst=True)

# Then add the column using the enum type
op.add_column(
"app_db",
sa.Column(
"app_type",
app_enumtype,
nullable=True,
),
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###

# Drop the column first
op.drop_column("app_db", "app_type")

# Then drop the enum type
app_enumtype = sa.Enum(
"CHAT_PROMPT", "SINGLE_PROMPT", "RAG", "CUSTOM", name="app_enumtype"
)
app_enumtype.drop(op.get_bind(), checkfirst=True)
# ### 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 @@ -211,6 +211,7 @@ class URI(BaseModel):
class App(BaseModel):
app_id: str
app_name: str
app_type: Optional[str] = None


class RemoveApp(BaseModel):
Expand Down
4 changes: 3 additions & 1 deletion agenta-backend/agenta_backend/models/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,9 @@ 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), app_type=app_db.app_type
)


def image_db_to_pydantic(image_db: ImageDB) -> ImageExtended:
Expand Down
3 changes: 2 additions & 1 deletion agenta-backend/agenta_backend/models/db_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from sqlalchemy.dialects.postgresql import UUID, JSONB

from agenta_backend.models.base import Base
from agenta_backend.models.shared_models import TemplateType
from agenta_backend.models.shared_models import TemplateType, AppType


class UserDB(Base):
Expand Down Expand Up @@ -76,6 +76,7 @@ class AppDB(Base):
nullable=False,
)
app_name = Column(String)
app_type = Column(Enum(AppType, name="app_enumtype"), nullable=True)
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"))
created_at = Column(
DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)
Expand Down
7 changes: 7 additions & 0 deletions agenta-backend/agenta_backend/models/shared_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,10 @@ class HumanEvaluationScenarioOutput(BaseModel):
class TemplateType(enum.Enum):
IMAGE = "image"
ZIP = "zip"


class AppType(enum.Enum):
aybruhm marked this conversation as resolved.
Show resolved Hide resolved
CHAT_PROMPT = "chat_prompt"
SINGLE_PROMPT = "single_prompt"
RAG = "rag"
CUSTOM = "custom"
24 changes: 13 additions & 11 deletions agenta-backend/agenta_backend/routers/app_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ async def create_app(
request.state.user_id,
organization_id if isCloudEE() else None,
str(workspace.id) if isCloudEE() else None,
template_id=None,
)
return CreateAppOutput(app_id=str(app_db.id), app_name=str(app_db.app_name))
except Exception as e:
Expand Down Expand Up @@ -503,32 +504,33 @@ async def create_app_and_variant_from_template(
)

logger.debug(
"Step 5: Creating new app and initializing environments"
"Step 5: Retrieve template from db"
if isCloudEE()
else "Step 2: Creating new app and initializing environments"
else "Step 2: Retrieve template from db"
)
template_db = await db_manager.get_template(payload.template_id)

logger.debug(
"Step 6: Creating new app and initializing environments"
if isCloudEE()
else "Step 3: Creating new app and initializing environments"
)
if app is None:
app = await db_manager.create_app_and_envs(
app_name,
request.state.user_id,
payload.organization_id if isCloudEE() else None, # type: ignore
payload.workspace_id if isCloudEE() else None, # type: ignore
str(template_db.id),
)

logger.debug(
"Step 6: Retrieve template from db"
if isCloudEE()
else "Step 3: Retrieve template from db"
)
template_db = await db_manager.get_template(payload.template_id)
repo_name = os.environ.get("AGENTA_TEMPLATE_REPO", "agentaai/templates_v2")
image_name = f"{repo_name}:{template_db.name}"

logger.debug(
"Step 7: Creating image instance and adding variant based on image"
if isCloudEE()
else "Step 4: Creating image instance and adding variant based on image"
)
repo_name = os.environ.get("AGENTA_TEMPLATE_REPO", "agentaai/templates_v2")
image_name = f"{repo_name}:{template_db.name}"
app_variant_db = await app_manager.add_variant_based_on_image(
app=app,
variant_name="app.default",
Expand Down
30 changes: 29 additions & 1 deletion agenta-backend/agenta_backend/services/db_manager.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import uuid
import logging
from enum import Enum
from pathlib import Path
from urllib.parse import urlparse
from typing import Any, Dict, List, Optional
Expand Down Expand Up @@ -73,6 +74,7 @@

from agenta_backend.models.shared_models import (
Result,
AppType,
ConfigDB,
TemplateType,
CorrectAnswer,
Expand Down Expand Up @@ -616,11 +618,35 @@ async def create_deployment(
raise Exception(f"Error while creating deployment: {e}")


async def get_app_type_from_template(template_id: Optional[str]) -> Enum:
aybruhm marked this conversation as resolved.
Show resolved Hide resolved
"""Get the application type from the specified template.

Args:
template_id (Optional[str]): The ID of the template

Returns:
AppType (Enum): The determined application type. Defaults to AppType.CUSTOM.
"""

if template_id is None:
return AppType.CUSTOM

template_db = await get_template(template_id=template_id)
aybruhm marked this conversation as resolved.
Show resolved Hide resolved
if "Single Prompt" in template_db.title:
return AppType.SINGLE_PROMPT
elif "Chat Application" in template_db.title:
return AppType.CHAT_PROMPT
elif "RAG" in template_db.title:
return AppType.RAG
return AppType.CUSTOM


async def create_app_and_envs(
app_name: str,
user_uid: str,
organization_id: Optional[str] = None,
workspace_id: Optional[str] = None,
template_id: Optional[str] = None,
) -> AppDB:
"""
Create a new app with the given name and organization ID.
Expand All @@ -630,6 +656,7 @@ async def create_app_and_envs(
user_uid (str): The UID of the user that the app belongs to.
organization_id (str): The ID of the organization that the app belongs to.
workspace_id (str): The ID of the workspace that the app belongs to.
template_id (str): The ID of the template

Returns:
AppDB: The created app.
Expand All @@ -648,8 +675,9 @@ async def create_app_and_envs(
if app is not None:
raise ValueError("App with the same name already exists")

app_type = await get_app_type_from_template(template_id)
async with db_engine.get_session() as session:
app = AppDB(app_name=app_name, user_id=user.id)
app = AppDB(app_name=app_name, user_id=user.id, app_type=app_type)

if isCloudEE():
# assert that if organization_id is provided, workspace_id is also provided, and vice versa
Expand Down
Loading