Files
Pre_Seg_Server/backend/minio_client.py
admin b5413066a0 添加Docker自包含部署分支
- 新增 Seg_Server_Docker 自包含部署内容,包含前后端、FastAPI、Celery、PostgreSQL、Redis、MinIO、演示视频和 DICOM 数据。

- 保留 demo 数据以支持恢复演示出厂设置,排除 SAM 2.1 .pt 权重并在 README 中补充下载命令。

- 补充 GPU 部署、backend/worker 镜像复用、frpc/frps + NPM 公网域名反代部署说明。

- 在 .env/.env.example 中用 # XXXX 标注局域网和公网域名部署需要修改的配置项。

- 添加部署分支 .gitignore,忽略本地模型权重、构建产物、缓存和日志。
2026-05-07 19:06:07 +08:00

143 lines
3.8 KiB
Python

"""MinIO client wrapper for object storage operations."""
import io
import logging
from typing import Optional
from minio import Minio
from minio.error import S3Error
from config import settings
logger = logging.getLogger(__name__)
BUCKET_NAME = "seg-media"
_minio_client: Optional[Minio] = None
_minio_public_client: Optional[Minio] = None
def get_minio_client() -> Minio:
"""Return a singleton MinIO client instance."""
global _minio_client
if _minio_client is None:
_minio_client = Minio(
settings.minio_endpoint,
access_key=settings.minio_access_key,
secret_key=settings.minio_secret_key,
secure=settings.minio_secure,
)
return _minio_client
def get_minio_public_client() -> Minio:
"""Return a MinIO client configured for browser-facing presigned URLs."""
global _minio_public_client
if _minio_public_client is None:
endpoint = settings.minio_public_endpoint or settings.minio_endpoint
_minio_public_client = Minio(
endpoint,
access_key=settings.minio_access_key,
secret_key=settings.minio_secret_key,
secure=settings.minio_secure,
)
return _minio_public_client
def ensure_bucket_exists() -> None:
"""Create the bucket if it does not already exist."""
client = get_minio_client()
try:
if not client.bucket_exists(BUCKET_NAME):
client.make_bucket(BUCKET_NAME)
logger.info("Created MinIO bucket: %s", BUCKET_NAME)
else:
logger.info("MinIO bucket %s already exists", BUCKET_NAME)
except S3Error as exc:
logger.error("MinIO bucket check/creation failed: %s", exc)
raise
def upload_file(
object_name: str,
data: bytes,
content_type: str = "application/octet-stream",
length: int = -1,
) -> str:
"""Upload bytes to MinIO and return the object name.
Args:
object_name: Destination path inside the bucket.
data: Raw bytes or a file-like object.
content_type: MIME type of the object.
length: Object size; -1 for unknown (uses chunked upload).
Returns:
The object name (same as input).
"""
client = get_minio_client()
if isinstance(data, bytes):
data = io.BytesIO(data)
length = len(data.getvalue())
try:
client.put_object(
BUCKET_NAME,
object_name,
data,
length=length,
content_type=content_type,
)
logger.info("Uploaded to MinIO: %s", object_name)
return object_name
except S3Error as exc:
logger.error("MinIO upload failed: %s", exc)
raise
from datetime import timedelta
def get_presigned_url(
object_name: str,
expires: int = 3600,
method: str = "GET",
) -> str:
"""Generate a presigned URL for an object.
Args:
object_name: Path inside the bucket.
expires: Expiration time in seconds (default 1 hour).
method: HTTP method (GET or PUT).
Returns:
Presigned URL string.
"""
client = get_minio_public_client()
try:
url = client.get_presigned_url(method, BUCKET_NAME, object_name, expires=timedelta(seconds=expires))
return url
except S3Error as exc:
logger.error("MinIO presigned URL failed: %s", exc)
raise
def download_file(object_name: str) -> bytes:
"""Download an object from MinIO and return its bytes.
Args:
object_name: Path inside the bucket.
Returns:
Raw bytes of the object.
"""
client = get_minio_client()
try:
response = client.get_object(BUCKET_NAME, object_name)
data = response.read()
response.close()
response.release_conn()
return data
except S3Error as exc:
logger.error("MinIO download failed: %s", exc)
raise