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

Feat: Ability to invite users to organizations #604

Merged
Show file tree
Hide file tree
Changes from 62 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
c64933d
setup db schema for organisations
devgenix Sep 13, 2023
f406233
fix requested changes
devgenix Sep 13, 2023
1dc844a
Update agenta-backend/agenta_backend/models/db_models.py
devgenix Sep 13, 2023
204e007
fix members field
devgenix Sep 13, 2023
2736ad1
Merge branch '#58-oss-ability-to-invite-users-to-organizations' of ht…
devgenix Sep 13, 2023
43b334a
add owners and members
devgenix Sep 13, 2023
320b796
modify get_user_objectid to return list of organization ids
devgenix Sep 13, 2023
b8a99fc
format with black
devgenix Sep 13, 2023
0b73e9e
updated get user's organisations
devgenix Sep 13, 2023
180d1c8
switch to odmantic
devgenix Sep 13, 2023
c905c7e
return ids in get_user_and_org_id
devgenix Sep 13, 2023
0e288d6
added forward ref
devgenix Sep 13, 2023
041cbf2
update get_user_object to use organisations
devgenix Sep 13, 2023
ee85443
change organizations to use objectid to avoid circular import
devgenix Sep 13, 2023
99903f1
modify get_organisation & get apps fromorg and user
devgenix Sep 13, 2023
e06d9b1
format black
devgenix Sep 13, 2023
5bf5fc8
Merge branch 'Agenta-AI:main' into #58-oss-ability-to-invite-users-to…
devgenix Sep 14, 2023
bd32422
remove debugging
devgenix Sep 14, 2023
2d83f22
Merge branch '#58-oss-ability-to-invite-users-to-organizations' of ht…
devgenix Sep 14, 2023
c769ffc
change get organisation format
devgenix Sep 14, 2023
71e3f32
installed sendgrid
devgenix Sep 14, 2023
c0e9d9a
built func to generate token by length
devgenix Sep 15, 2023
89874ba
created organisation router
devgenix Sep 15, 2023
864c072
create db schema for org invites
devgenix Sep 15, 2023
358a0b9
update model referenc to follow new schema
devgenix Sep 15, 2023
1c9b59e
remove org_instance to comply with ee
devgenix Sep 15, 2023
e6e0ad0
defined Organizational types
devgenix Sep 15, 2023
8ff61f3
exclude file from black
devgenix Sep 15, 2023
20abb0f
run black
devgenix Sep 15, 2023
14d808f
feat: allow users to invite and join organizations
devgenix Sep 15, 2023
6858850
switch to using payload data.
devgenix Sep 15, 2023
235cf67
undo change to workflow
devgenix Sep 15, 2023
59d25d2
fix resolve pr comments
devgenix Sep 15, 2023
338b248
global organization name refactor & optmised perf with sets
devgenix Sep 15, 2023
80d8502
format black
devgenix Sep 15, 2023
be83f4e
move org funcs to ee
devgenix Sep 15, 2023
94331a2
add type to organizationDB
devgenix Sep 18, 2023
16c82ae
add organization_id to AppVariant type
devgenix Sep 18, 2023
a9d7610
move dbegine to common to avoid circular import
devgenix Sep 18, 2023
01febad
improve functions
devgenix Sep 18, 2023
a4e37f7
use try except & create user based on feature flag
devgenix Sep 18, 2023
3f7e639
define get_user_own_org
devgenix Sep 18, 2023
638cfdf
save AppVariant with organization based on condition
devgenix Sep 18, 2023
208353c
fix requested changes
devgenix Sep 18, 2023
3f73b57
fix minor issues
devgenix Sep 18, 2023
5f12960
Merge branch 'main' into #58-oss-email-invitations-to-join-an-organiz…
devgenix Sep 19, 2023
83a8274
remove router
devgenix Sep 19, 2023
20e5565
ran format black
devgenix Sep 19, 2023
b8b5962
update db schema
devgenix Sep 19, 2023
ea60381
use BaseModel and add fields
devgenix Sep 19, 2023
c37dd73
fix get org apps & create user, org; use org in add app from variant …
devgenix Sep 19, 2023
9e149f0
use user.id for irg owner
devgenix Sep 19, 2023
a9cec29
move token function to ee
devgenix Sep 19, 2023
c0afa59
update local with remote
devgenix Sep 19, 2023
c59315c
ran format black
devgenix Sep 19, 2023
cefddcb
resolved poetry
devgenix Sep 19, 2023
867be6b
Merge branch 'main' into #58-oss-email-invitations-to-join-an-organiz…
devgenix Sep 20, 2023
f7cf526
return list_apps by org_id if present
devgenix Sep 20, 2023
620e078
update local with remote
devgenix Sep 20, 2023
20e6345
oss sync with frontend request improvements
devgenix Sep 20, 2023
fd2f092
sync with frontend enpoints request
devgenix Sep 20, 2023
f7b1068
create user profile router and endpoint
devgenix Sep 20, 2023
4753be2
remove org ee router
devgenix Sep 21, 2023
b73d727
ran format black
devgenix Sep 21, 2023
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
2 changes: 1 addition & 1 deletion agenta-backend/agenta_backend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from agenta_backend.models.api.user_models import User
from agenta_backend.models.api.organization_models import Organization
from agenta_backend.services.user_service import create_new_user
from agenta_backend.services.organization_service import (
from agenta_backend.ee.services.organization_service import (
create_new_organization,
)
from agenta_backend.config import settings
Expand Down
4 changes: 4 additions & 0 deletions agenta-backend/agenta_backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from agenta_backend.config import settings
from agenta_backend.routers import (
app_variant,
user_profile,
container_router,
environment_router,
evaluation_router,
Expand Down Expand Up @@ -80,6 +81,7 @@ async def lifespan(application: FastAPI, cache=True):


app = FastAPI(lifespan=lifespan)
app.include_router(user_profile.router, prefix="/profile")
app.include_router(app_variant.router, prefix="/app_variant")
app.include_router(evaluation_router.router, prefix="/evaluations")
app.include_router(testset_router.router, prefix="/testsets")
Expand All @@ -90,7 +92,9 @@ async def lifespan(application: FastAPI, cache=True):

if os.environ["FEATURE_FLAG"] in ["cloud", "ee", "demo"]:
import agenta_backend.ee.main as ee
from agenta_backend.ee.routers import organization_router

app.include_router(organization_router.router, prefix="/organizations")
devgenix marked this conversation as resolved.
Show resolved Hide resolved
app, allow_headers = ee.extend_main(app)
# this is the prefix in which we are reverse proxying the api
#
Expand Down
7 changes: 7 additions & 0 deletions agenta-backend/agenta_backend/models/api/api_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class AppVariant(BaseModel):
variant_name: str
parameters: Optional[Dict[str, Any]]
previous_variant_name: Optional[str]
organization_id: Optional[str]


class RestartAppContainer(BaseModel):
Expand Down Expand Up @@ -62,6 +63,12 @@ class CreateAppVariant(BaseModel):
image_tag: str
env_vars: Dict[str, str]

class InviteRequest(BaseModel):
email: str


class InviteToken(BaseModel):
token: str

class Environment(BaseModel):
name: str
Expand Down
10 changes: 8 additions & 2 deletions agenta-backend/agenta_backend/models/api/organization_models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Optional
from datetime import datetime
from bson import ObjectId
from typing import Optional, List
from pydantic import BaseModel, Field


Expand All @@ -8,9 +9,14 @@ class TimestampModel(BaseModel):
updated_at: datetime = Field(datetime.utcnow())


class Organization(TimestampModel):
class Organization(BaseModel):
id: Optional[str]
name: str
description: Optional[str]
type: Optional[str]
owner: str
members: Optional[List[str]]
invitations: Optional[List]


class OrganizationUpdate(BaseModel):
Expand Down
5 changes: 3 additions & 2 deletions agenta-backend/agenta_backend/models/api/user_models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import Optional
from datetime import datetime
from typing import Optional, List
from pydantic import BaseModel, Field


Expand All @@ -9,10 +9,11 @@ class TimestampModel(BaseModel):


class User(TimestampModel):
id: Optional[str]
uid: str
username: str
email: str # switch to EmailStr when langchain support pydantic>=2.1
devgenix marked this conversation as resolved.
Show resolved Hide resolved
organization_id: str
organizations: Optional[List[str]]


class UserUpdate(BaseModel):
Expand Down
23 changes: 19 additions & 4 deletions agenta-backend/agenta_backend/models/db_models.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
from datetime import datetime
from typing import Any, Dict, List, Optional
from bson import ObjectId
from datetime import datetime, timedelta
from typing import Optional, Dict, Any, List
from odmantic import Field, Model, Reference, EmbeddedModel

from odmantic import EmbeddedModel, Field, Model, Reference

class InvitationDB(EmbeddedModel):
token: str = Field(unique=True)
email: str
expiration_date: datetime = Field(default="0")
used: bool = False


class OrganizationDB(Model):
name: str = Field(default="agenta")
description: str = Field(default="")
type: Optional[str]
owner: str
members: Optional[List[ObjectId]]
invitations: Optional[List[InvitationDB]] = []

class Config:
collection = "organizations"
Expand All @@ -16,7 +27,7 @@ class UserDB(Model):
uid: str = Field(default="0", unique=True, index=True)
username: str = Field(default="agenta")
email: str = Field(default="[email protected]", unique=True)
organization_id: OrganizationDB = Reference(key_name="org")
organizations: Optional[List[ObjectId]] = []

class Config:
collection = "users"
Expand All @@ -42,6 +53,7 @@ class AppVariantDB(Model):
user_id: UserDB = Reference(key_name="user")
parameters: Dict[str, Any] = Field(default=dict)
previous_variant_name: Optional[str]
organization_id: Optional[str]
is_deleted: bool = Field(
default=False
) # soft deletion for using the template variants
Expand Down Expand Up @@ -104,6 +116,7 @@ class EvaluationDB(Model):
app_name: str
testset: Dict[str, str]
user: UserDB = Reference(key_name="user")
organization_id: Optional[str]
created_at: Optional[datetime] = Field(default=datetime.utcnow())
updated_at: Optional[datetime] = Field(default=datetime.utcnow())

Expand All @@ -119,6 +132,7 @@ class EvaluationScenarioDB(Model):
evaluation: Optional[str]
evaluation_id: str
user: UserDB = Reference(key_name="user")
organization_id: Optional[str]
correct_answer: Optional[str]
created_at: Optional[datetime] = Field(default=datetime.utcnow())
updated_at: Optional[datetime] = Field(default=datetime.utcnow())
Expand All @@ -144,6 +158,7 @@ class TestSetDB(Model):
app_name: str
csvdata: List[Dict[str, str]]
user: UserDB = Reference(key_name="user")
organization_id: Optional[str]
created_at: Optional[datetime] = Field(default=datetime.utcnow())
updated_at: Optional[datetime] = Field(default=datetime.utcnow())

Expand Down
3 changes: 2 additions & 1 deletion agenta-backend/agenta_backend/routers/app_variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ async def get_variant_by_env(

@router.get("/list_apps/", response_model=List[App])
async def list_apps(
org_id: Optional[str] = None,
stoken_session: SessionContainer = Depends(verify_session()),
) -> List[App]:
"""Lists the apps from our repository.
Expand All @@ -147,7 +148,7 @@ async def list_apps(
"""
try:
kwargs: dict = await get_user_and_org_id(stoken_session)
apps = await db_manager.list_apps(**kwargs)
apps = await db_manager.list_apps(org_id, **kwargs)
return apps
except Exception as e:
logger.error(f"list_apps exception ===> {e}")
Expand Down
3 changes: 2 additions & 1 deletion agenta-backend/agenta_backend/routers/evaluation_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
create_custom_code_evaluation,
execute_custom_code_evaluation,
)
from agenta_backend.services.db_manager import engine, query, get_user_object
from agenta_backend.utills.common import engine
from agenta_backend.services.db_manager import query, get_user_object
from agenta_backend.models.db_models import EvaluationDB, EvaluationScenarioDB
from agenta_backend.config import settings

Expand Down
3 changes: 2 additions & 1 deletion agenta-backend/agenta_backend/routers/testset_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
TestSetOutputResponse,
)
from agenta_backend.config import settings
from agenta_backend.utills.common import engine
from agenta_backend.models.db_models import TestSetDB
from agenta_backend.services.db_manager import engine, query, get_user_object
from agenta_backend.services.db_manager import query, get_user_object


upload_folder = "./path/to/upload/folder"
Expand Down
40 changes: 40 additions & 0 deletions agenta-backend/agenta_backend/routers/user_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import os
from agenta_backend.utills.common import engine
from agenta_backend.services.db_manager import UserDB
from fastapi import APIRouter, HTTPException, Depends
from agenta_backend.models.api.user_models import User

router = APIRouter()

if os.environ["FEATURE_FLAG"] in ["cloud", "ee", "demo"]:
from agenta_backend.ee.services.auth_helper import (
SessionContainer,
verify_session,
)
from agenta_backend.ee.services.selectors import get_user_and_org_id
else:
from agenta_backend.services.auth_helper import (
SessionContainer,
verify_session,
)
from agenta_backend.services.selectors import get_user_and_org_id

@router.get("/")
async def user_profile(
stoken_session: SessionContainer = Depends(verify_session()),
):

try:

kwargs: dict = await get_user_and_org_id(stoken_session)
user = await engine.find_one(UserDB, UserDB.uid == kwargs["uid"])
return User(
id=str(user.id),
uid=str(user.uid),
username=str(user.username),
email=str(user.email)
).dict(exclude_unset=True)

except Exception as e:
raise HTTPException(status_code=500, detail=str(e))

Loading