feat: add upsert identities properties route (#1672)
This commit is contained in:
@@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, List, Optional
|
||||
from fastapi import APIRouter, Body, Depends, Header, HTTPException, Query
|
||||
|
||||
from letta.orm.errors import NoResultFound, UniqueConstraintViolationError
|
||||
from letta.schemas.identity import Identity, IdentityCreate, IdentityType, IdentityUpdate
|
||||
from letta.schemas.identity import Identity, IdentityCreate, IdentityProperty, IdentityType, IdentityUpdate
|
||||
from letta.server.rest_api.utils import get_letta_server
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -125,6 +125,24 @@ def modify_identity(
|
||||
raise HTTPException(status_code=500, detail=f"{e}")
|
||||
|
||||
|
||||
@router.put("/{identity_id}/properties", tags=["identities"], operation_id="upsert_identity_properties")
|
||||
def upsert_identity_properties(
|
||||
identity_id: str,
|
||||
properties: List[IdentityProperty] = Body(...),
|
||||
server: "SyncServer" = Depends(get_letta_server),
|
||||
actor_id: Optional[str] = Header(None, alias="user_id"), # Extract user_id from header, default to None if not present
|
||||
):
|
||||
try:
|
||||
actor = server.user_manager.get_user_or_default(user_id=actor_id)
|
||||
return server.identity_manager.upsert_identity_properties(identity_id=identity_id, properties=properties, actor=actor)
|
||||
except HTTPException:
|
||||
raise
|
||||
except NoResultFound as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"{e}")
|
||||
|
||||
|
||||
@router.delete("/{identity_id}", tags=["identities"], operation_id="delete_identity")
|
||||
def delete_identity(
|
||||
identity_id: str,
|
||||
|
||||
@@ -8,7 +8,7 @@ from letta.orm.agent import Agent as AgentModel
|
||||
from letta.orm.block import Block as BlockModel
|
||||
from letta.orm.identity import Identity as IdentityModel
|
||||
from letta.schemas.identity import Identity as PydanticIdentity
|
||||
from letta.schemas.identity import IdentityCreate, IdentityType, IdentityUpdate
|
||||
from letta.schemas.identity import IdentityCreate, IdentityProperty, IdentityType, IdentityUpdate
|
||||
from letta.schemas.user import User as PydanticUser
|
||||
from letta.utils import enforce_types
|
||||
|
||||
@@ -165,6 +165,20 @@ class IdentityManager:
|
||||
existing_identity.update(session, actor=actor)
|
||||
return existing_identity.to_pydantic()
|
||||
|
||||
@enforce_types
|
||||
def upsert_identity_properties(self, identity_id: str, properties: List[IdentityProperty], actor: PydanticUser) -> PydanticIdentity:
|
||||
with self.session_maker() as session:
|
||||
existing_identity = IdentityModel.read(db_session=session, identifier=identity_id, actor=actor)
|
||||
if existing_identity is None:
|
||||
raise HTTPException(status_code=404, detail="Identity not found")
|
||||
return self._update_identity(
|
||||
session=session,
|
||||
existing_identity=existing_identity,
|
||||
identity=IdentityUpdate(properties=properties),
|
||||
actor=actor,
|
||||
replace=True,
|
||||
)
|
||||
|
||||
@enforce_types
|
||||
def delete_identity(self, identity_id: str, actor: PydanticUser) -> None:
|
||||
with self.session_maker() as session:
|
||||
|
||||
@@ -3488,6 +3488,34 @@ def test_get_set_blocks_for_identities(server: SyncServer, default_block, defaul
|
||||
server.identity_manager.delete_identity(identity.id, actor=default_user)
|
||||
|
||||
|
||||
def test_upsert_properties(server: SyncServer, default_user):
|
||||
identity_create = IdentityCreate(
|
||||
identifier_key="1234",
|
||||
name="caren",
|
||||
identity_type=IdentityType.user,
|
||||
properties=[
|
||||
IdentityProperty(key="email", value="caren@letta.com", type=IdentityPropertyType.string),
|
||||
IdentityProperty(key="age", value=28, type=IdentityPropertyType.number),
|
||||
],
|
||||
)
|
||||
|
||||
identity = server.identity_manager.create_identity(identity_create, actor=default_user)
|
||||
properties = [
|
||||
IdentityProperty(key="email", value="caren@gmail.com", type=IdentityPropertyType.string),
|
||||
IdentityProperty(key="age", value="28", type=IdentityPropertyType.string),
|
||||
IdentityProperty(key="test", value=123, type=IdentityPropertyType.number),
|
||||
]
|
||||
|
||||
updated_identity = server.identity_manager.upsert_identity_properties(
|
||||
identity_id=identity.id,
|
||||
properties=properties,
|
||||
actor=default_user,
|
||||
)
|
||||
assert updated_identity.properties == properties
|
||||
|
||||
server.identity_manager.delete_identity(identity.id, actor=default_user)
|
||||
|
||||
|
||||
# ======================================================================================================================
|
||||
# SourceManager Tests - Sources
|
||||
# ======================================================================================================================
|
||||
|
||||
Reference in New Issue
Block a user