Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
open-webui
Commits
8f6f7668
You need to sign in or sign up before continuing.
Unverified
Commit
8f6f7668
authored
Jul 05, 2024
by
Timothy Jaeryang Baek
Committed by
GitHub
Jul 05, 2024
Browse files
Merge pull request #3595 from open-webui/dev-migration
feat: db migration
parents
97a84918
4e751501
Changes
44
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
375 additions
and
0 deletions
+375
-0
backend/test/apps/webui/routers/test_users.py
backend/test/apps/webui/routers/test_users.py
+168
-0
backend/test/util/abstract_integration_test.py
backend/test/util/abstract_integration_test.py
+161
-0
backend/test/util/mock_user.py
backend/test/util/mock_user.py
+45
-0
backend/utils/utils.py
backend/utils/utils.py
+1
-0
No files found.
backend/test/apps/webui/routers/test_users.py
0 → 100644
View file @
8f6f7668
from
test.util.abstract_integration_test
import
AbstractPostgresTest
from
test.util.mock_user
import
mock_webui_user
def
_get_user_by_id
(
data
,
param
):
return
next
((
item
for
item
in
data
if
item
[
"id"
]
==
param
),
None
)
def
_assert_user
(
data
,
id
,
**
kwargs
):
user
=
_get_user_by_id
(
data
,
id
)
assert
user
is
not
None
comparison_data
=
{
"name"
:
f
"user
{
id
}
"
,
"email"
:
f
"user
{
id
}
@openwebui.com"
,
"profile_image_url"
:
f
"/user
{
id
}
.png"
,
"role"
:
"user"
,
**
kwargs
,
}
for
key
,
value
in
comparison_data
.
items
():
assert
user
[
key
]
==
value
class
TestUsers
(
AbstractPostgresTest
):
BASE_PATH
=
"/api/v1/users"
def
setup_class
(
cls
):
super
().
setup_class
()
from
apps.webui.models.users
import
Users
cls
.
users
=
Users
def
setup_method
(
self
):
super
().
setup_method
()
self
.
users
.
insert_new_user
(
id
=
"1"
,
name
=
"user 1"
,
email
=
"user1@openwebui.com"
,
profile_image_url
=
"/user1.png"
,
role
=
"user"
,
)
self
.
users
.
insert_new_user
(
id
=
"2"
,
name
=
"user 2"
,
email
=
"user2@openwebui.com"
,
profile_image_url
=
"/user2.png"
,
role
=
"user"
,
)
def
test_users
(
self
):
# Get all users
with
mock_webui_user
(
id
=
"3"
):
response
=
self
.
fast_api_client
.
get
(
self
.
create_url
(
""
))
assert
response
.
status_code
==
200
assert
len
(
response
.
json
())
==
2
data
=
response
.
json
()
_assert_user
(
data
,
"1"
)
_assert_user
(
data
,
"2"
)
# update role
with
mock_webui_user
(
id
=
"3"
):
response
=
self
.
fast_api_client
.
post
(
self
.
create_url
(
"/update/role"
),
json
=
{
"id"
:
"2"
,
"role"
:
"admin"
}
)
assert
response
.
status_code
==
200
_assert_user
([
response
.
json
()],
"2"
,
role
=
"admin"
)
# Get all users
with
mock_webui_user
(
id
=
"3"
):
response
=
self
.
fast_api_client
.
get
(
self
.
create_url
(
""
))
assert
response
.
status_code
==
200
assert
len
(
response
.
json
())
==
2
data
=
response
.
json
()
_assert_user
(
data
,
"1"
)
_assert_user
(
data
,
"2"
,
role
=
"admin"
)
# Get (empty) user settings
with
mock_webui_user
(
id
=
"2"
):
response
=
self
.
fast_api_client
.
get
(
self
.
create_url
(
"/user/settings"
))
assert
response
.
status_code
==
200
assert
response
.
json
()
is
None
# Update user settings
with
mock_webui_user
(
id
=
"2"
):
response
=
self
.
fast_api_client
.
post
(
self
.
create_url
(
"/user/settings/update"
),
json
=
{
"ui"
:
{
"attr1"
:
"value1"
,
"attr2"
:
"value2"
},
"model_config"
:
{
"attr3"
:
"value3"
,
"attr4"
:
"value4"
},
},
)
assert
response
.
status_code
==
200
# Get user settings
with
mock_webui_user
(
id
=
"2"
):
response
=
self
.
fast_api_client
.
get
(
self
.
create_url
(
"/user/settings"
))
assert
response
.
status_code
==
200
assert
response
.
json
()
==
{
"ui"
:
{
"attr1"
:
"value1"
,
"attr2"
:
"value2"
},
"model_config"
:
{
"attr3"
:
"value3"
,
"attr4"
:
"value4"
},
}
# Get (empty) user info
with
mock_webui_user
(
id
=
"1"
):
response
=
self
.
fast_api_client
.
get
(
self
.
create_url
(
"/user/info"
))
assert
response
.
status_code
==
200
assert
response
.
json
()
is
None
# Update user info
with
mock_webui_user
(
id
=
"1"
):
response
=
self
.
fast_api_client
.
post
(
self
.
create_url
(
"/user/info/update"
),
json
=
{
"attr1"
:
"value1"
,
"attr2"
:
"value2"
},
)
assert
response
.
status_code
==
200
# Get user info
with
mock_webui_user
(
id
=
"1"
):
response
=
self
.
fast_api_client
.
get
(
self
.
create_url
(
"/user/info"
))
assert
response
.
status_code
==
200
assert
response
.
json
()
==
{
"attr1"
:
"value1"
,
"attr2"
:
"value2"
}
# Get user by id
with
mock_webui_user
(
id
=
"1"
):
response
=
self
.
fast_api_client
.
get
(
self
.
create_url
(
"/2"
))
assert
response
.
status_code
==
200
assert
response
.
json
()
==
{
"name"
:
"user 2"
,
"profile_image_url"
:
"/user2.png"
}
# Update user by id
with
mock_webui_user
(
id
=
"1"
):
response
=
self
.
fast_api_client
.
post
(
self
.
create_url
(
"/2/update"
),
json
=
{
"name"
:
"user 2 updated"
,
"email"
:
"user2-updated@openwebui.com"
,
"profile_image_url"
:
"/user2-updated.png"
,
},
)
assert
response
.
status_code
==
200
# Get all users
with
mock_webui_user
(
id
=
"3"
):
response
=
self
.
fast_api_client
.
get
(
self
.
create_url
(
""
))
assert
response
.
status_code
==
200
assert
len
(
response
.
json
())
==
2
data
=
response
.
json
()
_assert_user
(
data
,
"1"
)
_assert_user
(
data
,
"2"
,
role
=
"admin"
,
name
=
"user 2 updated"
,
email
=
"user2-updated@openwebui.com"
,
profile_image_url
=
"/user2-updated.png"
,
)
# Delete user by id
with
mock_webui_user
(
id
=
"1"
):
response
=
self
.
fast_api_client
.
delete
(
self
.
create_url
(
"/2"
))
assert
response
.
status_code
==
200
# Get all users
with
mock_webui_user
(
id
=
"3"
):
response
=
self
.
fast_api_client
.
get
(
self
.
create_url
(
""
))
assert
response
.
status_code
==
200
assert
len
(
response
.
json
())
==
1
data
=
response
.
json
()
_assert_user
(
data
,
"1"
)
backend/test/util/abstract_integration_test.py
0 → 100644
View file @
8f6f7668
import
logging
import
os
import
time
import
docker
import
pytest
from
docker
import
DockerClient
from
pytest_docker.plugin
import
get_docker_ip
from
fastapi.testclient
import
TestClient
from
sqlalchemy
import
text
,
create_engine
log
=
logging
.
getLogger
(
__name__
)
def
get_fast_api_client
():
from
main
import
app
with
TestClient
(
app
)
as
c
:
return
c
class
AbstractIntegrationTest
:
BASE_PATH
=
None
def
create_url
(
self
,
path
=
""
,
query_params
=
None
):
if
self
.
BASE_PATH
is
None
:
raise
Exception
(
"BASE_PATH is not set"
)
parts
=
self
.
BASE_PATH
.
split
(
"/"
)
parts
=
[
part
.
strip
()
for
part
in
parts
if
part
.
strip
()
!=
""
]
path_parts
=
path
.
split
(
"/"
)
path_parts
=
[
part
.
strip
()
for
part
in
path_parts
if
part
.
strip
()
!=
""
]
query_parts
=
""
if
query_params
:
query_parts
=
"&"
.
join
(
[
f
"
{
key
}
=
{
value
}
"
for
key
,
value
in
query_params
.
items
()]
)
query_parts
=
f
"?
{
query_parts
}
"
return
"/"
.
join
(
parts
+
path_parts
)
+
query_parts
@
classmethod
def
setup_class
(
cls
):
pass
def
setup_method
(
self
):
pass
@
classmethod
def
teardown_class
(
cls
):
pass
def
teardown_method
(
self
):
pass
class
AbstractPostgresTest
(
AbstractIntegrationTest
):
DOCKER_CONTAINER_NAME
=
"postgres-test-container-will-get-deleted"
docker_client
:
DockerClient
@
classmethod
def
_create_db_url
(
cls
,
env_vars_postgres
:
dict
)
->
str
:
host
=
get_docker_ip
()
user
=
env_vars_postgres
[
"POSTGRES_USER"
]
pw
=
env_vars_postgres
[
"POSTGRES_PASSWORD"
]
port
=
8081
db
=
env_vars_postgres
[
"POSTGRES_DB"
]
return
f
"postgresql://
{
user
}
:
{
pw
}
@
{
host
}
:
{
port
}
/
{
db
}
"
@
classmethod
def
setup_class
(
cls
):
super
().
setup_class
()
try
:
env_vars_postgres
=
{
"POSTGRES_USER"
:
"user"
,
"POSTGRES_PASSWORD"
:
"example"
,
"POSTGRES_DB"
:
"openwebui"
,
}
cls
.
docker_client
=
docker
.
from_env
()
cls
.
docker_client
.
containers
.
run
(
"postgres:16.2"
,
detach
=
True
,
environment
=
env_vars_postgres
,
name
=
cls
.
DOCKER_CONTAINER_NAME
,
ports
=
{
5432
:
(
"0.0.0.0"
,
8081
)},
command
=
"postgres -c log_statement=all"
,
)
time
.
sleep
(
0.5
)
database_url
=
cls
.
_create_db_url
(
env_vars_postgres
)
os
.
environ
[
"DATABASE_URL"
]
=
database_url
retries
=
10
db
=
None
while
retries
>
0
:
try
:
from
config
import
BACKEND_DIR
db
=
create_engine
(
database_url
,
pool_pre_ping
=
True
)
db
=
db
.
connect
()
log
.
info
(
"postgres is ready!"
)
break
except
Exception
as
e
:
log
.
warning
(
e
)
time
.
sleep
(
3
)
retries
-=
1
if
db
:
# import must be after setting env!
cls
.
fast_api_client
=
get_fast_api_client
()
db
.
close
()
else
:
raise
Exception
(
"Could not connect to Postgres"
)
except
Exception
as
ex
:
log
.
error
(
ex
)
cls
.
teardown_class
()
pytest
.
fail
(
f
"Could not setup test environment:
{
ex
}
"
)
def
_check_db_connection
(
self
):
from
apps.webui.internal.db
import
Session
retries
=
10
while
retries
>
0
:
try
:
Session
.
execute
(
text
(
"SELECT 1"
))
Session
.
commit
()
break
except
Exception
as
e
:
Session
.
rollback
()
log
.
warning
(
e
)
time
.
sleep
(
3
)
retries
-=
1
def
setup_method
(
self
):
super
().
setup_method
()
self
.
_check_db_connection
()
@
classmethod
def
teardown_class
(
cls
)
->
None
:
super
().
teardown_class
()
cls
.
docker_client
.
containers
.
get
(
cls
.
DOCKER_CONTAINER_NAME
).
remove
(
force
=
True
)
def
teardown_method
(
self
):
from
apps.webui.internal.db
import
Session
# rollback everything not yet committed
Session
.
commit
()
# truncate all tables
tables
=
[
"auth"
,
"chat"
,
"chatidtag"
,
"document"
,
"memory"
,
"model"
,
"prompt"
,
"tag"
,
'"user"'
,
]
for
table
in
tables
:
Session
.
execute
(
text
(
f
"TRUNCATE TABLE
{
table
}
"
))
Session
.
commit
()
backend/test/util/mock_user.py
0 → 100644
View file @
8f6f7668
from
contextlib
import
contextmanager
from
fastapi
import
FastAPI
@
contextmanager
def
mock_webui_user
(
**
kwargs
):
from
apps.webui.main
import
app
with
mock_user
(
app
,
**
kwargs
):
yield
@
contextmanager
def
mock_user
(
app
:
FastAPI
,
**
kwargs
):
from
utils.utils
import
(
get_current_user
,
get_verified_user
,
get_admin_user
,
get_current_user_by_api_key
,
)
from
apps.webui.models.users
import
User
def
create_user
():
user_parameters
=
{
"id"
:
"1"
,
"name"
:
"John Doe"
,
"email"
:
"john.doe@openwebui.com"
,
"role"
:
"user"
,
"profile_image_url"
:
"/user.png"
,
"last_active_at"
:
1627351200
,
"updated_at"
:
1627351200
,
"created_at"
:
162735120
,
**
kwargs
,
}
return
User
(
**
user_parameters
)
app
.
dependency_overrides
=
{
get_current_user
:
create_user
,
get_verified_user
:
create_user
,
get_admin_user
:
create_user
,
get_current_user_by_api_key
:
create_user
,
}
yield
app
.
dependency_overrides
=
{}
backend/utils/utils.py
View file @
8f6f7668
from
fastapi.security
import
HTTPBearer
,
HTTPAuthorizationCredentials
from
fastapi.security
import
HTTPBearer
,
HTTPAuthorizationCredentials
from
fastapi
import
HTTPException
,
status
,
Depends
,
Request
from
fastapi
import
HTTPException
,
status
,
Depends
,
Request
from
sqlalchemy.orm
import
Session
from
apps.webui.models.users
import
Users
from
apps.webui.models.users
import
Users
...
...
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment