B \W@sddlZddlmZddlmZddlmZddlmZmZddl m Z ddl m Z dd l mZmZd d lmZd d lmZeeZGd ddeZdS)N)partial) ServiceAction) WaiterAction) ResourceMetaServiceResource)CollectionFactory) ResourceModel)build_identifiersResourceHandler)ResourceLoadException) docstringc@seZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZddZddZddZd d!Zd&d#d$Zd%S)'ResourceFactoryaW A factory to create new :py:class:`~boto3.resources.base.ServiceResource` classes from a :py:class:`~boto3.resources.model.ResourceModel`. There are two types of lookups that can be done: one on the service itself (e.g. an SQS resource) and another on models contained within the service (e.g. an SQS Queue resource). cCst|_||_dS)N)r_collection_factory_emitter)selfZemitterr8/tmp/pip-build-uw_ogi45/boto3/boto3/resources/factory.py__init__&szResourceFactory.__init__c Cs td|j|t|||j}d}|jr6|j|j}||t |j|d}d|i}|j ||||d|j ||||d|j |||||d|j |||d|j||||d|j||||d|}|j|krd }|jd |}tg} |jdk r |jjd ||| |d tt|t| |S) a{ Loads a resource from a model, creating a new :py:class:`~boto3.resources.base.ServiceResource` subclass with the correct properties and methods, named based on the service and resource name, e.g. EC2.Instance. :type resource_name: string :param resource_name: Name of the resource to look up. For services, this should match the ``service_name``. :type single_resource_json_definition: dict :param single_resource_json_definition: The loaded json of a single service resource or resource definition. :type service_context: :py:class:`~boto3.utils.ServiceContext` :param service_context: Context about the AWS service :rtype: Subclass of :py:class:`~boto3.resources.base.ServiceResource` :return: The service or resource class. z Loading %s:%sN)resource_modelmeta)attrsr resource_namer)rrrservice_context)rrrrr)rrrr.zcreating-resource-class.%s)Zclass_attributes base_classesr)loggerdebug service_namer resource_json_definitionsshape service_model shape_forZload_rename_mapr_load_identifiers _load_actions_load_attributes_load_collections_load_has_relations _load_waitersrremittypestrtuple) rrsingle_resource_json_definitionrrr!rrZcls_namerrrrload_from_definition*sV        z$ResourceFactory.load_from_definitioncCs4x.|jD]$}|j|j|||||j<qWdS)z Populate required identifiers. These are arguments without which the resource cannot be used. Identifiers become arguments for operations on the resource. N) identifiersappendname_create_identifier)rrrrr identifierrrrr$s z!ResourceFactory._load_identifierscCsT|jr*|j|j||dd|d<|d|d<x$|jD]}|j|||d||j<q2WdS)z Actions on the resource become methods, with the ``load`` method being a special case which sets internal data for attributes, and ``reload`` is an alias for ``load``. T) action_modelrris_loadloadreload)r5rrN)r7_create_actionZactionsr2)rrrrractionrrrr%s  zResourceFactory._load_actionsc Cs|js dS|j|j}tdd|jD}||}xT|D]H\} \} } | |krl|j||| | |d} n|j|| | | |d} | || <q@WdS)a Load resource attributes based on the resource shape. The shape name is referenced in the resource JSON, but the shape itself is defined in the Botocore service JSON, hence the need for access to the ``service_model``. Ncss|]}|jr|j|fVqdS)N) member_name).0irrr sz3ResourceFactory._load_attributes..)rr4 member_modelr)rr2 snake_casedr?r) r!r"r#dictr0Zget_attributesitems_create_identifier_alias_create_autoload_property) rrrrrrr!r0 attributesr2Z orig_namememberproprrrr&s*   z ResourceFactory._load_attributescCs,x&|jD]}|j|j||d||j<qWdS)a Load resource collections from the model. Each collection becomes a :py:class:`~boto3.resources.collection.CollectionManager` instance on the resource instance, which allows you to iterate and filter through the collection's items. )rcollection_modelrN) collections_create_collectionr2)rrrrrHrrrr's  z!ResourceFactory._load_collectionscCs^x$|jD]}|j|||d||j<qWx$|jD]}|j|||d||j<q.W|||jdS)a Load related resources, which are defined via a ``has`` relationship but conceptually come in two forms: 1. A reference, which is a related resource instance and can be ``None``, such as an EC2 instance's ``vpc``. 2. A subresource, which is a resource constructor that will always return a resource instance which shares identifiers/data with this resource, such as ``s3.Bucket('name').Object('key')``. )reference_modelrr)subresource_modelrrN)Z references_create_referencer2 subresources_create_class_partial&_create_available_subresources_command)rrrrr reference subresourcerrrr(s  z#ResourceFactory._load_has_relationscs.dd|Dtfdd}||d<dS)NcSsg|] }|jqSr)r2)r<rRrrr szJResourceFactory._create_available_subresources_command..csS)z Returns a list of all the available sub-resources for this Resource. :returns: A list containing the name of each sub-resource for this resource :rtype: list of str r) factory_self) _subresourcesrrget_available_subresourcess zZResourceFactory._create_available_subresources_command..get_available_subresourcesrV)sorted)rrrNrVr)rUrrPs z6ResourceFactory._create_available_subresources_commandcCs*x$|jD]}|j|||d||j<qWdS)z Load resource waiters from the model. Each waiter allows you to wait until a resource reaches a specific state by polling the state of the resource. )resource_waiter_modelrrN)waiters_create_waiterr2)rrrrrwaiterrrrr)s  zResourceFactory._load_waiterscs2fdd}tj|_tj|dd|_t|S)zI Creates a read-only property for identifier attributes. cst|djdS)N_)getattrr2)r)r4rrget_identifier sz:ResourceFactory._create_identifier..get_identifierF)rZidentifier_modelinclude_signature)r,r2__name__rZIdentifierDocstring__doc__property)rTr4rr^r)r4rr3s  z"ResourceFactory._create_identifiercs>fdd}tj|_tj|j|j|j|dd|_t|S)zJ Creates a read-only property that aliases an identifier. cst|djdS)Nr\)r]r2)r)r4rrr^7sz@ResourceFactory._create_identifier_alias..get_identifierF)rr attr_name event_emitter attr_modelr_) r,r;r`rAttributeDocstringrrrarb)rTrr4r?rr^r)r4rrC2s   z(ResourceFactory._create_identifier_aliascs:fdd}t||_tj|j|||j|dd|_t|S)z Creates a new property on the resource to lazy-load its value via the resource's ``load`` method (if it exists). cs@|jjdkr2t|dr |ntd|jj|jjS)Nr7z{0} has no load method) rdatahasattrr7r format __class__r`get)r)r2rrproperty_loaderPs    zBResourceFactory._create_autoload_property..property_loaderF)rrrcrdrer_)r,r`rrfrrrarb)rTrr2r@r?rrlr)r2rrDFs  z)ResourceFactory._create_autoload_propertycsHt||jdfdd}t|j|_tj||j|j||jdd|_ |S)zx Creates a new wait method for each resource where both a waiter and resource model is defined. )Zwaiter_resource_namecs|f||dS)Nr)rargskwargs)r[rr do_waiterpsz1ResourceFactory._create_waiter..do_waiterF)rrdr"rXservice_waiter_modelr_) rr2r,r`rZResourceWaiterDocstringrr"rpra)rTrXrrror)r[rrZgs    zResourceFactory._create_waitercsLjj|jdfdd}tj|_tjdd|_t |S)zS Creates a new property on the resource to lazy-load a collection. )rrHrrdcs|dS)N)rHparentfactoryrr)r)clsrHrTrrrget_collectionsz:ResourceFactory._create_collection..get_collectionF)rHr_) rr/rr,r2r`rZCollectionDocstringrarb)rTrrHrrtr)rsrHrTrrrJ~s   z"ResourceFactory._create_collectioncs^t|jj||j|dtdd|jjDfdd}t|j|_tj |dd|_ t |S)zR Creates a new property on the resource to lazy-load a reference. ) search_pathrrrrcss|]}|jdkVqdS)rgN)source)r<r=rrrr>sz4ResourceFactory._create_reference..cs2r"|jjdkr"t|dr"||i|jjS)Nr7)rrgrhr7)r)handler needs_datarr get_referencesz8ResourceFactory._create_reference..get_referenceF)rKr_) r resourcepathanyr0r,r2r`rZReferenceDocstringrarb)rTrKrrryr)rwrxrrMs  z!ResourceFactory._create_referencecs>jjfdd}t|_tj|jdd|_|S)z Creates a new method which acts as a functools.partial, passing along the instance's low-level `client` to the new resource class' constructor. c srg}ji}j|d}jj}|dk rTx t||D]\}}||q>Wt|f|d|jj i||S)N)rr.rclient) r rkr/rzr0r r1rrr}) rrmrnZpositional_argsZjson_defZ resource_clsr0r4value)rTr2rrLrrcreate_resources z>ResourceFactory._create_class_partial..create_resourceF)rZsub_resource_modelr"r_)rzr+r,r`rZSubResourceDocstringr"ra)rTrLrrrr)rTr2rrLrrOs  z%ResourceFactory._create_class_partialFcsvt|||d|r<fdd}tj|j||j||jdd}n$fdd}tj||j||jdd}t|j|_||_ |S)zc Creates a new method which makes a request to the underlying AWS service. )rrrcs|f||}||j_dS)N)rrg)rrmrnresponse)r:rr do_actionsz1ResourceFactory._create_action..do_actionF)Z action_namerrdZ load_modelr"r_cs&|f||}t|dr"d|j_|S)Nr7)rhrrg)rrmrnr)r:rrrs )rrdr5r"r_) rrZLoadReloadDocstringr2rr"ZActionDocstringr,r`ra)rTr5rrr6rZlazy_docstringr)r:rr9s,     zResourceFactory._create_actionN)F)r` __module__ __qualname__rarr/r$r%r&r'r(rPr)r3rCrDrZrJrMrOr9rrrrrs$c #"!'-r)logging functoolsrr:rrbaserrZ collectionrmodelr rr r exceptionsr Zdocsr getLoggerr`robjectrrrrrs