switch from minio to seaweedfs

This commit is contained in:
2026-03-26 16:57:48 -07:00
parent 56f4c345cb
commit bb5f8b8494
10 changed files with 97 additions and 85 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "officeconvert-server"
version = "0.1.0"
description = "ConnectRPC server orchestrating file conversions with MinIO."
description = "ConnectRPC server orchestrating file conversions with S3-compatible storage."
readme = "../../../README.md"
requires-python = ">=3.12"
dependencies = [
@@ -6,18 +6,18 @@ from officeconvertapi.v1.conversion_connect import ConversionServiceASGIApplicat
from officeconvert_server.config import load_server_config
from officeconvert_server.service import ConversionServiceImpl
from officeconvert_server.storage import MinIOStore
from officeconvert_server.storage import S3Store
def create_app() -> ConversionServiceASGIApplication:
"""Construct and return the configured Connect ASGI application."""
config = load_server_config()
store = MinIOStore(
endpoint=config.minio_endpoint,
access_key=config.minio_access_key,
secret_key=config.minio_secret_key,
secure=config.minio_secure,
public_endpoint=config.minio_public_endpoint,
store = S3Store(
endpoint=config.s3_endpoint,
access_key=config.s3_access_key,
secret_key=config.s3_secret_key,
secure=config.s3_secure,
public_endpoint=config.s3_public_endpoint,
)
service = ConversionServiceImpl(config=config, store=store)
return ConversionServiceASGIApplication(service)
@@ -10,24 +10,24 @@ import os
class ServerConfig:
"""Defines environment-driven settings for server orchestration."""
minio_endpoint: str
minio_access_key: str
minio_secret_key: str
minio_secure: bool
minio_public_endpoint: str
minio_session_ttl_seconds: int
s3_endpoint: str
s3_access_key: str
s3_secret_key: str
s3_secure: bool
s3_public_endpoint: str
s3_session_ttl_seconds: int
conversion_cleanup_delay_seconds: int
def load_server_config() -> ServerConfig:
"""Load server configuration from environment variables."""
return ServerConfig(
minio_endpoint=os.getenv("MINIO_ENDPOINT", "localhost:9000"),
minio_access_key=os.getenv("MINIO_ACCESS_KEY", "minioadmin"),
minio_secret_key=os.getenv("MINIO_SECRET_KEY", "minioadmin"),
minio_secure=os.getenv("MINIO_USE_SSL", "false").lower() == "true",
minio_public_endpoint=os.getenv("MINIO_PUBLIC_ENDPOINT", "localhost:9000"),
minio_session_ttl_seconds=int(os.getenv("MINIO_SESSION_TTL_SECONDS", "3600")),
s3_endpoint=os.getenv("S3_ENDPOINT", "localhost:8333"),
s3_access_key=os.getenv("S3_ACCESS_KEY", "minioadmin"),
s3_secret_key=os.getenv("S3_SECRET_KEY", "minioadmin"),
s3_secure=os.getenv("S3_USE_SSL", "false").lower() == "true",
s3_public_endpoint=os.getenv("S3_PUBLIC_ENDPOINT", "localhost:8333"),
s3_session_ttl_seconds=int(os.getenv("S3_SESSION_TTL_SECONDS", "3600")),
conversion_cleanup_delay_seconds=int(
os.getenv("CONVERSION_CLEANUP_DELAY_SECONDS", "3600")
),
@@ -18,13 +18,13 @@ from officeconvertapi.v1 import conversion_connect, conversion_pb2
from officeconvert_server.config import ServerConfig
from officeconvert_server.models import ConversionSession, utc_now
from officeconvert_server.storage import MinIOStore
from officeconvert_server.storage import S3Store
class ConversionServiceImpl(conversion_connect.ConversionService):
"""Implements the conversion API with in-memory state and MinIO orchestration."""
"""Implements the conversion API with in-memory state and S3 orchestration."""
def __init__(self, config: ServerConfig, store: MinIOStore) -> None:
def __init__(self, config: ServerConfig, store: S3Store) -> None:
"""Initialize service with runtime config and storage adapter."""
self._config = config
self._store = store
@@ -47,13 +47,13 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
conversion_id = str(uuid.uuid4())
bucket_name = f"oc-{conversion_id}"
upload_key = "input/source.pptx"
expires_at = utc_now() + timedelta(seconds=self._config.minio_session_ttl_seconds)
expires_at = utc_now() + timedelta(seconds=self._config.s3_session_ttl_seconds)
self._store.ensure_bucket(bucket_name)
upload_url = self._store.presigned_put_url(
bucket_name,
upload_key,
ttl_seconds=self._config.minio_session_ttl_seconds,
ttl_seconds=self._config.s3_session_ttl_seconds,
)
session = ConversionSession(
@@ -143,7 +143,7 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
request: conversion_pb2.DeleteConversionRequest,
ctx: RequestContext,
) -> conversion_pb2.DeleteConversionResponse:
"""Delete a conversion session and associated MinIO/local artifacts."""
"""Delete a conversion session and associated object storage/local artifacts."""
del ctx
async with self._lock:
session = self._sessions.pop(request.conversion_id, None)
@@ -218,7 +218,7 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
image_url = self._store.presigned_get_url(
session.bucket_name,
object_key,
ttl_seconds=self._config.minio_session_ttl_seconds,
ttl_seconds=self._config.s3_session_ttl_seconds,
)
response_slides.append(
conversion_pb2.Slide(
@@ -1,4 +1,4 @@
"""MinIO helper abstraction for upload and artifact lifecycle."""
"""S3-compatible storage helper abstraction for upload and artifact lifecycle."""
from __future__ import annotations
@@ -11,8 +11,8 @@ from minio.deleteobjects import DeleteObject
from minio.error import S3Error
class MinIOStore:
"""Provides typed helper methods around MinIO object storage operations."""
class S3Store:
"""Provides typed helper methods around S3-compatible object storage operations."""
def __init__(
self,
@@ -23,7 +23,7 @@ class MinIOStore:
secure: bool,
public_endpoint: str,
) -> None:
"""Initialize MinIO clients for internal and public URL generation."""
"""Initialize S3 clients for internal and public URL generation."""
self._client = Minio(
endpoint,
access_key=access_key,
@@ -59,12 +59,12 @@ class MinIOStore:
)
def fget_object(self, bucket_name: str, object_key: str, output_path: Path) -> None:
"""Download one object from MinIO to a local filesystem path."""
"""Download one object from storage to a local filesystem path."""
output_path.parent.mkdir(parents=True, exist_ok=True)
self._client.fget_object(bucket_name, object_key, str(output_path))
def fput_object(self, bucket_name: str, object_key: str, source_path: Path) -> None:
"""Upload one local filesystem object to MinIO."""
"""Upload one local filesystem object to storage."""
self._client.fput_object(bucket_name, object_key, str(source_path))
def remove_bucket_tree(self, bucket_name: str) -> None: