Source code for keepluggable.storage_file
"""Strategies for storing file payloads."""
from abc import ABCMeta, abstractmethod
import mimetypes
from typing import Any, BinaryIO, Dict, Sequence
from keepluggable.orchestrator import Orchestrator
[docs]def get_extension(mime_type: str) -> str:
"""From a ``mime_type`` return a corresponding file extension, or empty."""
extensions = sorted(mimetypes.guess_all_extensions(
mime_type, strict=False))
return extensions[0] if extensions else ''
[docs]class BasePayloadStorage(metaclass=ABCMeta):
"""Abstract base class ― formal interface for payload storage backends."""
def __init__(self, orchestrator: Orchestrator) -> None:
"""Just store the orchestrator instance."""
self.orchestrator = orchestrator
[docs] @abstractmethod
def put(
self, namespace: str, metadata: Dict[str, Any], bytes_io: BinaryIO,
) -> None:
"""Store a file (``bytes_io``) inside ``namespace``."""
raise NotImplementedError()
[docs] @abstractmethod
def get_reader(self, namespace: str, metadata: Dict[str, Any]) -> BinaryIO:
"""Return an open "file" object from which the payload can be read.
Otherwise, raise KeyError.
"""
raise NotImplementedError()
def _get_filename(self, metadata: Dict[str, Any]) -> str:
return metadata['md5'] + get_extension(metadata['mime_type'])
[docs] @abstractmethod
def get_url(
self, namespace: str, metadata: Dict[str, Any], seconds: int = 3600,
https: bool = True,
) -> str:
"""Return a URL for a certain stored file."""
raise NotImplementedError()
[docs] @abstractmethod
def delete(
self, namespace: str, metadatas: Sequence[Dict[str, Any]],
) -> None:
"""Delete many files within a namespace."""
raise NotImplementedError()