Use __init_subclass__ to register storage backends
See https://docs.python.org/3.6/whatsnew/3.6.html#pep-487-simpler-customization-of-class-creation
This commit is contained in:
parent
1f3d699a0c
commit
6eadc09c10
@ -9,7 +9,7 @@ from gcloud.exceptions import NotFound
|
||||
from flask import current_app, g
|
||||
from werkzeug.local import LocalProxy
|
||||
|
||||
from pillar.api.utils.storage import register_backend, Bucket, Blob
|
||||
from pillar.api.utils.storage import Bucket, Blob
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -34,7 +34,6 @@ def get_client():
|
||||
gcs = LocalProxy(get_client)
|
||||
|
||||
|
||||
@register_backend('gcs')
|
||||
class GoogleCloudStorageBucket(Bucket):
|
||||
"""Cloud Storage bucket interface. We create a bucket for every project. In
|
||||
the bucket we create first level subdirs as follows:
|
||||
@ -51,6 +50,8 @@ class GoogleCloudStorageBucket(Bucket):
|
||||
|
||||
"""
|
||||
|
||||
backend_name = 'gcs'
|
||||
|
||||
def __init__(self, name, subdir='_/'):
|
||||
super(GoogleCloudStorageBucket, self).__init__(name=name)
|
||||
try:
|
||||
|
@ -14,18 +14,6 @@ from pillar.api.utils.imaging import generate_local_thumbnails
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Mapping from backend name to backend class
|
||||
backends = {}
|
||||
|
||||
|
||||
def register_backend(backend_name):
|
||||
def wrapper(cls):
|
||||
assert backend_name not in backends
|
||||
backends[backend_name] = cls
|
||||
return cls
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class Bucket(object, metaclass=abc.ABCMeta):
|
||||
"""Can be a GCS bucket or simply a project folder in Pillar
|
||||
@ -36,9 +24,24 @@ class Bucket(object, metaclass=abc.ABCMeta):
|
||||
|
||||
"""
|
||||
|
||||
# Mapping from backend name to Bucket class
|
||||
backends = {}
|
||||
|
||||
backend_name: str = None # define in subclass.
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
super().__init_subclass__(**kwargs)
|
||||
assert cls.backend_name, '%s.backend_name must be non-empty string' % cls
|
||||
cls.backends[cls.backend_name] = cls
|
||||
|
||||
@classmethod
|
||||
def for_backend(cls, backend_name: str) -> type:
|
||||
"""Returns the Bucket subclass for the given backend."""
|
||||
return cls.backends[backend_name]
|
||||
|
||||
@abc.abstractmethod
|
||||
def blob(self, blob_name):
|
||||
"""Factory constructor for blob object.
|
||||
@ -175,10 +178,8 @@ class Blob(object, metaclass=abc.ABCMeta):
|
||||
file_id, status, r)
|
||||
|
||||
|
||||
@register_backend('local')
|
||||
class LocalBucket(Bucket):
|
||||
def __init__(self, name):
|
||||
super(LocalBucket, self).__init__(name=name)
|
||||
backend_name = 'local'
|
||||
|
||||
def blob(self, blob_name):
|
||||
return LocalBlob(name=blob_name, bucket=self)
|
||||
@ -259,7 +260,6 @@ class LocalBlob(Blob):
|
||||
def default_storage_backend(name):
|
||||
from flask import current_app
|
||||
|
||||
backend_cls = backends[current_app.config['STORAGE_BACKEND']]
|
||||
backend_name = current_app.config['STORAGE_BACKEND']
|
||||
backend_cls = Bucket.for_backend(backend_name)
|
||||
return backend_cls(name)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user