"backend/vscode:/vscode.git/clone" did not exist on "72354e06a759075024d6be6bc6a8e717ec29d823"
users.py 7.76 KB
Newer Older
1
from pydantic import BaseModel, ConfigDict, parse_obj_as
2
3
from typing import List, Union, Optional
import time
4
5
6
7

from sqlalchemy import String, Column, BigInteger, Text
from sqlalchemy.orm import Session

Timothy J. Baek's avatar
Timothy J. Baek committed
8
9
from utils.misc import get_gravatar_url

10
from apps.webui.internal.db import Base, JSONField, get_session
11
from apps.webui.models.chats import Chats
12

13
14
15
16
17
####################
# User DB Schema
####################


18
19
class User(Base):
    __tablename__ = "user"
Timothy J. Baek's avatar
Timothy J. Baek committed
20

21
22
23
24
25
    id = Column(String, primary_key=True)
    name = Column(String)
    email = Column(String)
    role = Column(String)
    profile_image_url = Column(String)
Timothy J. Baek's avatar
Timothy J. Baek committed
26

27
28
29
    last_active_at = Column(BigInteger)
    updated_at = Column(BigInteger)
    created_at = Column(BigInteger)
Timothy J. Baek's avatar
Timothy J. Baek committed
30

31
32
33
    api_key = Column(String, nullable=True, unique=True)
    settings = Column(JSONField, nullable=True)
    info = Column(JSONField, nullable=True)
34

35
    oauth_sub = Column(Text, unique=True)
Timothy J. Baek's avatar
Timothy J. Baek committed
36
37


38
39
40
41
42
43
class UserSettings(BaseModel):
    ui: Optional[dict] = {}
    model_config = ConfigDict(extra="allow")
    pass


44
45
46
47
class UserModel(BaseModel):
    id: str
    name: str
    email: str
Timothy J. Baek's avatar
Timothy J. Baek committed
48
    role: str = "pending"
49
    profile_image_url: str
Timothy J. Baek's avatar
Timothy J. Baek committed
50
51
52
53
54

    last_active_at: int  # timestamp in epoch
    updated_at: int  # timestamp in epoch
    created_at: int  # timestamp in epoch

55
    api_key: Optional[str] = None
56
    settings: Optional[UserSettings] = None
Timothy J. Baek's avatar
Timothy J. Baek committed
57
    info: Optional[dict] = None
58

59
60
    oauth_sub: Optional[str] = None

61
62
    model_config = ConfigDict(from_attributes=True)

63
64
65
66
67
68

####################
# Forms
####################


Timothy J. Baek's avatar
Timothy J. Baek committed
69
70
71
72
73
class UserRoleUpdateForm(BaseModel):
    id: str
    role: str


Timothy J. Baek's avatar
Timothy J. Baek committed
74
75
76
77
78
79
class UserUpdateForm(BaseModel):
    name: str
    email: str
    profile_image_url: str
    password: Optional[str] = None

80

Timothy J. Baek's avatar
Timothy J. Baek committed
81
class UsersTable:
82

Timothy J. Baek's avatar
Timothy J. Baek committed
83
    def insert_new_user(
Danny Liu's avatar
Danny Liu committed
84
85
86
87
        self,
        id: str,
        name: str,
        email: str,
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
88
        profile_image_url: str = "/user.png",
Danny Liu's avatar
Danny Liu committed
89
        role: str = "pending",
90
        oauth_sub: Optional[str] = None,
Timothy J. Baek's avatar
Timothy J. Baek committed
91
    ) -> Optional[UserModel]:
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
        with get_session() as db:
            user = UserModel(
                **{
                    "id": id,
                    "name": name,
                    "email": email,
                    "role": role,
                    "profile_image_url": profile_image_url,
                    "last_active_at": int(time.time()),
                    "created_at": int(time.time()),
                    "updated_at": int(time.time()),
                    "oauth_sub": oauth_sub,
                }
            )
            result = User(**user.model_dump())
            db.add(result)
            db.commit()
            db.refresh(result)
            if result:
                return user
            else:
                return None

    def get_user_by_id(self, id: str) -> Optional[UserModel]:
        with get_session() as db:
            try:
                user = db.query(User).filter_by(id=id).first()
                return UserModel.model_validate(user)
            except Exception as e:
                return None

    def get_user_by_api_key(self, api_key: str) -> Optional[UserModel]:
        with get_session() as db:
            try:
                user = db.query(User).filter_by(api_key=api_key).first()
                return UserModel.model_validate(user)
            except:
                return None

    def get_user_by_email(self, email: str) -> Optional[UserModel]:
        with get_session() as db:
            try:
                user = db.query(User).filter_by(email=email).first()
                return UserModel.model_validate(user)
            except:
                return None
138

139
    def get_user_by_oauth_sub(self, sub: str) -> Optional[UserModel]:
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
        with get_session() as db:
            try:
                user = db.query(User).filter_by(oauth_sub=sub).first()
                return UserModel.model_validate(user)
            except:
                return None

    def get_users(self, skip: int = 0, limit: int = 50) -> List[UserModel]:
        with get_session() as db:
            users = (
                db.query(User)
                # .offset(skip).limit(limit)
                .all()
            )
            return [UserModel.model_validate(user) for user in users]

    def get_num_users(self) -> Optional[int]:
        with get_session() as db:
            return db.query(User).count()

    def get_first_user(self) -> UserModel:
        with get_session() as db:
            try:
                user = db.query(User).order_by(User.created_at).first()
                return UserModel.model_validate(user)
            except:
                return None
167

168
    def update_user_role_by_id(self, id: str, role: str) -> Optional[UserModel]:
169
170
171
172
        with get_session() as db:
            try:
                db.query(User).filter_by(id=id).update({"role": role})
                db.commit()
Timothy J. Baek's avatar
Timothy J. Baek committed
173

174
175
176
177
                user = db.query(User).filter_by(id=id).first()
                return UserModel.model_validate(user)
            except:
                return None
Timothy J. Baek's avatar
Timothy J. Baek committed
178

179
    def update_user_profile_image_url_by_id(
180
        self, id: str, profile_image_url: str
181
    ) -> Optional[UserModel]:
182
183
184
185
186
187
        with get_session() as db:
            try:
                db.query(User).filter_by(id=id).update(
                    {"profile_image_url": profile_image_url}
                )
                db.commit()
188

189
190
191
192
                user = db.query(User).filter_by(id=id).first()
                return UserModel.model_validate(user)
            except:
                return None
193

194
    def update_user_last_active_by_id(self, id: str) -> Optional[UserModel]:
195
196
        with get_session() as db:
            try:
197
198
199
                db.query(User).filter_by(id=id).update(
                    {"last_active_at": int(time.time())}
                )
Timothy J. Baek's avatar
Timothy J. Baek committed
200

201
202
203
204
                user = db.query(User).filter_by(id=id).first()
                return UserModel.model_validate(user)
            except:
                return None
Timothy J. Baek's avatar
Timothy J. Baek committed
205

206
    def update_user_oauth_sub_by_id(
207
        self, id: str, oauth_sub: str
208
    ) -> Optional[UserModel]:
209
210
211
        with get_session() as db:
            try:
                db.query(User).filter_by(id=id).update({"oauth_sub": oauth_sub})
212

213
214
215
216
                user = db.query(User).filter_by(id=id).first()
                return UserModel.model_validate(user)
            except:
                return None
217

218
    def update_user_by_id(self, id: str, updated: dict) -> Optional[UserModel]:
219
220
221
222
        with get_session() as db:
            try:
                db.query(User).filter_by(id=id).update(updated)
                db.commit()
Timothy J. Baek's avatar
Timothy J. Baek committed
223

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
                user = db.query(User).filter_by(id=id).first()
                return UserModel.model_validate(user)
                # return UserModel(**user.dict())
            except Exception as e:
                return None

    def delete_user_by_id(self, id: str) -> bool:
        with get_session() as db:
            try:
                # Delete User Chats
                result = Chats.delete_chats_by_user_id(id)

                if result:
                    # Delete User
                    db.query(User).filter_by(id=id).delete()
                    db.commit()

                    return True
                else:
                    return False
            except:
                return False
246

247
248
249
250
    def update_user_api_key_by_id(self, id: str, api_key: str) -> str:
        with get_session() as db:
            try:
                result = db.query(User).filter_by(id=id).update({"api_key": api_key})
251
                db.commit()
252
253
                return True if result == 1 else False
            except:
254
                return False
255

256
257
258
259
260
261
262
    def get_user_api_key_by_id(self, id: str) -> Optional[str]:
        with get_session() as db:
            try:
                user = db.query(User).filter_by(id=id).first()
                return user.api_key
            except Exception as e:
                return None
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
263

264

265
Users = UsersTable()