Finish MVP and dockerize

This commit is contained in:
2026-04-02 19:15:47 +02:00
parent 90ad5e0260
commit 30cb18b55e
50 changed files with 2346 additions and 17 deletions

View File

@@ -0,0 +1,51 @@
from __future__ import annotations
from datetime import datetime
from pathlib import Path
from typing import Tuple
from fastapi import UploadFile
from app.core.config import get_settings
from dlib.storage import MinioStorageClient, MinioStorageConfig
def _build_storage_client() -> MinioStorageClient:
settings = get_settings()
config = MinioStorageConfig(
bucket_name=settings.storage_bucket,
region_name=settings.storage_region,
endpoint_url=settings.storage_endpoint_url,
access_key_id=settings.storage_access_key,
secret_access_key=settings.storage_secret_key,
path_prefix=settings.storage_path_prefix,
)
return MinioStorageClient(config)
storage_client = _build_storage_client()
def build_artifact_key(owner_id: str, suffix: str) -> str:
safe_suffix = suffix.lstrip(".") if suffix else ""
timestamp = datetime.utcnow().strftime("%Y%m%d%H%M%S")
return storage_client.build_key(
stem=f"{owner_id}-{timestamp}", extension=safe_suffix
)
async def persist_upload(upload: UploadFile, owner_id: str) -> Tuple[str, bytes]:
data = await upload.read()
suffix = Path(upload.filename or "document.docx").suffix or ".docx"
key = build_artifact_key(owner_id, suffix)
storage_client.upload_bytes(key=key, data=data, content_type=upload.content_type)
return key, data
def build_public_url(key: str) -> str | None:
settings = get_settings()
if settings.storage_endpoint_url:
# Object storage accessible through endpoint URL
base = settings.storage_endpoint_url.rstrip("/")
return f"{base}/{settings.storage_bucket}/{key}"
return storage_client.generate_presigned_url(key=key, expires_in=3600)