Spaces:
Paused
Paused
File size: 10,836 Bytes
296386a 9822188 296386a 9822188 296386a 9822188 296386a 9822188 296386a 9822188 296386a 9822188 296386a 9822188 296386a 9822188 296386a 9822188 296386a 9822188 296386a 9822188 296386a 9822188 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 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 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | from __future__ import annotations
from typing import Annotated, Any, Literal
from fastapi import Body, Path, Query, Request, Response
from sqlalchemy.ext.asyncio import AsyncSession
from common.aspect.db_seesion import DBSessionDependency
from common.aspect.interface_auth import UserInterfaceAuthDependency
from common.aspect.pre_auth import PreAuthDependency
from common.router import APIRouterPro
from common.vo import DataResponseModel, ResponseBaseModel
from module_admin.entity.vo.storage_vo import (
StorageDatabaseRowCreateModel,
StorageDatabaseRowDeleteModel,
StorageDatabaseRowUpdateModel,
StorageRedisStringMutationModel,
)
from module_admin.service.storage_service import StorageService
from utils.log_util import logger
from utils.response_util import ResponseUtil
storage_controller = APIRouterPro(
prefix='/monitor/storage',
order_num=16,
tags=['系统监控-存储监控'],
dependencies=[PreAuthDependency()],
)
@storage_controller.get(
'/backup/status',
summary='获取内部备份状态接口',
description='用于获取 Hugging Face Space 内部 PostgreSQL/Redis 备份状态',
response_model=DataResponseModel[dict[str, Any]],
dependencies=[UserInterfaceAuthDependency('monitor:storage:query')],
)
async def get_backup_status(request: Request) -> Response:
backup_status = StorageService.get_backup_status_services()
logger.info('获取内部备份状态成功')
return ResponseUtil.success(data=backup_status)
@storage_controller.post(
'/backup/sync/{target}',
summary='触发内部备份同步接口',
description='用于请求 PostgreSQL/Redis 立即执行一次 GitHub 备份同步',
response_model=DataResponseModel[dict[str, str]],
dependencies=[UserInterfaceAuthDependency('monitor:storage:sync')],
)
async def trigger_backup_sync(
request: Request, target: Annotated[Literal['postgres', 'redis', 'all'], Path(description='同步目标')]
) -> Response:
result = StorageService.request_backup_sync_services(target)
logger.info(f'已请求内部备份同步: {target}')
return ResponseUtil.success(msg='已提交同步请求', data=result)
@storage_controller.get(
'/database/tables',
summary='获取内部 PostgreSQL 表列表接口',
description='用于获取内部 PostgreSQL 指定 schema 下的表列表',
response_model=DataResponseModel[list[dict[str, Any]]],
dependencies=[UserInterfaceAuthDependency('monitor:storage:query')],
)
async def get_database_tables(
request: Request,
query_db: Annotated[AsyncSession, DBSessionDependency()],
schema: Annotated[str, Query(description='schema 名称')] = 'public',
) -> Response:
try:
table_list = await StorageService.get_pg_table_list_services(query_db, schema=schema)
except ValueError as exc:
return ResponseUtil.error(msg=str(exc))
logger.info(f'获取 schema={schema} 的 PostgreSQL 表列表成功')
return ResponseUtil.success(data=table_list)
@storage_controller.get(
'/database/tables/{table_name}',
summary='获取内部 PostgreSQL 表详情接口',
description='用于获取内部 PostgreSQL 指定数据表的列信息与主键信息',
response_model=DataResponseModel[dict[str, Any]],
dependencies=[UserInterfaceAuthDependency('monitor:storage:query')],
)
async def get_database_table_detail(
request: Request,
table_name: Annotated[str, Path(description='表名称')],
query_db: Annotated[AsyncSession, DBSessionDependency()],
schema: Annotated[str, Query(description='schema 名称')] = 'public',
) -> Response:
try:
detail = await StorageService.get_pg_table_detail_services(query_db, table_name=table_name, schema=schema)
except ValueError as exc:
return ResponseUtil.error(msg=str(exc))
logger.info(f'获取 PostgreSQL 表详情成功: {schema}.{table_name}')
return ResponseUtil.success(data=detail)
@storage_controller.get(
'/database/tables/{table_name}/rows',
summary='获取内部 PostgreSQL 表数据接口',
description='用于分页获取内部 PostgreSQL 数据表内容',
response_model=DataResponseModel[dict[str, Any]],
dependencies=[UserInterfaceAuthDependency('monitor:storage:query')],
)
async def get_database_table_rows(
request: Request,
table_name: Annotated[str, Path(description='表名称')],
query_db: Annotated[AsyncSession, DBSessionDependency()],
schema: Annotated[str, Query(description='schema 名称')] = 'public',
page_num: Annotated[int, Query(description='页码')] = 1,
page_size: Annotated[int, Query(description='每页条数')] = 50,
) -> Response:
try:
rows = await StorageService.get_pg_table_rows_services(
query_db, table_name=table_name, schema=schema, page_num=page_num, page_size=page_size
)
except ValueError as exc:
return ResponseUtil.error(msg=str(exc))
logger.info(f'获取 PostgreSQL 表数据成功: {schema}.{table_name}')
return ResponseUtil.success(data=rows)
@storage_controller.post(
'/database/tables/{table_name}/rows',
summary='新增内部 PostgreSQL 表数据接口',
description='用于向内部 PostgreSQL 指定数据表新增一条记录',
response_model=DataResponseModel[dict[str, Any]],
dependencies=[UserInterfaceAuthDependency('monitor:storage:add')],
)
async def create_database_table_row(
request: Request,
table_name: Annotated[str, Path(description='表名称')],
payload: Annotated[StorageDatabaseRowCreateModel, Body()],
query_db: Annotated[AsyncSession, DBSessionDependency()],
) -> Response:
try:
result = await StorageService.create_pg_row_services(query_db, table_name=table_name, payload=payload)
except ValueError as exc:
return ResponseUtil.error(msg=str(exc))
logger.info(f'新增 PostgreSQL 表数据成功: {payload.schema}.{table_name}')
return ResponseUtil.success(msg=result['message'], data=result)
@storage_controller.put(
'/database/tables/{table_name}/rows',
summary='修改内部 PostgreSQL 表数据接口',
description='用于按主键更新内部 PostgreSQL 指定数据表的一条记录',
response_model=DataResponseModel[dict[str, Any]],
dependencies=[UserInterfaceAuthDependency('monitor:storage:edit')],
)
async def update_database_table_row(
request: Request,
table_name: Annotated[str, Path(description='表名称')],
payload: Annotated[StorageDatabaseRowUpdateModel, Body()],
query_db: Annotated[AsyncSession, DBSessionDependency()],
) -> Response:
try:
result = await StorageService.update_pg_row_services(query_db, table_name=table_name, payload=payload)
except ValueError as exc:
return ResponseUtil.error(msg=str(exc))
logger.info(f'修改 PostgreSQL 表数据成功: {payload.schema}.{table_name}')
return ResponseUtil.success(msg=result['message'], data=result)
@storage_controller.delete(
'/database/tables/{table_name}/rows',
summary='删除内部 PostgreSQL 表数据接口',
description='用于按主键删除内部 PostgreSQL 指定数据表的一条记录',
response_model=DataResponseModel[dict[str, Any]],
dependencies=[UserInterfaceAuthDependency('monitor:storage:remove')],
)
async def delete_database_table_row(
request: Request,
table_name: Annotated[str, Path(description='表名称')],
payload: Annotated[StorageDatabaseRowDeleteModel, Body()],
query_db: Annotated[AsyncSession, DBSessionDependency()],
) -> Response:
try:
result = await StorageService.delete_pg_row_services(query_db, table_name=table_name, payload=payload)
except ValueError as exc:
return ResponseUtil.error(msg=str(exc))
logger.info(f'删除 PostgreSQL 表数据成功: {payload.schema}.{table_name}')
return ResponseUtil.success(msg=result['message'], data=result)
@storage_controller.get(
'/redis/scan',
summary='扫描内部 Redis 键接口',
description='用于按 pattern 扫描内部 Redis 键信息',
response_model=DataResponseModel[dict[str, Any]],
dependencies=[UserInterfaceAuthDependency('monitor:storage:query')],
)
async def scan_redis_keys(
request: Request,
pattern: Annotated[str, Query(description='Redis 键匹配模式')] = '*',
cursor: Annotated[int, Query(description='Redis 游标')] = 0,
count: Annotated[int, Query(description='扫描数量')] = 50,
) -> Response:
result = await StorageService.scan_redis_keys_services(request, pattern=pattern, cursor=cursor, count=count)
logger.info(f'扫描内部 Redis 键成功: pattern={pattern}, cursor={cursor}')
return ResponseUtil.success(data=result)
@storage_controller.get(
'/redis/key',
summary='查看内部 Redis 键详情接口',
description='用于查看内部 Redis 指定键的数据详情',
response_model=DataResponseModel[dict[str, Any]],
dependencies=[UserInterfaceAuthDependency('monitor:storage:query')],
)
async def get_redis_key_detail(
request: Request, key: Annotated[str, Query(description='Redis 键名')]
) -> Response:
try:
result = await StorageService.get_redis_key_detail_services(request, key=key)
except ValueError as exc:
return ResponseUtil.error(msg=str(exc))
logger.info(f'查看内部 Redis 键详情成功: key={key}')
return ResponseUtil.success(data=result)
@storage_controller.post(
'/redis/string',
summary='写入内部 Redis 字符串键接口',
description='用于新增或覆盖内部 Redis 的字符串键',
response_model=DataResponseModel[dict[str, Any]],
dependencies=[UserInterfaceAuthDependency('monitor:storage:edit')],
)
async def upsert_redis_string(
request: Request, payload: Annotated[StorageRedisStringMutationModel, Body()]
) -> Response:
try:
result = await StorageService.upsert_redis_string_services(request, payload)
except ValueError as exc:
return ResponseUtil.error(msg=str(exc))
logger.info(f'写入 Redis 字符串键成功: key={payload.key}')
return ResponseUtil.success(msg='写入成功', data=result)
@storage_controller.delete(
'/redis/key',
summary='删除内部 Redis 键接口',
description='用于删除内部 Redis 指定键',
response_model=DataResponseModel[dict[str, Any]],
dependencies=[UserInterfaceAuthDependency('monitor:storage:remove')],
)
async def delete_redis_key(
request: Request, key: Annotated[str, Query(description='Redis 键名')]
) -> Response:
try:
result = await StorageService.delete_redis_key_services(request, key=key)
except ValueError as exc:
return ResponseUtil.error(msg=str(exc))
logger.info(f'删除 Redis 键成功: key={key}')
return ResponseUtil.success(msg='删除成功', data=result)
|