mirror of
https://github.com/open-webui/open-webui.git
synced 2026-02-24 12:11:56 +01:00
refac: defer profile
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import time
|
||||
from typing import Optional
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.orm import Session, defer
|
||||
from open_webui.internal.db import Base, JSONField, get_db, get_db_context
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ from open_webui.utils.misc import throttle
|
||||
from open_webui.utils.validate import validate_profile_image_url
|
||||
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, field_validator
|
||||
from pydantic import BaseModel, ConfigDict, field_validator, model_validator
|
||||
from sqlalchemy import (
|
||||
BigInteger,
|
||||
JSON,
|
||||
@@ -28,7 +28,7 @@ from sqlalchemy import (
|
||||
select,
|
||||
cast,
|
||||
)
|
||||
from sqlalchemy import or_, case
|
||||
from sqlalchemy import or_, case, func
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
|
||||
import datetime
|
||||
@@ -86,7 +86,7 @@ class UserModel(BaseModel):
|
||||
|
||||
name: str
|
||||
|
||||
profile_image_url: str
|
||||
profile_image_url: Optional[str] = None
|
||||
profile_banner_image_url: Optional[str] = None
|
||||
|
||||
bio: Optional[str] = None
|
||||
@@ -110,6 +110,12 @@ class UserModel(BaseModel):
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def set_profile_image_url(self):
|
||||
if not self.profile_image_url:
|
||||
self.profile_image_url = f"/api/v1/users/{self.id}/profile/image"
|
||||
return self
|
||||
|
||||
|
||||
class UserStatusModel(UserModel):
|
||||
is_active: bool = False
|
||||
@@ -315,8 +321,12 @@ class UsersTable:
|
||||
) -> Optional[UserModel]:
|
||||
try:
|
||||
with get_db_context(db) as db:
|
||||
user = db.query(User).filter_by(email=email).first()
|
||||
return UserModel.model_validate(user)
|
||||
user = (
|
||||
db.query(User)
|
||||
.filter(func.lower(User.email) == email.lower())
|
||||
.first()
|
||||
)
|
||||
return UserModel.model_validate(user) if user else None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
@@ -350,7 +360,7 @@ class UsersTable:
|
||||
) -> dict:
|
||||
with get_db_context(db) as db:
|
||||
# Join GroupMember so we can order by group_id when requested
|
||||
query = db.query(User)
|
||||
query = db.query(User).options(defer(User.profile_image_url))
|
||||
|
||||
if filter:
|
||||
query_key = filter.get("query")
|
||||
@@ -485,6 +495,7 @@ class UsersTable:
|
||||
with get_db_context(db) as db:
|
||||
users = (
|
||||
db.query(User)
|
||||
.options(defer(User.profile_image_url))
|
||||
.join(GroupMember, User.id == GroupMember.user_id)
|
||||
.filter(GroupMember.group_id == group_id)
|
||||
.all()
|
||||
@@ -495,7 +506,7 @@ class UsersTable:
|
||||
self, user_ids: list[str], db: Optional[Session] = None
|
||||
) -> list[UserStatusModel]:
|
||||
with get_db_context(db) as db:
|
||||
users = db.query(User).filter(User.id.in_(user_ids)).all()
|
||||
users = db.query(User).options(defer(User.profile_image_url)).filter(User.id.in_(user_ids)).all()
|
||||
return [UserModel.model_validate(user) for user in users]
|
||||
|
||||
def get_num_users(self, db: Optional[Session] = None) -> Optional[int]:
|
||||
|
||||
@@ -145,7 +145,7 @@ def create_session_response(
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"role": user.role,
|
||||
"profile_image_url": user.profile_image_url,
|
||||
"profile_image_url": f"/api/v1/users/{user.id}/profile/image",
|
||||
"permissions": user_permissions,
|
||||
}
|
||||
|
||||
@@ -926,7 +926,7 @@ async def add_user(
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"role": user.role,
|
||||
"profile_image_url": user.profile_image_url,
|
||||
"profile_image_url": f"/api/v1/users/{user.id}/profile/image",
|
||||
}
|
||||
else:
|
||||
raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR)
|
||||
|
||||
@@ -314,7 +314,13 @@ async def connect(sid, environ, auth):
|
||||
|
||||
if user:
|
||||
SESSION_POOL[sid] = user.model_dump(
|
||||
exclude=["date_of_birth", "bio", "gender"]
|
||||
exclude=[
|
||||
"profile_image_url",
|
||||
"profile_banner_image_url",
|
||||
"date_of_birth",
|
||||
"bio",
|
||||
"gender",
|
||||
]
|
||||
)
|
||||
await sio.enter_room(sid, f"user:{user.id}")
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ def _assert_user(data, id, **kwargs):
|
||||
comparison_data = {
|
||||
"name": f"user {id}",
|
||||
"email": f"user{id}@openwebui.com",
|
||||
"profile_image_url": f"/user{id}.png",
|
||||
"profile_image_url": f"/api/v1/users/{id}/profile/image",
|
||||
"role": "user",
|
||||
**kwargs,
|
||||
}
|
||||
@@ -150,7 +150,7 @@ class TestUsers(AbstractPostgresTest):
|
||||
role="admin",
|
||||
name="user 2 updated",
|
||||
email="user2-updated@openwebui.com",
|
||||
profile_image_url="/user2-updated.png",
|
||||
profile_image_url=f"/api/v1/users/2/profile/image",
|
||||
)
|
||||
|
||||
# Delete user by id
|
||||
|
||||
Reference in New Issue
Block a user