mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-15 00:22:34 +00:00
feat: expose user_email in organization members response
Add user_email field to LiteLLM_OrganizationMembershipTable with a model_validator that populates it from the nested user object, and update the /organization/info Prisma query to select user_email from the related user record. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2437,9 +2437,19 @@ class LiteLLM_OrganizationMembershipTable(LiteLLMPydanticObjectBase):
|
||||
Any
|
||||
] = None # You might want to replace 'Any' with a more specific type if available
|
||||
litellm_budget_table: Optional[LiteLLM_BudgetTable] = None
|
||||
user_email: Optional[str] = None
|
||||
|
||||
model_config = ConfigDict(protected_namespaces=())
|
||||
|
||||
@model_validator(mode="after")
|
||||
def populate_user_email(self) -> "LiteLLM_OrganizationMembershipTable":
|
||||
if self.user_email is None and self.user is not None:
|
||||
if isinstance(self.user, dict):
|
||||
self.user_email = self.user.get("user_email")
|
||||
else:
|
||||
self.user_email = getattr(self.user, "user_email", None)
|
||||
return self
|
||||
|
||||
|
||||
class LiteLLM_OrganizationTableUpdate(LiteLLM_BudgetTable):
|
||||
"""Represents user-controllable params for a LiteLLM_OrganizationTable record"""
|
||||
|
||||
@@ -721,7 +721,13 @@ async def info_organization(organization_id: str):
|
||||
where={"organization_id": organization_id},
|
||||
include={
|
||||
"litellm_budget_table": True,
|
||||
"members": True,
|
||||
"members": {
|
||||
"include": {
|
||||
"user": {
|
||||
"select": {"user_email": True},
|
||||
}
|
||||
}
|
||||
},
|
||||
"teams": True,
|
||||
"object_permission": True,
|
||||
},
|
||||
|
||||
@@ -535,3 +535,28 @@ async def test_list_organization_filter_by_org_alias(monkeypatch):
|
||||
"members": True,
|
||||
"teams": True,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_organization_info_includes_user_email(monkeypatch):
|
||||
"""
|
||||
Test that GET /organization/info returns user_email in members list.
|
||||
"""
|
||||
from litellm.proxy._types import LiteLLM_OrganizationMembershipTable
|
||||
from datetime import datetime
|
||||
|
||||
# Simulate a membership row with a nested user object that has user_email
|
||||
raw_membership = {
|
||||
"user_id": "user_abc",
|
||||
"organization_id": "org_xyz",
|
||||
"user_role": "org_admin",
|
||||
"spend": 0.0,
|
||||
"budget_id": None,
|
||||
"created_at": datetime.utcnow(),
|
||||
"updated_at": datetime.utcnow(),
|
||||
"user": {"user_email": "alice@example.com"},
|
||||
"litellm_budget_table": None,
|
||||
}
|
||||
|
||||
membership = LiteLLM_OrganizationMembershipTable(**raw_membership)
|
||||
assert membership.user_email == "alice@example.com"
|
||||
|
||||
Reference in New Issue
Block a user