| | |
| | import inspect |
| | from typing import Optional, Type, Union |
| |
|
| | from .base import BaseStorageBackend |
| | from .http_backend import HTTPBackend |
| | from .lmdb_backend import LmdbBackend |
| | from .local_backend import LocalBackend |
| | from .memcached_backend import MemcachedBackend |
| | from .petrel_backend import PetrelBackend |
| |
|
| | backends: dict = {} |
| | prefix_to_backends: dict = {} |
| |
|
| |
|
| | def _register_backend(name: str, |
| | backend: Type[BaseStorageBackend], |
| | force: bool = False, |
| | prefixes: Union[str, list, tuple, None] = None): |
| | """Register a backend. |
| | |
| | Args: |
| | name (str): The name of the registered backend. |
| | backend (BaseStorageBackend): The backend class to be registered, |
| | which must be a subclass of :class:`BaseStorageBackend`. |
| | force (bool): Whether to override the backend if the name has already |
| | been registered. Defaults to False. |
| | prefixes (str or list[str] or tuple[str], optional): The prefix |
| | of the registered storage backend. Defaults to None. |
| | """ |
| | global backends, prefix_to_backends |
| |
|
| | if not isinstance(name, str): |
| | raise TypeError('the backend name should be a string, ' |
| | f'but got {type(name)}') |
| |
|
| | if not inspect.isclass(backend): |
| | raise TypeError(f'backend should be a class, but got {type(backend)}') |
| | if not issubclass(backend, BaseStorageBackend): |
| | raise TypeError( |
| | f'backend {backend} is not a subclass of BaseStorageBackend') |
| |
|
| | if name in backends and not force: |
| | raise ValueError(f'{name} is already registered as a storage backend, ' |
| | 'add "force=True" if you want to override it') |
| | backends[name] = backend |
| |
|
| | if prefixes is not None: |
| | if isinstance(prefixes, str): |
| | prefixes = [prefixes] |
| | else: |
| | assert isinstance(prefixes, (list, tuple)) |
| |
|
| | for prefix in prefixes: |
| | if prefix in prefix_to_backends and not force: |
| | raise ValueError( |
| | f'{prefix} is already registered as a storage backend,' |
| | ' add "force=True" if you want to override it') |
| |
|
| | prefix_to_backends[prefix] = backend |
| |
|
| |
|
| | def register_backend(name: str, |
| | backend: Optional[Type[BaseStorageBackend]] = None, |
| | force: bool = False, |
| | prefixes: Union[str, list, tuple, None] = None): |
| | """Register a backend. |
| | |
| | Args: |
| | name (str): The name of the registered backend. |
| | backend (class, optional): The backend class to be registered, |
| | which must be a subclass of :class:`BaseStorageBackend`. |
| | When this method is used as a decorator, backend is None. |
| | Defaults to None. |
| | force (bool): Whether to override the backend if the name has already |
| | been registered. Defaults to False. |
| | prefixes (str or list[str] or tuple[str], optional): The prefix |
| | of the registered storage backend. Defaults to None. |
| | |
| | This method can be used as a normal method or a decorator. |
| | |
| | Examples: |
| | |
| | >>> class NewBackend(BaseStorageBackend): |
| | ... def get(self, filepath): |
| | ... return filepath |
| | ... |
| | ... def get_text(self, filepath): |
| | ... return filepath |
| | >>> register_backend('new', NewBackend) |
| | |
| | >>> @register_backend('new') |
| | ... class NewBackend(BaseStorageBackend): |
| | ... def get(self, filepath): |
| | ... return filepath |
| | ... |
| | ... def get_text(self, filepath): |
| | ... return filepath |
| | """ |
| | if backend is not None: |
| | _register_backend(name, backend, force=force, prefixes=prefixes) |
| | return |
| |
|
| | def _register(backend_cls): |
| | _register_backend(name, backend_cls, force=force, prefixes=prefixes) |
| | return backend_cls |
| |
|
| | return _register |
| |
|
| |
|
| | register_backend('local', LocalBackend, prefixes='') |
| | register_backend('memcached', MemcachedBackend) |
| | register_backend('lmdb', LmdbBackend) |
| | |
| | |
| | register_backend('petrel', PetrelBackend, prefixes=['petrel', 's3']) |
| | register_backend('http', HTTPBackend, prefixes=['http', 'https']) |
| |
|