Added MinIO integration and logic

This commit is contained in:
kyy
2025-08-12 12:25:56 +09:00
parent d656c6f8b1
commit 6df78c9fae
5 changed files with 345 additions and 126 deletions

99
utils/minio_utils.py Normal file
View File

@@ -0,0 +1,99 @@
import logging
from datetime import timedelta
from config.setting import (
MINIO_ACCESS_KEY,
MINIO_BUCKET_NAME,
MINIO_ENDPOINT,
MINIO_SECRET_KEY,
)
from fastapi import UploadFile
from minio import Minio
from minio.error import S3Error
logger = logging.getLogger(__name__)
def get_minio_client():
"""MinIO 클라이언트를 생성하고 반환합니다."""
try:
client = Minio(
MINIO_ENDPOINT,
access_key=MINIO_ACCESS_KEY,
secret_key=MINIO_SECRET_KEY,
secure=False, # 개발 환경에서는 False, 프로덕션에서는 True 사용
)
# 버킷 존재 여부 확인 및 생성
found = client.bucket_exists(MINIO_BUCKET_NAME)
if not found:
client.make_bucket(MINIO_BUCKET_NAME)
logger.info(f"Bucket '{MINIO_BUCKET_NAME}' created.")
else:
logger.info(f"Bucket '{MINIO_BUCKET_NAME}' already exists.")
return client
except (S3Error, Exception) as e:
logger.error(f"Error connecting to MinIO: {e}")
raise
def upload_file_to_minio(file: UploadFile, bucket_name: str, object_name: str) -> str:
"""
파일을 MinIO에 업로드하고, presigned URL을 반환합니다.
Args:
file (UploadFile): FastAPI의 UploadFile 객체
bucket_name (str): 업로드할 버킷 이름
object_name (str): 저장될 객체 이름 (경로 포함 가능)
Returns:
str: 생성된 presigned URL
"""
minio_client = get_minio_client()
try:
# 1. 버킷 존재 확인 및 생성
found = minio_client.bucket_exists(bucket_name)
if not found:
minio_client.make_bucket(bucket_name)
logger.info(f"✅ 버킷 '{bucket_name}' 생성 완료.")
# 2. 파일 업로드
file.file.seek(0) # 파일 포인터를 처음으로 이동
minio_client.put_object(
bucket_name,
object_name,
file.file,
length=-1, # 파일 크기를 모를 때 -1로 설정
part_size=10 * 1024 * 1024, # 10MB 단위로 청크 업로드
)
logger.info(f"'{object_name}' -> '{bucket_name}' 업로드 성공.")
# 3. Presigned URL 생성
presigned_url = minio_client.presigned_get_object(
bucket_name,
object_name,
expires=timedelta(days=7), # URL 만료 기간 (예: 7일, 필요에 따라 조절 가능)
)
logger.info(f"✅ Presigned URL 생성 완료: {presigned_url}")
return presigned_url
except Exception as e:
logger.error(f"❌ MinIO 작업 실패: {e}")
raise # 실패 시 예외를 다시 발생시켜 호출 측에서 처리하도록 함
def download_file_from_minio(object_name: str, local_path: str):
"""
MinIO에서 객체를 다운로드하여 로컬 파일로 저장합니다.
Args:
object_name (str): 다운로드할 객체의 이름
local_path (str): 파일을 저장할 로컬 경로
"""
client = get_minio_client()
try:
client.fget_object(MINIO_BUCKET_NAME, object_name, local_path)
logger.info(f"'{object_name}' downloaded to '{local_path}' successfully.")
except S3Error as e:
logger.error(f"Error downloading from MinIO: {e}")
raise