2025-04-05 18:05:52 +08:00
|
|
|
from fastapi import APIRouter, Depends, Request, HTTPException
|
|
|
|
from pydantic import BaseModel, ConfigDict
|
2024-01-03 08:48:10 +08:00
|
|
|
|
2024-11-27 00:55:06 +08:00
|
|
|
from typing import Optional
|
2024-09-04 03:16:07 +08:00
|
|
|
|
2024-12-09 08:01:56 +08:00
|
|
|
from open_webui.utils.auth import get_admin_user, get_verified_user
|
2024-09-04 22:54:48 +08:00
|
|
|
from open_webui.config import get_config, save_config
|
2024-11-27 00:55:06 +08:00
|
|
|
from open_webui.config import BannerModel
|
|
|
|
|
2025-07-28 22:32:05 +08:00
|
|
|
from open_webui.utils.tools import (
|
|
|
|
get_tool_server_data,
|
|
|
|
get_tool_servers_data,
|
2025-07-31 20:47:02 +08:00
|
|
|
get_tool_server_url,
|
2025-07-28 22:32:05 +08:00
|
|
|
)
|
2025-04-05 18:05:52 +08:00
|
|
|
|
2024-09-04 03:16:07 +08:00
|
|
|
|
2024-01-03 08:48:10 +08:00
|
|
|
router = APIRouter()
|
|
|
|
|
|
|
|
|
2024-09-04 03:16:07 +08:00
|
|
|
############################
|
|
|
|
# ImportConfig
|
|
|
|
############################
|
|
|
|
|
|
|
|
|
|
|
|
class ImportConfigForm(BaseModel):
|
|
|
|
config: dict
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/import", response_model=dict)
|
|
|
|
async def import_config(form_data: ImportConfigForm, user=Depends(get_admin_user)):
|
|
|
|
save_config(form_data.config)
|
|
|
|
return get_config()
|
|
|
|
|
|
|
|
|
|
|
|
############################
|
|
|
|
# ExportConfig
|
|
|
|
############################
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/export", response_model=dict)
|
|
|
|
async def export_config(user=Depends(get_admin_user)):
|
|
|
|
return get_config()
|
|
|
|
|
|
|
|
|
2025-02-12 14:29:45 +08:00
|
|
|
############################
|
2025-06-28 19:12:31 +08:00
|
|
|
# Connections Config
|
2025-02-12 14:29:45 +08:00
|
|
|
############################
|
|
|
|
|
|
|
|
|
2025-06-28 19:12:31 +08:00
|
|
|
class ConnectionsConfigForm(BaseModel):
|
2025-02-12 15:12:00 +08:00
|
|
|
ENABLE_DIRECT_CONNECTIONS: bool
|
2025-06-30 17:27:07 +08:00
|
|
|
ENABLE_BASE_MODELS_CACHE: bool
|
2025-02-12 14:29:45 +08:00
|
|
|
|
|
|
|
|
2025-06-28 19:12:31 +08:00
|
|
|
@router.get("/connections", response_model=ConnectionsConfigForm)
|
|
|
|
async def get_connections_config(request: Request, user=Depends(get_admin_user)):
|
2025-02-12 14:29:45 +08:00
|
|
|
return {
|
2025-02-12 15:12:00 +08:00
|
|
|
"ENABLE_DIRECT_CONNECTIONS": request.app.state.config.ENABLE_DIRECT_CONNECTIONS,
|
2025-06-30 17:27:07 +08:00
|
|
|
"ENABLE_BASE_MODELS_CACHE": request.app.state.config.ENABLE_BASE_MODELS_CACHE,
|
2025-02-12 14:29:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2025-06-28 19:12:31 +08:00
|
|
|
@router.post("/connections", response_model=ConnectionsConfigForm)
|
|
|
|
async def set_connections_config(
|
2025-02-12 15:13:48 +08:00
|
|
|
request: Request,
|
2025-06-28 19:12:31 +08:00
|
|
|
form_data: ConnectionsConfigForm,
|
2025-02-12 15:13:48 +08:00
|
|
|
user=Depends(get_admin_user),
|
2025-02-12 14:29:45 +08:00
|
|
|
):
|
2025-02-12 15:12:00 +08:00
|
|
|
request.app.state.config.ENABLE_DIRECT_CONNECTIONS = (
|
|
|
|
form_data.ENABLE_DIRECT_CONNECTIONS
|
|
|
|
)
|
2025-06-30 17:27:07 +08:00
|
|
|
request.app.state.config.ENABLE_BASE_MODELS_CACHE = (
|
|
|
|
form_data.ENABLE_BASE_MODELS_CACHE
|
|
|
|
)
|
2025-06-28 19:12:31 +08:00
|
|
|
|
2025-02-12 14:29:45 +08:00
|
|
|
return {
|
2025-02-12 15:12:00 +08:00
|
|
|
"ENABLE_DIRECT_CONNECTIONS": request.app.state.config.ENABLE_DIRECT_CONNECTIONS,
|
2025-06-30 17:27:07 +08:00
|
|
|
"ENABLE_BASE_MODELS_CACHE": request.app.state.config.ENABLE_BASE_MODELS_CACHE,
|
2025-02-12 14:29:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2025-04-05 18:05:52 +08:00
|
|
|
############################
|
|
|
|
# ToolServers Config
|
|
|
|
############################
|
|
|
|
|
|
|
|
|
|
|
|
class ToolServerConnection(BaseModel):
|
|
|
|
url: str
|
|
|
|
path: str
|
|
|
|
auth_type: Optional[str]
|
|
|
|
key: Optional[str]
|
|
|
|
config: Optional[dict]
|
|
|
|
|
|
|
|
model_config = ConfigDict(extra="allow")
|
|
|
|
|
|
|
|
|
|
|
|
class ToolServersConfigForm(BaseModel):
|
|
|
|
TOOL_SERVER_CONNECTIONS: list[ToolServerConnection]
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/tool_servers", response_model=ToolServersConfigForm)
|
|
|
|
async def get_tool_servers_config(request: Request, user=Depends(get_admin_user)):
|
|
|
|
return {
|
|
|
|
"TOOL_SERVER_CONNECTIONS": request.app.state.config.TOOL_SERVER_CONNECTIONS,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/tool_servers", response_model=ToolServersConfigForm)
|
|
|
|
async def set_tool_servers_config(
|
|
|
|
request: Request,
|
|
|
|
form_data: ToolServersConfigForm,
|
|
|
|
user=Depends(get_admin_user),
|
|
|
|
):
|
2025-04-05 18:12:57 +08:00
|
|
|
request.app.state.config.TOOL_SERVER_CONNECTIONS = [
|
|
|
|
connection.model_dump() for connection in form_data.TOOL_SERVER_CONNECTIONS
|
|
|
|
]
|
2025-04-05 18:05:52 +08:00
|
|
|
|
|
|
|
request.app.state.TOOL_SERVERS = await get_tool_servers_data(
|
|
|
|
request.app.state.config.TOOL_SERVER_CONNECTIONS
|
|
|
|
)
|
|
|
|
|
|
|
|
return {
|
|
|
|
"TOOL_SERVER_CONNECTIONS": request.app.state.config.TOOL_SERVER_CONNECTIONS,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/tool_servers/verify")
|
|
|
|
async def verify_tool_servers_config(
|
|
|
|
request: Request, form_data: ToolServerConnection, user=Depends(get_admin_user)
|
|
|
|
):
|
|
|
|
"""
|
|
|
|
Verify the connection to the tool server.
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
|
|
|
|
token = None
|
|
|
|
if form_data.auth_type == "bearer":
|
|
|
|
token = form_data.key
|
|
|
|
elif form_data.auth_type == "session":
|
|
|
|
token = request.state.token.credentials
|
|
|
|
|
2025-07-31 20:47:02 +08:00
|
|
|
url = get_tool_server_url(form_data.url, form_data.path)
|
2025-04-05 18:05:52 +08:00
|
|
|
return await get_tool_server_data(token, url)
|
|
|
|
except Exception as e:
|
|
|
|
raise HTTPException(
|
|
|
|
status_code=400,
|
|
|
|
detail=f"Failed to connect to the tool server: {str(e)}",
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2025-02-10 18:25:02 +08:00
|
|
|
############################
|
|
|
|
# CodeInterpreterConfig
|
|
|
|
############################
|
|
|
|
class CodeInterpreterConfigForm(BaseModel):
|
2025-03-06 11:06:28 +08:00
|
|
|
ENABLE_CODE_EXECUTION: bool
|
2025-02-18 08:25:50 +08:00
|
|
|
CODE_EXECUTION_ENGINE: str
|
|
|
|
CODE_EXECUTION_JUPYTER_URL: Optional[str]
|
|
|
|
CODE_EXECUTION_JUPYTER_AUTH: Optional[str]
|
|
|
|
CODE_EXECUTION_JUPYTER_AUTH_TOKEN: Optional[str]
|
|
|
|
CODE_EXECUTION_JUPYTER_AUTH_PASSWORD: Optional[str]
|
2025-02-20 09:05:37 +08:00
|
|
|
CODE_EXECUTION_JUPYTER_TIMEOUT: Optional[int]
|
2025-02-10 18:25:02 +08:00
|
|
|
ENABLE_CODE_INTERPRETER: bool
|
|
|
|
CODE_INTERPRETER_ENGINE: str
|
2025-02-12 13:36:16 +08:00
|
|
|
CODE_INTERPRETER_PROMPT_TEMPLATE: Optional[str]
|
2025-02-10 18:25:02 +08:00
|
|
|
CODE_INTERPRETER_JUPYTER_URL: Optional[str]
|
|
|
|
CODE_INTERPRETER_JUPYTER_AUTH: Optional[str]
|
|
|
|
CODE_INTERPRETER_JUPYTER_AUTH_TOKEN: Optional[str]
|
|
|
|
CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD: Optional[str]
|
2025-02-20 09:05:37 +08:00
|
|
|
CODE_INTERPRETER_JUPYTER_TIMEOUT: Optional[int]
|
2025-02-10 18:25:02 +08:00
|
|
|
|
|
|
|
|
2025-02-18 08:25:50 +08:00
|
|
|
@router.get("/code_execution", response_model=CodeInterpreterConfigForm)
|
|
|
|
async def get_code_execution_config(request: Request, user=Depends(get_admin_user)):
|
2025-02-10 18:25:02 +08:00
|
|
|
return {
|
2025-03-06 11:06:28 +08:00
|
|
|
"ENABLE_CODE_EXECUTION": request.app.state.config.ENABLE_CODE_EXECUTION,
|
2025-02-18 08:25:50 +08:00
|
|
|
"CODE_EXECUTION_ENGINE": request.app.state.config.CODE_EXECUTION_ENGINE,
|
|
|
|
"CODE_EXECUTION_JUPYTER_URL": request.app.state.config.CODE_EXECUTION_JUPYTER_URL,
|
|
|
|
"CODE_EXECUTION_JUPYTER_AUTH": request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH,
|
|
|
|
"CODE_EXECUTION_JUPYTER_AUTH_TOKEN": request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_TOKEN,
|
|
|
|
"CODE_EXECUTION_JUPYTER_AUTH_PASSWORD": request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_PASSWORD,
|
2025-02-20 09:05:37 +08:00
|
|
|
"CODE_EXECUTION_JUPYTER_TIMEOUT": request.app.state.config.CODE_EXECUTION_JUPYTER_TIMEOUT,
|
2025-02-10 18:25:02 +08:00
|
|
|
"ENABLE_CODE_INTERPRETER": request.app.state.config.ENABLE_CODE_INTERPRETER,
|
|
|
|
"CODE_INTERPRETER_ENGINE": request.app.state.config.CODE_INTERPRETER_ENGINE,
|
2025-02-12 13:36:16 +08:00
|
|
|
"CODE_INTERPRETER_PROMPT_TEMPLATE": request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE,
|
2025-02-10 18:25:02 +08:00
|
|
|
"CODE_INTERPRETER_JUPYTER_URL": request.app.state.config.CODE_INTERPRETER_JUPYTER_URL,
|
|
|
|
"CODE_INTERPRETER_JUPYTER_AUTH": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH,
|
|
|
|
"CODE_INTERPRETER_JUPYTER_AUTH_TOKEN": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN,
|
|
|
|
"CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD,
|
2025-02-20 09:05:37 +08:00
|
|
|
"CODE_INTERPRETER_JUPYTER_TIMEOUT": request.app.state.config.CODE_INTERPRETER_JUPYTER_TIMEOUT,
|
2025-02-10 18:25:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2025-02-18 08:25:50 +08:00
|
|
|
@router.post("/code_execution", response_model=CodeInterpreterConfigForm)
|
|
|
|
async def set_code_execution_config(
|
2025-02-10 18:25:02 +08:00
|
|
|
request: Request, form_data: CodeInterpreterConfigForm, user=Depends(get_admin_user)
|
|
|
|
):
|
2025-02-18 08:25:50 +08:00
|
|
|
|
2025-03-06 11:06:28 +08:00
|
|
|
request.app.state.config.ENABLE_CODE_EXECUTION = form_data.ENABLE_CODE_EXECUTION
|
|
|
|
|
2025-02-18 08:25:50 +08:00
|
|
|
request.app.state.config.CODE_EXECUTION_ENGINE = form_data.CODE_EXECUTION_ENGINE
|
|
|
|
request.app.state.config.CODE_EXECUTION_JUPYTER_URL = (
|
|
|
|
form_data.CODE_EXECUTION_JUPYTER_URL
|
|
|
|
)
|
|
|
|
request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH = (
|
|
|
|
form_data.CODE_EXECUTION_JUPYTER_AUTH
|
|
|
|
)
|
|
|
|
request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_TOKEN = (
|
|
|
|
form_data.CODE_EXECUTION_JUPYTER_AUTH_TOKEN
|
|
|
|
)
|
|
|
|
request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_PASSWORD = (
|
|
|
|
form_data.CODE_EXECUTION_JUPYTER_AUTH_PASSWORD
|
|
|
|
)
|
2025-02-20 09:05:37 +08:00
|
|
|
request.app.state.config.CODE_EXECUTION_JUPYTER_TIMEOUT = (
|
|
|
|
form_data.CODE_EXECUTION_JUPYTER_TIMEOUT
|
|
|
|
)
|
2025-02-18 08:25:50 +08:00
|
|
|
|
2025-02-10 18:25:02 +08:00
|
|
|
request.app.state.config.ENABLE_CODE_INTERPRETER = form_data.ENABLE_CODE_INTERPRETER
|
|
|
|
request.app.state.config.CODE_INTERPRETER_ENGINE = form_data.CODE_INTERPRETER_ENGINE
|
2025-02-12 13:36:16 +08:00
|
|
|
request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE = (
|
|
|
|
form_data.CODE_INTERPRETER_PROMPT_TEMPLATE
|
|
|
|
)
|
|
|
|
|
2025-02-10 18:25:02 +08:00
|
|
|
request.app.state.config.CODE_INTERPRETER_JUPYTER_URL = (
|
|
|
|
form_data.CODE_INTERPRETER_JUPYTER_URL
|
|
|
|
)
|
|
|
|
|
|
|
|
request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH = (
|
|
|
|
form_data.CODE_INTERPRETER_JUPYTER_AUTH
|
|
|
|
)
|
|
|
|
|
|
|
|
request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN = (
|
|
|
|
form_data.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN
|
|
|
|
)
|
|
|
|
request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD = (
|
|
|
|
form_data.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD
|
|
|
|
)
|
2025-02-20 09:05:37 +08:00
|
|
|
request.app.state.config.CODE_INTERPRETER_JUPYTER_TIMEOUT = (
|
|
|
|
form_data.CODE_INTERPRETER_JUPYTER_TIMEOUT
|
|
|
|
)
|
2025-02-10 18:25:02 +08:00
|
|
|
|
|
|
|
return {
|
2025-03-06 11:06:28 +08:00
|
|
|
"ENABLE_CODE_EXECUTION": request.app.state.config.ENABLE_CODE_EXECUTION,
|
2025-02-18 08:25:50 +08:00
|
|
|
"CODE_EXECUTION_ENGINE": request.app.state.config.CODE_EXECUTION_ENGINE,
|
|
|
|
"CODE_EXECUTION_JUPYTER_URL": request.app.state.config.CODE_EXECUTION_JUPYTER_URL,
|
|
|
|
"CODE_EXECUTION_JUPYTER_AUTH": request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH,
|
|
|
|
"CODE_EXECUTION_JUPYTER_AUTH_TOKEN": request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_TOKEN,
|
|
|
|
"CODE_EXECUTION_JUPYTER_AUTH_PASSWORD": request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_PASSWORD,
|
2025-02-20 09:05:37 +08:00
|
|
|
"CODE_EXECUTION_JUPYTER_TIMEOUT": request.app.state.config.CODE_EXECUTION_JUPYTER_TIMEOUT,
|
2025-02-10 18:25:02 +08:00
|
|
|
"ENABLE_CODE_INTERPRETER": request.app.state.config.ENABLE_CODE_INTERPRETER,
|
|
|
|
"CODE_INTERPRETER_ENGINE": request.app.state.config.CODE_INTERPRETER_ENGINE,
|
2025-02-12 13:36:16 +08:00
|
|
|
"CODE_INTERPRETER_PROMPT_TEMPLATE": request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE,
|
2025-02-10 18:25:02 +08:00
|
|
|
"CODE_INTERPRETER_JUPYTER_URL": request.app.state.config.CODE_INTERPRETER_JUPYTER_URL,
|
|
|
|
"CODE_INTERPRETER_JUPYTER_AUTH": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH,
|
|
|
|
"CODE_INTERPRETER_JUPYTER_AUTH_TOKEN": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN,
|
|
|
|
"CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD,
|
2025-02-20 09:05:37 +08:00
|
|
|
"CODE_INTERPRETER_JUPYTER_TIMEOUT": request.app.state.config.CODE_INTERPRETER_JUPYTER_TIMEOUT,
|
2025-02-10 18:25:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-11-26 16:55:58 +08:00
|
|
|
############################
|
|
|
|
# SetDefaultModels
|
|
|
|
############################
|
|
|
|
class ModelsConfigForm(BaseModel):
|
2024-11-27 00:55:06 +08:00
|
|
|
DEFAULT_MODELS: Optional[str]
|
|
|
|
MODEL_ORDER_LIST: Optional[list[str]]
|
2024-11-26 16:55:58 +08:00
|
|
|
|
|
|
|
|
|
|
|
@router.get("/models", response_model=ModelsConfigForm)
|
|
|
|
async def get_models_config(request: Request, user=Depends(get_admin_user)):
|
|
|
|
return {
|
|
|
|
"DEFAULT_MODELS": request.app.state.config.DEFAULT_MODELS,
|
|
|
|
"MODEL_ORDER_LIST": request.app.state.config.MODEL_ORDER_LIST,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/models", response_model=ModelsConfigForm)
|
|
|
|
async def set_models_config(
|
|
|
|
request: Request, form_data: ModelsConfigForm, user=Depends(get_admin_user)
|
|
|
|
):
|
|
|
|
request.app.state.config.DEFAULT_MODELS = form_data.DEFAULT_MODELS
|
|
|
|
request.app.state.config.MODEL_ORDER_LIST = form_data.MODEL_ORDER_LIST
|
|
|
|
return {
|
|
|
|
"DEFAULT_MODELS": request.app.state.config.DEFAULT_MODELS,
|
|
|
|
"MODEL_ORDER_LIST": request.app.state.config.MODEL_ORDER_LIST,
|
|
|
|
}
|
2024-01-03 08:48:10 +08:00
|
|
|
|
|
|
|
|
2024-01-23 13:07:40 +08:00
|
|
|
class PromptSuggestion(BaseModel):
|
2024-08-14 20:46:31 +08:00
|
|
|
title: list[str]
|
2024-01-23 13:07:40 +08:00
|
|
|
content: str
|
|
|
|
|
|
|
|
|
|
|
|
class SetDefaultSuggestionsForm(BaseModel):
|
2024-08-14 20:46:31 +08:00
|
|
|
suggestions: list[PromptSuggestion]
|
2024-01-23 13:07:40 +08:00
|
|
|
|
|
|
|
|
2024-11-26 16:55:58 +08:00
|
|
|
@router.post("/suggestions", response_model=list[PromptSuggestion])
|
|
|
|
async def set_default_suggestions(
|
2024-01-23 13:07:40 +08:00
|
|
|
request: Request,
|
|
|
|
form_data: SetDefaultSuggestionsForm,
|
2024-02-09 08:05:01 +08:00
|
|
|
user=Depends(get_admin_user),
|
2024-01-23 13:07:40 +08:00
|
|
|
):
|
2024-02-09 08:05:01 +08:00
|
|
|
data = form_data.model_dump()
|
2024-05-10 15:03:24 +08:00
|
|
|
request.app.state.config.DEFAULT_PROMPT_SUGGESTIONS = data["suggestions"]
|
|
|
|
return request.app.state.config.DEFAULT_PROMPT_SUGGESTIONS
|
2024-05-27 03:18:43 +08:00
|
|
|
|
|
|
|
|
|
|
|
############################
|
|
|
|
# SetBanners
|
|
|
|
############################
|
|
|
|
|
|
|
|
|
|
|
|
class SetBannersForm(BaseModel):
|
2024-08-14 20:46:31 +08:00
|
|
|
banners: list[BannerModel]
|
2024-05-27 03:18:43 +08:00
|
|
|
|
|
|
|
|
2024-08-14 20:46:31 +08:00
|
|
|
@router.post("/banners", response_model=list[BannerModel])
|
2024-05-27 03:18:43 +08:00
|
|
|
async def set_banners(
|
|
|
|
request: Request,
|
|
|
|
form_data: SetBannersForm,
|
|
|
|
user=Depends(get_admin_user),
|
|
|
|
):
|
|
|
|
data = form_data.model_dump()
|
|
|
|
request.app.state.config.BANNERS = data["banners"]
|
|
|
|
return request.app.state.config.BANNERS
|
|
|
|
|
|
|
|
|
2024-08-14 20:46:31 +08:00
|
|
|
@router.get("/banners", response_model=list[BannerModel])
|
2024-05-27 03:18:43 +08:00
|
|
|
async def get_banners(
|
|
|
|
request: Request,
|
2024-06-28 02:29:59 +08:00
|
|
|
user=Depends(get_verified_user),
|
2024-05-27 03:18:43 +08:00
|
|
|
):
|
|
|
|
return request.app.state.config.BANNERS
|