# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Storage APIs. """ import threading class StorageAPI(object): """ Base class for storage APIs. """ def create(self, **kwargs): """ Create a storage API. :param kwargs: :return: """ raise NotImplementedError('Subclass must implement abstract create method') class ModelAPI(StorageAPI): """ Base class for model APIs ("MAPI"). """ def __init__(self, model_cls, name=None, **kwargs): """ :param model_cls: representing class of the model :param name: name of the model """ super(ModelAPI, self).__init__(**kwargs) self._model_cls = model_cls self._name = name or model_cls.__modelname__ self._thread_local = threading.local() self._thread_local._instrumentation = [] @property def _instrumentation(self): if not hasattr(self._thread_local, '_instrumentation'): self._thread_local._instrumentation = [] return self._thread_local._instrumentation @property def name(self): """ Name of the class. :type: :obj:`basestring` """ return self._name @property def model_cls(self): """ Class representing the model :type: :obj:`Type` """ return self._model_cls def get(self, entry_id, filters=None, **kwargs): """ Gets a model from storage. :param entry_id: """ raise NotImplementedError('Subclass must implement abstract get method') def put(self, entry, **kwargs): """ Puts a model in storage. :param entry: """ raise NotImplementedError('Subclass must implement abstract store method') def delete(self, entry_id, **kwargs): """ Deletes a model from storage. :param entry_id: """ raise NotImplementedError('Subclass must implement abstract delete method') def __iter__(self): return self.iter() def iter(self, **kwargs): """ Iterate over all models in storage. """ raise NotImplementedError('Subclass must implement abstract iter method') def update(self, entry, **kwargs): """ Update a model in storage. :param entry: :param kwargs: """ raise NotImplementedError('Subclass must implement abstract update method') class ResourceAPI(StorageAPI): """ Base class for resource APIs ("RAPI"). """ def __init__(self, name, **kwargs): """ :param name: resource type """ super(ResourceAPI, self).__init__(**kwargs) self._name = name @property def name(self): """ Name of resource. :type: :obj:`basestring` """ return self._name def read(self, entry_id, path, **kwargs): """ Get a bytesteam for a resource from storage. :param entry_id: :param path: """ raise NotImplementedError('Subclass must implement abstract read method') def delete(self, entry_id, path, **kwargs): """ Delete a resource from storage. :param entry_id: :param path: """ raise NotImplementedError('Subclass must implement abstract delete method') def download(self, entry_id, destination, path=None, **kwargs): """ Download a resource from storage. :param entry_id: :param destination: :param path: """ raise NotImplementedError('Subclass must implement abstract download method') def upload(self, entry_id, source, path=None, **kwargs): """ Upload a resource to storage. :param entry_id: :param source: :param path: """ raise NotImplementedError('Subclass must implement abstract upload method') def generate_lower_name(model_cls): """ Generates the name of the class from the class object, e.g. ``SomeClass`` -> ``some_class`` :param model_cls: class to evaluate :return: lowercase name :rtype: basestring """ return getattr(model_cls, '__mapiname__', model_cls.__tablename__)