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: db migration #3595

Merged
merged 34 commits into from
Jul 6, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift click to select a range
df09d08
feat(sqlalchemy): Replace peewee with sqlalchemy
jonathan-rohde Jun 18, 2024
bee835c
feat(sqlalchemy): remove session reference from router
jonathan-rohde Jun 21, 2024
070d908
feat(sqlalchemy): use subprocess to do migrations
jonathan-rohde Jun 24, 2024
320e658
feat(sqlalchemy): cleanup fixes
jonathan-rohde Jun 24, 2024
c134eab
feat(sqlalchemy): format backend
jonathan-rohde Jun 24, 2024
eb01e8d
feat(sqlalchemy): use scoped session
jonathan-rohde Jun 24, 2024
da403f3
feat(sqlalchemy): use session factory instead of context manager
jonathan-rohde Jun 24, 2024
a9b1487
feat(sqlalchemy): fix wrong column types
jonathan-rohde Jun 24, 2024
8f939cf
feat(sqlalchemy): some fixes
jonathan-rohde Jun 24, 2024
2fb27ad
feat(sqlalchemy): add missing file
jonathan-rohde Jun 24, 2024
d88bd51
feat(sqlalchemy): format backend
jonathan-rohde Jun 24, 2024
642c352
feat(sqlalchemy): rebase
jonathan-rohde Jun 25, 2024
d4b6b7c
feat(sqlalchemy): reverted not needed api change
jonathan-rohde Jun 25, 2024
23e4d9d
feat(sqlalchemy): formatting
jonathan-rohde Jun 25, 2024
827b1e5
feat(sqlalchemy): execute tests in github actions
jonathan-rohde Jun 25, 2024
df47c49
Merge branch 'refs/heads/dev' into feat/sqlalchemy-instead-of-peewee
jonathan-rohde Jun 28, 2024
5391f4c
feat(sqlalchemy): add new column
jonathan-rohde Jun 28, 2024
2aecd7d
Merge branch 'refs/heads/dev' into feat/sqlalchemy-instead-of-peewee
jonathan-rohde Jul 1, 2024
d0e89a0
Merge pull request #3327 from jonathan-rohde/feat/sqlalchemy-instead-…
tjbck Jul 2, 2024
647aa19
chore: format
tjbck Jul 2, 2024
44a9b86
fix: functions
tjbck Jul 3, 2024
aa88022
fix: functions
tjbck Jul 3, 2024
4d23957
revert: model_validate
tjbck Jul 3, 2024
0d78b63
Merge pull request #3621 from open-webui/dev
tjbck Jul 4, 2024
15f6f7b
revert: peewee migrations
tjbck Jul 4, 2024
bfc53b4
revert
tjbck Jul 4, 2024
1b65df3
revert
tjbck Jul 4, 2024
8646460
refac
tjbck Jul 4, 2024
37a5d2c
Update db.py
tjbck Jul 4, 2024
8fe2a7b
fix
tjbck Jul 4, 2024
8b13755
Update auths.py
tjbck Jul 4, 2024
d60f066
Merge pull request #3668 from open-webui/dev
tjbck Jul 6, 2024
1436bb7
enh: handle peewee migration
tjbck Jul 6, 2024
4e75150
Merge pull request #3669 from open-webui/dev-migration-session
tjbck Jul 6, 2024
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
Prev Previous commit
Next Next commit
feat(sqlalchemy): remove session reference from router
  • Loading branch information
jonathan-rohde committed Jun 27, 2024
commit bee835cb65a8b3feba6824d2e6c9378b95f6e990
7 changes: 2 additions & 5 deletions backend/apps/ollama/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 31,6 @@

from starlette.background import BackgroundTask

from apps.webui.internal.db import get_db
from apps.webui.models.models import Models
from apps.webui.models.users import Users
from constants import ERROR_MESSAGES
Expand Down Expand Up @@ -712,7 711,6 @@ async def generate_chat_completion(
form_data: GenerateChatCompletionForm,
url_idx: Optional[int] = None,
user=Depends(get_verified_user),
db=Depends(get_db),
):

log.debug(
Expand All @@ -726,7 724,7 @@ async def generate_chat_completion(
}

model_id = form_data.model
model_info = Models.get_model_by_id(db, model_id)
model_info = Models.get_model_by_id(model_id)

if model_info:
if model_info.base_model_id:
Expand Down Expand Up @@ -885,7 883,6 @@ async def generate_openai_chat_completion(
form_data: dict,
url_idx: Optional[int] = None,
user=Depends(get_verified_user),
db=Depends(get_db),
):
form_data = OpenAIChatCompletionForm(**form_data)

Expand All @@ -894,7 891,7 @@ async def generate_openai_chat_completion(
}

model_id = form_data.model
model_info = Models.get_model_by_id(db, model_id)
model_info = Models.get_model_by_id(model_id)

if model_info:
if model_info.base_model_id:
Expand Down
4 changes: 1 addition & 3 deletions backend/apps/openai/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 11,6 @@
from pydantic import BaseModel
from starlette.background import BackgroundTask

from apps.webui.internal.db import get_db
from apps.webui.models.models import Models
from apps.webui.models.users import Users
from constants import ERROR_MESSAGES
Expand Down Expand Up @@ -354,13 353,12 @@ async def generate_chat_completion(
form_data: dict,
url_idx: Optional[int] = None,
user=Depends(get_verified_user),
db=Depends(get_db),
):
idx = 0
payload = {**form_data}

model_id = form_data.get("model")
model_info = Models.get_model_by_id(db, model_id)
model_info = Models.get_model_by_id(model_id)

if model_info:
if model_info.base_model_id:
Expand Down
9 changes: 5 additions & 4 deletions backend/apps/webui/internal/db.py
Original file line number Diff line number Diff line change
@@ -1,6 1,7 @@
import os
import logging
import json
from contextlib import contextmanager
from typing import Optional, Any
from typing_extensions import Self

Expand Down Expand Up @@ -52,17 53,17 @@ def python_value(self, value):
)
else:
engine = create_engine(SQLALCHEMY_DATABASE_URL, pool_pre_ping=True)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine, expire_on_commit=False)
Base = declarative_base()


def get_db():
@contextmanager
def get_session():
db = SessionLocal()
try:
yield db
db.commit()
except Exception as e:
db.rollback()
raise e
finally:
db.close()

4 changes: 2 additions & 2 deletions backend/apps/webui/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 114,8 @@ async def get_status():
}


async def get_pipe_models(db: Session):
pipes = Functions.get_functions_by_type(db, "pipe", active_only=True)
async def get_pipe_models():
pipes = Functions.get_functions_by_type("pipe", active_only=True)
pipe_models = []

for pipe in pipes:
Expand Down
148 changes: 77 additions & 71 deletions backend/apps/webui/models/auths.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 8,7 @@
from apps.webui.models.users import UserModel, Users
from utils.utils import verify_password

from apps.webui.internal.db import Base
from apps.webui.internal.db import Base, get_session

from config import SRC_LOG_LEVELS

Expand Down Expand Up @@ -96,108 96,114 @@ class AuthsTable:

def insert_new_auth(
self,
db: Session,
email: str,
password: str,
name: str,
profile_image_url: str = "/user.png",
role: str = "pending",
oauth_sub: Optional[str] = None,
) -> Optional[UserModel]:
log.info("insert_new_auth")
with get_session() as db:
log.info("insert_new_auth")

id = str(uuid.uuid4())
id = str(uuid.uuid4())

auth = AuthModel(
**{"id": id, "email": email, "password": password, "active": True}
)
result = Auth(**auth.model_dump())
db.add(result)
auth = AuthModel(
**{"id": id, "email": email, "password": password, "active": True}
)
result = Auth(**auth.model_dump())
db.add(result)

user = Users.insert_new_user(
db, id, name, email, profile_image_url, role, oauth_sub
)
user = Users.insert_new_user(
id, name, email, profile_image_url, role, oauth_sub
)

db.commit()
db.refresh(result)
db.commit()
db.refresh(result)

if result and user:
return user
else:
return None
if result and user:
return user
else:
return None

def authenticate_user(
self, db: Session, email: str, password: str
self, email: str, password: str
) -> Optional[UserModel]:
log.info(f"authenticate_user: {email}")
try:
auth = db.query(Auth).filter_by(email=email, active=True).first()
if auth:
if verify_password(password, auth.password):
user = Users.get_user_by_id(db, auth.id)
return user
with get_session() as db:
try:
auth = db.query(Auth).filter_by(email=email, active=True).first()
if auth:
if verify_password(password, auth.password):
user = Users.get_user_by_id(auth.id)
return user
else:
return None
else:
return None
else:
except:
return None
except:
return None

def authenticate_user_by_api_key(
self, db: Session, api_key: str
self, api_key: str
) -> Optional[UserModel]:
log.info(f"authenticate_user_by_api_key: {api_key}")
# if no api_key, return None
if not api_key:
return None
with get_session() as db:
# if no api_key, return None
if not api_key:
return None

try:
user = Users.get_user_by_api_key(db, api_key)
return user if user else None
except:
return False
try:
user = Users.get_user_by_api_key(api_key)
return user if user else None
except:
return False

def authenticate_user_by_trusted_header(
self, db: Session, email: str
self, email: str
) -> Optional[UserModel]:
log.info(f"authenticate_user_by_trusted_header: {email}")
try:
auth = db.query(Auth).filter(email=email, active=True).first()
if auth:
user = Users.get_user_by_id(auth.id)
return user
except:
return None
with get_session() as db:
try:
auth = db.query(Auth).filter(email=email, active=True).first()
if auth:
user = Users.get_user_by_id(auth.id)
return user
except:
return None

def update_user_password_by_id(
self, db: Session, id: str, new_password: str
self, id: str, new_password: str
) -> bool:
try:
result = db.query(Auth).filter_by(id=id).update({"password": new_password})
return True if result == 1 else False
except:
return False

def update_email_by_id(self, db: Session, id: str, email: str) -> bool:
try:
result = db.query(Auth).filter_by(id=id).update({"email": email})
return True if result == 1 else False
except:
return False

def delete_auth_by_id(self, db: Session, id: str) -> bool:
try:
# Delete User
result = Users.delete_user_by_id(db, id)

if result:
db.query(Auth).filter_by(id=id).delete()

return True
else:
with get_session() as db:
try:
result = db.query(Auth).filter_by(id=id).update({"password": new_password})
return True if result == 1 else False
except:
return False

def update_email_by_id(self, id: str, email: str) -> bool:
with get_session() as db:
try:
result = db.query(Auth).filter_by(id=id).update({"email": email})
return True if result == 1 else False
except:
return False

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

if result:
db.query(Auth).filter_by(id=id).delete()

return True
else:
return False
except:
return False
except:
return False


Auths = AuthsTable()
Loading