4e3a4b4602
带 Web 操作界面的备份系统,支持: - 数据源:MySQL 数据库(mysqldump)、服务器目录(tar.gz) - 存储目标:本地目录、S3 兼容对象存储(MinIO/Ceph/AWS S3) - 触发方式:手动 + Cron 定时调度(APScheduler) - 备份还原:MySQL 库、目录 - JWT 登录认证 + Fernet 字段加密 - 保留策略:按数量 + 按天数双重清理 技术栈:FastAPI + SQLAlchemy 2 + APScheduler + aioboto3; 前端 Vite + React 18 + TypeScript + Ant Design 5 + Zustand。 Docker Compose 一键起。 Co-Authored-By: Claude <noreply@anthropic.com>
46 lines
1.1 KiB
Python
46 lines
1.1 KiB
Python
"""存储后端抽象接口。"""
|
|
from abc import ABC, abstractmethod
|
|
from dataclasses import dataclass
|
|
from typing import AsyncIterator, Optional
|
|
|
|
|
|
@dataclass
|
|
class StorageObject:
|
|
key: str
|
|
size: int
|
|
last_modified: Optional[str] = None # ISO 8601
|
|
|
|
|
|
class BaseStorage(ABC):
|
|
"""所有存储后端实现的统一接口。"""
|
|
|
|
type: str = "base"
|
|
|
|
def __init__(self, config: dict):
|
|
self.config = config
|
|
|
|
@abstractmethod
|
|
async def test_connection(self) -> tuple[bool, str]:
|
|
"""测试连通性。返回 (ok, message)。"""
|
|
|
|
@abstractmethod
|
|
async def upload_stream(
|
|
self,
|
|
source: AsyncIterator[bytes],
|
|
key: str,
|
|
content_type: str = "application/octet-stream",
|
|
) -> tuple[int, str]:
|
|
"""流式上传。返回 (size_bytes, sha256_hex)。"""
|
|
|
|
@abstractmethod
|
|
async def download_stream(self, key: str) -> AsyncIterator[bytes]: ...
|
|
|
|
@abstractmethod
|
|
async def delete(self, key: str) -> None: ...
|
|
|
|
@abstractmethod
|
|
async def exists(self, key: str) -> bool: ...
|
|
|
|
@abstractmethod
|
|
async def list(self, prefix: str = "") -> list[StorageObject]: ...
|