Skip to content

Commit

Permalink
Merge pull request #30 from theriverman/develop
Browse files Browse the repository at this point in the history
Merging #28 and #29 from develop
  • Loading branch information
theriverman authored Nov 1, 2021
2 parents c9f2f9d + 3e34707 commit 9325386
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 19 deletions.
5 changes: 4 additions & 1 deletion django_minio_backend/apps.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.apps import AppConfig
from .utils import get_setting, ConfigurationError
from .models import MinioBackendStatic
from .models import MinioBackend, MinioBackendStatic


__all__ = ['DjangoMinioBackendConfig', ]
Expand All @@ -10,6 +10,9 @@ class DjangoMinioBackendConfig(AppConfig):
name = 'django_minio_backend'

def ready(self):
mb = MinioBackend()
mb.validate_settings()

consistency_check_on_start = get_setting('MINIO_CONSISTENCY_CHECK_ON_START', False)
if consistency_check_on_start:
from django.core.management import call_command
Expand Down
49 changes: 31 additions & 18 deletions django_minio_backend/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

from .utils import MinioServerStatus, PrivatePublicMixedError, ConfigurationError, get_setting

__all__ = ['MinioBackend', 'get_iso_date', 'iso_date_prefix', ]
__all__ = ['MinioBackend', 'MinioBackendStatic', 'get_iso_date', 'iso_date_prefix', ]


def get_iso_date() -> str:
Expand Down Expand Up @@ -85,7 +85,7 @@ def __init__(self,

self.__CLIENT: Union[minio.Minio, None] = None # This client is used for internal communication only. Communication this way should not leave the host network's perimeter
self.__CLIENT_FAKE: Union[minio.Minio, None] = None # This fake client is used for pre-signed URL generation only; it does not execute HTTP requests
self.__MINIO_ENDPOINT: str = get_setting("MINIO_ENDPOINT")
self.__MINIO_ENDPOINT: str = get_setting("MINIO_ENDPOINT", "")
self.__MINIO_EXTERNAL_ENDPOINT: str = get_setting("MINIO_EXTERNAL_ENDPOINT", self.__MINIO_ENDPOINT)
self.__MINIO_ACCESS_KEY: str = get_setting("MINIO_ACCESS_KEY")
self.__MINIO_SECRET_KEY: str = get_setting("MINIO_SECRET_KEY")
Expand Down Expand Up @@ -146,11 +146,14 @@ def _save(self, file_path_name: str, content: InMemoryUploadedFile) -> str:

# Upload object
file_path: Path = Path(file_path_name) # app name + file.suffix
content_bytes: io.BytesIO = io.BytesIO(content.read())
content_length: int = len(content_bytes.getvalue())

self.client.put_object(
bucket_name=self.bucket,
object_name=file_path.as_posix(),
data=content,
length=content.size,
data=content_bytes,
length=content_length,
content_type=self._guess_content_type(file_path_name, content),
metadata=self._META_KWARGS.get('metadata', None),
sse=self._META_KWARGS.get('sse', None),
Expand Down Expand Up @@ -333,16 +336,12 @@ def is_minio_available(self) -> MinioServerStatus:
@property
def client(self) -> minio.Minio:
"""Get handle to an (already) instantiated minio.Minio instance"""
if not self.__CLIENT:
return self._create_new_client()
return self.__CLIENT
return self.__CLIENT or self._create_new_client()

@property
def client_fake(self) -> minio.Minio:
"""Get handle to an (already) instantiated FAKE minio.Minio instance for generating signed URLs for external access"""
if not self.__CLIENT_FAKE:
return self._create_new_client(fake=True)
return self.__CLIENT_FAKE
return self.__CLIENT_FAKE or self._create_new_client(fake=True)

@property
def base_url(self) -> str:
Expand All @@ -358,14 +357,6 @@ def _create_new_client(self, fake: bool = False) -> minio.Minio:
"""
Instantiates a new Minio client and assigns it to their respective class variable
"""
# Safety Guards
if not self.PRIVATE_BUCKETS or not self.PUBLIC_BUCKETS:
raise ConfigurationError(
'MINIO_PRIVATE_BUCKETS or '
'MINIO_PUBLIC_BUCKETS '
'is not configured properly in your settings.py (or equivalent)'
)

mc = minio.Minio(
endpoint=self.__MINIO_EXTERNAL_ENDPOINT if fake else self.__MINIO_ENDPOINT,
access_key=self.__MINIO_ACCESS_KEY,
Expand Down Expand Up @@ -424,6 +415,28 @@ def set_bucket_to_public(self):
]}
self.set_bucket_policy(self.bucket, policy_public_read_only)

def validate_settings(self):
"""
validate_settings raises a ConfigurationError exception when one of the following conditions is met:
* Neither MINIO_PRIVATE_BUCKETS nor MINIO_PUBLIC_BUCKETS have been declared and configured with at least 1 bucket
* A mandatory parameter (ENDPOINT, ACCESS_KEY, SECRET_KEY or USE_HTTP) hasn't been declared and configured properly
"""
# minimum 1 bucket has to be declared
if not (get_setting("MINIO_PRIVATE_BUCKETS") or get_setting("MINIO_PUBLIC_BUCKETS")):
raise ConfigurationError(
'Either '
'MINIO_PRIVATE_BUCKETS'
' or '
'MINIO_PUBLIC_BUCKETS '
'must be configured in your settings.py (can be both)'
)
# mandatory parameters must be configured
mandatory_parameters = (self.__MINIO_ENDPOINT, self.__MINIO_ACCESS_KEY, self.__MINIO_SECRET_KEY, self.__MINIO_USE_HTTPS)
if any([bool(x) is False for x in mandatory_parameters]):
raise ConfigurationError(
"A mandatory parameter (ENDPOINT, ACCESS_KEY, SECRET_KEY or USE_HTTP) hasn't been configured properly"
)


@deconstructible
class MinioBackendStatic(MinioBackend):
Expand Down

0 comments on commit 9325386

Please sign in to comment.