123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- # Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- #
- # Licensed under the Apache License, Version 2.0 (the "License"). You
- # may not use this file except in compliance with the License. A copy of
- # the License is located at
- #
- # http://aws.amazon.com/apache2.0/
- #
- # or in the "license" file accompanying this file. This file 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.
- import logging
- import boto3
- logger = logging.getLogger(__name__)
- class ResourceMeta(object):
- """
- An object containing metadata about a resource.
- """
- def __init__(self, service_name, identifiers=None, client=None,
- data=None, resource_model=None):
- #: (``string``) The service name, e.g. 's3'
- self.service_name = service_name
- if identifiers is None:
- identifiers = []
- #: (``list``) List of identifier names
- self.identifiers = identifiers
- #: (:py:class:`~botocore.client.BaseClient`) Low-level Botocore client
- self.client = client
- #: (``dict``) Loaded resource data attributes
- self.data = data
- # The resource model for that resource
- self.resource_model = resource_model
- def __repr__(self):
- return 'ResourceMeta(\'{0}\', identifiers={1})'.format(
- self.service_name, self.identifiers)
- def __eq__(self, other):
- # Two metas are equal if their components are all equal
- if other.__class__.__name__ != self.__class__.__name__:
- return False
- return self.__dict__ == other.__dict__
- def copy(self):
- """
- Create a copy of this metadata object.
- """
- params = self.__dict__.copy()
- service_name = params.pop('service_name')
- return ResourceMeta(service_name, **params)
- class ServiceResource(object):
- """
- A base class for resources.
- :type client: botocore.client
- :param client: A low-level Botocore client instance
- """
- meta = None
- """
- Stores metadata about this resource instance, such as the
- ``service_name``, the low-level ``client`` and any cached ``data``
- from when the instance was hydrated. For example::
- # Get a low-level client from a resource instance
- client = resource.meta.client
- response = client.operation(Param='foo')
- # Print the resource instance's service short name
- print(resource.meta.service_name)
- See :py:class:`ResourceMeta` for more information.
- """
- def __init__(self, *args, **kwargs):
- # Always work on a copy of meta, otherwise we would affect other
- # instances of the same subclass.
- self.meta = self.meta.copy()
- # Create a default client if none was passed
- if kwargs.get('client') is not None:
- self.meta.client = kwargs.get('client')
- else:
- self.meta.client = boto3.client(self.meta.service_name)
- # Allow setting identifiers as positional arguments in the order
- # in which they were defined in the ResourceJSON.
- for i, value in enumerate(args):
- setattr(self, '_' + self.meta.identifiers[i], value)
- # Allow setting identifiers via keyword arguments. Here we need
- # extra logic to ignore other keyword arguments like ``client``.
- for name, value in kwargs.items():
- if name == 'client':
- continue
- if name not in self.meta.identifiers:
- raise ValueError('Unknown keyword argument: {0}'.format(name))
- setattr(self, '_' + name, value)
- # Validate that all identifiers have been set.
- for identifier in self.meta.identifiers:
- if getattr(self, identifier) is None:
- raise ValueError(
- 'Required parameter {0} not set'.format(identifier))
- def __repr__(self):
- identifiers = []
- for identifier in self.meta.identifiers:
- identifiers.append('{0}={1}'.format(
- identifier, repr(getattr(self, identifier))))
- return "{0}({1})".format(
- self.__class__.__name__,
- ', '.join(identifiers),
- )
- def __eq__(self, other):
- # Should be instances of the same resource class
- if other.__class__.__name__ != self.__class__.__name__:
- return False
- # Each of the identifiers should have the same value in both
- # instances, e.g. two buckets need the same name to be equal.
- for identifier in self.meta.identifiers:
- if getattr(self, identifier) != getattr(other, identifier):
- return False
- return True
- def __hash__(self):
- identifiers = []
- for identifier in self.meta.identifiers:
- identifiers.append(getattr(self, identifier))
- return hash((self.__class__.__name__, tuple(identifiers)))
|