70 lines
2.2 KiB
Python
70 lines
2.2 KiB
Python
"""
|
||
对象存储:只存字节;元数据登记走主账 attachment。
|
||
|
||
禁止:在本包维护工单状态。
|
||
骨架:S3 兼容客户端工厂与 put/get 占位(未配 endpoint 时不连网)。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import logging
|
||
from dataclasses import dataclass
|
||
from typing import Optional
|
||
|
||
from agent.config import Settings, get_settings
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
@dataclass
|
||
class ObjectStorageClient:
|
||
"""
|
||
对象存储骨架。
|
||
|
||
正式用 boto3/minio SDK;本版仅记录配置是否齐全,put_bytes 在未配置时返回 False。
|
||
"""
|
||
|
||
endpoint_url: str
|
||
bucket: str
|
||
access_key: str = ""
|
||
secret_key: str = ""
|
||
path_style: bool = True
|
||
|
||
@classmethod
|
||
def from_settings(cls, settings: Optional[Settings] = None) -> "ObjectStorageClient":
|
||
cfg = settings or get_settings()
|
||
return cls(
|
||
endpoint_url=getattr(cfg, "object_storage_endpoint_url", "") or "",
|
||
bucket=getattr(cfg, "object_storage_bucket", "") or "",
|
||
access_key=getattr(cfg, "object_storage_access_key", "") or "",
|
||
secret_key=getattr(cfg, "object_storage_secret_key", "") or "",
|
||
path_style=bool(getattr(cfg, "object_storage_path_style", True)),
|
||
)
|
||
|
||
def configured(self) -> bool:
|
||
"""endpoint + bucket 是否已配(不含密钥是否正确)。"""
|
||
return bool(self.endpoint_url and self.bucket)
|
||
|
||
def put_bytes_stub(self, *, key: str, data: bytes, content_type: str = "") -> bool:
|
||
"""
|
||
上传占位:未配置则 False;已配置也仅打日志不真正上传(骨架防误写桶)。
|
||
|
||
正式实现再打开真实 PUT。
|
||
"""
|
||
if not self.configured():
|
||
logger.warning("object_storage 未配置,跳过 put key=%s", key)
|
||
return False
|
||
logger.info(
|
||
"object_storage.put_bytes_stub bucket=%s key=%s bytes=%s(骨架不上传)",
|
||
self.bucket,
|
||
key,
|
||
len(data),
|
||
)
|
||
return True
|
||
|
||
|
||
# SDK 壳:见 s3_client(默认 dry_run)
|
||
from agent.storage.s3_client import S3ObjectStorage # noqa: E402
|
||
|
||
__all__ = ["ObjectStorageClient", "S3ObjectStorage"]
|