203 lines
7.6 KiB
Python
203 lines
7.6 KiB
Python
import copy
|
|
import time
|
|
from typing import List
|
|
|
|
import yaml
|
|
from fastapi import APIRouter, Body, Depends, HTTPException, Path, Request, UploadFile
|
|
from loguru import logger
|
|
|
|
from bisheng.api.v1.schemas import (UploadFileResponse,
|
|
resp_200)
|
|
from bisheng.common.dependencies.user_deps import UserPayload
|
|
from bisheng.common.errcode.server import SystemConfigEmptyError, SystemConfigInvalidError, UploadFileEmptyError, \
|
|
UploadFileExtError
|
|
from bisheng.common.models.config import Config, ConfigDao, ConfigKeyEnum
|
|
from bisheng.common.services.config_service import settings as bisheng_settings
|
|
from bisheng.core.cache.redis_manager import get_redis_client_sync
|
|
from bisheng.core.cache.utils import save_uploaded_file, upload_file_to_minio
|
|
from bisheng.utils import generate_uuid
|
|
from bisheng.utils import get_request_ip
|
|
|
|
# build router
|
|
router = APIRouter(tags=['Base'])
|
|
|
|
if bisheng_settings.debug:
|
|
import tracemalloc
|
|
import os
|
|
import threading
|
|
|
|
|
|
@router.get("/tracemalloc")
|
|
def tracemalloc_point():
|
|
snapshot = tracemalloc.take_snapshot()
|
|
process_id = os.getpid()
|
|
thread_id = threading.get_ident()
|
|
snapshot.dump(f"/app/data/snapshot_{process_id}_{thread_id}_{time.time()}.prof")
|
|
|
|
return resp_200()
|
|
|
|
|
|
@router.get('/env')
|
|
def get_env():
|
|
from bisheng import __version__
|
|
"""Get environment variable parameters"""
|
|
uns_support = ['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'txt', 'md', 'html', 'pdf', 'csv']
|
|
|
|
etl_for_lm_url = bisheng_settings.get_knowledge().etl4lm.url
|
|
if etl_for_lm_url:
|
|
uns_support.extend(['png', 'jpg', 'jpeg', 'bmp'])
|
|
|
|
env = {}
|
|
if isinstance(bisheng_settings.environment, str):
|
|
env['env'] = bisheng_settings.environment
|
|
else:
|
|
env = copy.deepcopy(bisheng_settings.environment)
|
|
|
|
env['uns_support'] = uns_support
|
|
if bisheng_settings.get_from_db('office_url'):
|
|
env['office_url'] = bisheng_settings.get_from_db('office_url')
|
|
# add tips from settings
|
|
env['dialog_tips'] = bisheng_settings.get_from_db('dialog_tips')
|
|
# add env dict from settings
|
|
env.update(bisheng_settings.get_from_db('env') or {})
|
|
env['pro'] = bisheng_settings.get_system_login_method().bisheng_pro
|
|
env['dashboard_pro'] = bisheng_settings.get_system_login_method().dashboard_pro
|
|
env['version'] = __version__
|
|
env['enable_etl4lm'] = bool(etl_for_lm_url)
|
|
|
|
return resp_200(env)
|
|
|
|
|
|
@router.get('/config')
|
|
def get_config(admin_user: UserPayload = Depends(UserPayload.get_admin_user)):
|
|
db_config = ConfigDao.get_config(ConfigKeyEnum.INIT_DB)
|
|
config_str = db_config.value if db_config else ''
|
|
return resp_200(config_str)
|
|
|
|
|
|
@router.post('/config/save')
|
|
def save_config(data: dict, admin_user: UserPayload = Depends(UserPayload.get_admin_user)):
|
|
if not data.get('data', '').strip():
|
|
raise SystemConfigEmptyError()
|
|
try:
|
|
# Check for complianceyamlFormat
|
|
config = yaml.safe_load(data.get('data'))
|
|
|
|
# Judging linsight_invitation_code Right?boolean
|
|
if isinstance(config, dict) and 'linsight_invitation_code' in config.keys():
|
|
if config['linsight_invitation_code'] is not None and bool(config['linsight_invitation_code']) not in [True,
|
|
False]:
|
|
raise ValueError('linsight_invitation_code must be a boolean value')
|
|
|
|
db_config = ConfigDao.get_config(ConfigKeyEnum.INIT_DB)
|
|
db_config.value = data.get('data')
|
|
ConfigDao.insert_config(db_config)
|
|
get_redis_client_sync().delete('config:initdb_config')
|
|
except Exception as e:
|
|
raise SystemConfigInvalidError()
|
|
|
|
return resp_200()
|
|
|
|
|
|
@router.get('/web/config')
|
|
async def get_web_config():
|
|
""" Get some configuration items required by the front-end, the content is determined by the front-end """
|
|
web_conf = ConfigDao.get_config(ConfigKeyEnum.WEB_CONFIG)
|
|
if not web_conf:
|
|
return resp_200(data='')
|
|
return resp_200(data={'value': web_conf.value})
|
|
|
|
|
|
@router.post('/web/config')
|
|
async def update_web_config(request: Request,
|
|
admin_user: UserPayload = Depends(UserPayload.get_admin_user),
|
|
value: str = Body(embed=True)):
|
|
""" Update some configuration items required by the front-end, the content is determined by the front-end """
|
|
logger.info(
|
|
f'update_web_config user_name={admin_user.user_name}, ip={get_request_ip(request)}')
|
|
web_conf = ConfigDao.get_config(ConfigKeyEnum.WEB_CONFIG)
|
|
if not web_conf:
|
|
web_conf = Config(key=ConfigKeyEnum.WEB_CONFIG.value, value=value)
|
|
else:
|
|
web_conf.value = value
|
|
ConfigDao.insert_config(web_conf)
|
|
return resp_200(data={'value': web_conf.value})
|
|
|
|
|
|
async def _upload_file(file: UploadFile, object_name_prefix: str, file_supports: List[str] = None,
|
|
bucket_name: str = None) \
|
|
-> UploadFileResponse:
|
|
if file.size == 0:
|
|
raise UploadFileEmptyError()
|
|
file_ext = file.filename.split('.')[-1].lower()
|
|
if file_supports and file_ext not in file_supports:
|
|
raise UploadFileExtError()
|
|
object_name = f'{object_name_prefix}/{generate_uuid()}.png'
|
|
file_path = await upload_file_to_minio(file, object_name=object_name, bucket_name=bucket_name)
|
|
if not isinstance(file_path, str):
|
|
file_path = str(file_path)
|
|
|
|
return UploadFileResponse(
|
|
file_path=file_path, # minioAccessible links
|
|
relative_path=object_name, # miniohitting the nail on the headobject_name
|
|
)
|
|
|
|
|
|
@router.post('/upload/icon')
|
|
async def upload_icon(request: Request,
|
|
login_user: UserPayload = Depends(UserPayload.get_login_user),
|
|
file: UploadFile = None):
|
|
try:
|
|
bucket = bisheng_settings.object_storage.minio.public_bucket
|
|
resp = await _upload_file(file,
|
|
object_name_prefix='icon',
|
|
file_supports=['jpeg', 'jpg', 'png'],
|
|
bucket_name=bucket)
|
|
return resp_200(data=resp)
|
|
except Exception as e:
|
|
raise e
|
|
finally:
|
|
await file.close()
|
|
|
|
|
|
@router.post('/upload/workflow/{workflow_id}')
|
|
async def upload_icon_workflow(request: Request,
|
|
login_user: UserPayload = Depends(UserPayload.get_login_user),
|
|
file: UploadFile = None,
|
|
workflow_id: str = Path(..., description='workflow id')):
|
|
try:
|
|
bucket = bisheng_settings.object_storage.minio.public_bucket
|
|
resp = await _upload_file(file, object_name_prefix=f'workflow/{workflow_id}', bucket_name=bucket)
|
|
return resp_200(data=resp)
|
|
except Exception as e:
|
|
raise e
|
|
finally:
|
|
await file.close()
|
|
|
|
|
|
@router.post('/upload/{flow_id}')
|
|
async def create_upload_file(file: UploadFile, flow_id: str):
|
|
# Cache file
|
|
try:
|
|
if len(file.filename) > 80:
|
|
file.filename = file.filename[-80:]
|
|
file_path = await save_uploaded_file(file, folder_name=flow_id, file_name=file.filename)
|
|
if not isinstance(file_path, str):
|
|
file_path = str(file_path)
|
|
return resp_200(UploadFileResponse(
|
|
flowId=flow_id,
|
|
file_path=file_path,
|
|
))
|
|
except Exception as exc:
|
|
logger.error(f'Error saving file: {exc}')
|
|
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
|
finally:
|
|
await file.close()
|
|
|
|
|
|
# get endpoint to return version of bisheng
|
|
@router.get('/version')
|
|
def get_version():
|
|
from bisheng import __version__
|
|
return resp_200({'version': __version__})
|