2026-10-04 02:45:25 +04:00

45 lines
2.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Клиент S3 (MinIO) сервиса: чтение исходника и запись файла результата (design D-4).
`Storage` — протокол, от которого зависит воркер (design D-7): в unit-тестах его подменяет фейк, в приложении —
`S3Storage` поверх `miniopy_async.Minio`. Бакет передаётся в каждый вызов: исходник читается из `request.s3.bucket`,
результат пишется в тот же бакет.
"""
import json
from io import BytesIO
from typing import Any, Protocol, runtime_checkable
from miniopy_async import Minio
JSON_CONTENT_TYPE = "application/json"
@runtime_checkable
class Storage(Protocol):
"""Хранилище объектов, нужное воркеру: байты исходника и JSON результата."""
async def get_bytes(self, bucket: str, key: str) -> bytes: ...
async def put_json(self, bucket: str, key: str, obj: Any) -> None: ...
class S3Storage:
"""`Storage` поверх MinIO. `bucket` — бакет из настроек (проверяется при старте), методы принимают бакет явно."""
def __init__(self, client: Minio, bucket_name: str) -> None:
self.client = client
self.bucket = bucket_name
async def get_bytes(self, bucket: str, key: str) -> bytes:
"""Содержимое объекта целиком; ошибки MinIO/сети пробрасываются (воркер превращает их в `FILE_READ_ERROR`)."""
response = await self.client.get_object(bucket, key)
try:
return await response.read()
finally:
response.release()
async def put_json(self, bucket: str, key: str, obj: Any) -> None:
"""Записывает JSON-сериализуемый `obj` как UTF-8 (`application/json`, кириллица без экранирования)."""
body = json.dumps(obj, ensure_ascii=False).encode("utf-8")
await self.client.put_object(bucket, key, BytesIO(body), length=len(body), content_type=JSON_CONTENT_TYPE)