
    R
`                     l   d Z eZg dZddlZddlmZ ddlZddlZddl	Z	ddl
Z
ddlZddlZ	 ddlmZ 	 ddlmc mZ ddlmZmZ ddlmZmZ ddlmZ d	Zd
Z d Z!d Z"d Z# G d de$      Z% G d de%      Z& G d de%      Z' G d de(      Z) G d d      Z* G d de)      Z+ G d de+      Z, G d de)      Z- G d de)e*      Z. G d  d!e*      Z/ G d" d#e+e*      Z0 G d$ d%e)      Z1 G d& d'e)      Z2 G d( d)e+      Z3 G d* d+e)      Z4 G d, d-e)      Z5y# e$ r	 ddlmZ Y w xY w# e$ r ddlmc mZ Y w xY w).a  Navigate the resources exposed by a web service.

The wadllib library helps a web client navigate the resources
exposed by a web service. The service defines its resources in a
single WADL file. wadllib parses this file and gives access to the
resources defined inside. The client code can see the capabilities of
a given resource and make the corresponding HTTP requests.

If a request returns a representation of the resource, the client can
bind the string representation to the wadllib Resource object.
)
ApplicationLinkMethodNoBoundRepresentationError	ParameterRepresentationDefinitionResponseDefinitionResourceResourceType	WADLError    N)quote)	urlencode)URImerge)_make_unicode_string_types)iso_strptimez	xmlns:mapz http://www.w3.org/2001/XMLSchemac                     d| z   S )z)Scope a tag name with the WADL namespace.z&{http://research.sun.com/wadl/2006/10} tag_names    5/usr/lib/python3/dist-packages/wadllib/application.pywadl_tagr   H   s    3h>>    c                     dt        |       z   S )z#Turn a tag name into an XPath path.z./)r   r   s    r   
wadl_xpathr   M   s    (8$$$r   c                  @    i }| D ]  }||j                  |        |S )z<Merge any number of dictionaries, some of which may be None.)update)dictsfinaldicts      r   _merge_dictsr"   R   s/    E LL Lr   c                       e Zd ZdZy)r   zAAn exception having to do with the state of the WADL application.N__name__
__module____qualname____doc__r   r   r   r   r   [   s    Kr   r   c                       e Zd ZdZy)r   aA  An unbound resource was used where wadllib expected a bound resource.

    To obtain the value of a resource's parameter, you first must bind
    the resource to a representation. Otherwise the resource has no
    idea what the value is and doesn't even know if you've given it a
    parameter name that makes sense.
    Nr$   r   r   r   r   r   `   s    r   r   c                       e Zd ZdZy)UnsupportedMediaTypeErrorzA media type was given that's not supported in this context.

    A resource can only be bound to media types it has representations
    of.
    Nr$   r   r   r   r+   r+   j   s    r   r+   c                       e Zd ZdZy)WADLBasez?A base class for objects that contain WADL-derived information.Nr$   r   r   r   r-   r-   r   s    Ir   r-   c                   "    e Zd ZdZddZ	 ddZy)HasParametersMixinzAA mixin class for objects that have associated Parameter objects.Nc                    || j                   }|t        d      | j                  g S | j                  j                  t	        d            }|g S |D cg c]+  }|j
                  j                  d      |v rt        ||      - c}S c c}w )z6Find subsidiary parameters that have the given styles.z&Could not find any particular resourceparamstyle)resource
ValueErrortagfindallr   attribgetr   )selfstylesr3   
param_tags	param_tags        r   paramszHasParametersMixin.paramsy   s    }}HEFF88IXX%%j&9:
I!+<##''0F: (I. < 	< <s   0B	c                    t        ||      }i }|D ]  }|j                  }|j                  G||v r4||   |j                  k7  r"t        d||   d|d|j                  d      |j                  ||<   |j                  D cg c]  }|j
                   }	}t        |	      dkD  r2||v r.||   |	vr't        d||   d|ddj                  |	      d	      |r|j                  r||vrt        d
|z        ||v s||   ||<   ||=  t        |      dkD  r+t        ddj                  |j                               z        |S c c}w )a  Make sure the given valueset is valid.

        A valueset might be invalid because it contradicts a fixed
        value or (if enforce_completeness is True) because it lacks a
        required value.

        :param params: A list of Parameter objects.
        :param param_values: A dictionary of parameter values. May include
           paramters whose names are not valid Python identifiers.
        :param enforce_completeness: If True, this method will raise
           an exception when the given value set lacks a value for a
           required parameter.
        :param kw_param_values: A dictionary of parameter values.
        :return: A dictionary of validated parameter values.
        zValue 'z' for parameter 'z' conflicts with fixed value ''r   zInvalid value 'z': valid values are: "z", ""z$No value for required parameter '%s'zUnrecognized parameter(s): '%s'z', ')
r"   namefixed_valuer4   optionsvaluelenjoinis_requiredkeys)
r9   r=   param_valuesenforce_completenesskw_param_valuesvalidated_valuesr1   rA   optionrC   s
             r   validate_param_valuesz(HasParametersMixin.validate_param_values   s   " $L/B 	'E::D  ,L($T*e.?.??$(4T(:D(-(9(9&; < < &+%6%6T"27--@v||@G@Gq T\%9 &g5 $T*D&++g2F"H I I %):):, !G#'"( ) )|#)5d); & &-	'. |q >%{{<+<+<+>?@ A A! As   EN)T)r%   r&   r'   r(   r=   rN   r   r   r   r/   r/   v   s    K<  48- r   r/   c                   (    e Zd ZdZd Zd Zd Zd Zy)WADLResolvableDefinitionz=A base class for objects whose definitions may be references.c                      d| _         || _        y)zInitialize with a WADL application.

        :param application: A WADLDefinition. Relative links are
            assumed to be relative to this object's URL.
        N)_definitionapplication)r9   rT   s     r   __init__z!WADLResolvableDefinition.__init__   s      &r   c                     | j                   | j                   S | j                         }|	| | _         | S | j                  j                  |      }| j	                  |      }|t        d|z        || _         |S )a  Return the definition of this object, wherever it is.

        Resource is a good example. A WADL <resource> tag
        may contain a large number of nested tags describing a
        resource, or it may just contain a 'type' attribute that
        references a <resource_type> which contains those same
        tags. Resource.resolve_definition() will return the original
        Resource object in the first case, and a
        ResourceType object in the second case.
        No such XML ID: "%s")rS   _get_definition_urlrT   lookup_xml_id_definition_factoryKeyError)r9   
object_urlxml_id
definitions       r   resolve_definitionz+WADLResolvableDefinition.resolve_definition   s     '###--/
  $DK !!//
;--f5
 1J>??%r   c                     t               )zxTransform an XML ID into a wadllib wrapper object.

        Which kind of object it is depends on the subclass.
        NotImplementedErrorr9   ids     r   rZ   z,WADLResolvableDefinition._definition_factory       
 "##r   c                     t               )zmFind the URL that identifies an external reference.

        How to do this depends on the subclass.
        ra   r9   s    r   rX   z,WADLResolvableDefinition._get_definition_url   re   r   N)r%   r&   r'   r(   rU   r_   rZ   rX   r   r   r   rQ   rQ      s    G' D$$r   rQ   c                        e Zd ZdZ	 	 	 d fd	Zed        Zed        Zed        Z	 	 	 ddZ	d Z
	 	 ddZdd	Zdd
Zed        ZddZd Zd Zd Zd ZddZd Z xZS )r	   z/A resource, possibly bound to a representation.c                    t         t        |   |       || _        t	        |t
              r+| j                  j                  |      j                  | _        n|| _        d| _	        |A|dk(  r.|r$t        j                  t        |            | _	        n|| _	        nt        d|z        || _        |+||| _        y| j!                  | j                        | _        yy)a[  
        :param application: A WADLApplication.
        :param url: The URL to this resource.
        :param resource_type: An ElementTree <resource> or <resource_type> tag.
        :param representation: A string representation.
        :param media_type: The media type of the representation.
        :param representation_needs_processing: Set to False if the
            'representation' parameter should be used as
            is. Otherwise, it will be transformed from a string into
            an appropriate Python data structure, depending on its
            media type.
        :param representation_definition: A RepresentationDefinition
            object describing the structure of this
            representation. Used in cases when the representation
            isn't the result of sending a standard GET to the
            resource.
        Napplication/jsonz?This resource doesn't define a representation for media type %s)superr	   rU   _url
isinstancer   rT   get_resource_typer5   representationjsonloadsr   r+   
media_typerepresentation_definitionget_representation_definition)	r9   rT   urlresource_typero   rr   representation_needs_processingrs   	__class__s	           r   rU   zResource.__init__   s    * 	h&{3	m]3 ''99-HLLDH %DH"%//2*.**%n5+7D' +9D'/$&012 2 %%(41J. 66tG .	 &r   c                     | j                   S )z Return the URL to this resource.)rl   rg   s    r   ru   zResource.url,  s     yyr   c                 :   | j                   y| j                   j                  j                  d      }||S | j                   j                  j                  d      }|>t        | j                  j
                        j                         }t        |      dz   |z   S y)z@Return the URL to the type definition for this resource, if any.Ntyperd   #)r5   r7   r8   r   rT   
markup_urlensureSlashstr)r9   ru   type_idbases       r   type_urlzResource.type_url1  s     88hhoo!!&)?J((//%%d+t''223??ADt9s?W,, r   c                 4    | j                   j                  d   S )zReturn the ID of this resource.rd   )r5   r7   rg   s    r   rd   zResource.idC  s     xxt$$r   c           	      `    t        | j                  | j                  | j                  ||||      S )a  Bind the resource to a representation of that resource.

        :param representation: A string representation
        :param media_type: The media type of the representation.
        :param representation_needs_processing: Set to False if the
            'representation' parameter should be used as
            is.
        :param representation_definition: A RepresentationDefinition
            object describing the structure of this
            representation. Used in cases when the representation
            isn't the result of sending a standard GET to the
            resource.
        :return: A Resource bound to a particular representation.
        )r	   rT   ru   r5   )r9   ro   rr   rw   rs   s        r   bindzResource.bindH  s0    " (($((DHH&
713 	3r   c                     | j                  d      j                  }|D ]>  }|j                         j                  }|j                  j                  d      |k(  s<|c S  t        d|z        )z<Get a description of one of this resource's representations.GET	mediaTypez4No definition for representation with media type %s.)
get_methodresponser_   r5   r7   r8   r+   )r9   rr   default_get_responsero   representation_tags        r   rt   z&Resource.get_representation_definition^  sy    #u5>>2 	&N!/!B!B!D!H!H!((,,[9ZG%%	& ( )>@J)K L 	Lr   c                     | j                         D ]e  }|j                  j                  dd      j                         }|||j                         k(  sCt	        | |      }|j                  |||      sc|c S  y)a   Look up one of this resource's methods by HTTP method.

        :param http_method: The HTTP method used to invoke the desired
                            method. Case-insensitive and optional.

        :param media_type: The media type of the representation
                           accepted by the method. Optional.

        :param query_params: The names and values of any fixed query
                             parameters used to distinguish between
                             two methods that use the same HTTP
                             method. Optional.

        :param representation_params: The names and values of any
                             fixed representation parameters used to
                             distinguish between two methods that use
                             the same HTTP method and have the same
                             media type. Optional.

        :return: A MethodDefinition, or None if there's no definition
                  that fits the given constraints.
        rA    N)_method_tag_iterr7   r8   lowerr   is_described_by)r9   http_methodrr   query_paramsrepresentation_params
method_tagrA   methods           r   r   zResource.get_methodh  s    0 //1 	"J$$((4::<D"dk.?.?.A&Aj1))*l*?A!M	" r   c                 B    | j                  |      j                  |       S )a~  A list of this resource's parameters.

        :param media_type: Media type of the representation definition
            whose parameters are being named. Must be present unless
            this resource is bound to a representation.

        :raise NoBoundRepresentationError: If this resource is not
            bound to a representation and media_type was not provided.
        )_find_representation_definitionr=   r9   rr   s     r   
parameterszResource.parameters  s#     33t	%r   c                 B    | j                  |      j                  |       S )a  A list naming this resource's parameters.

        :param media_type: Media type of the representation definition
            whose parameters are being named. Must be present unless
            this resource is bound to a representation.

        :raise NoBoundRepresentationError: If this resource is not
            bound to a representation and media_type was not provided.
        )r   parameter_namesr   s     r   r   zResource.parameter_names  s$     33'-	.r   c              #   R   K   | j                         D ]  }t        | |        yw)z6An iterator over the methods defined on this resource.N)r   r   )r9   r   s     r   method_iterzResource.method_iter  s-      //1 	+Jz**	+s   %'c                     | j                  |      }|j                  }|j                  t        d            D ].  }|j                  j                  d      |k(  s"t        | |      c S  y)a  Find a parameter within a representation definition.

        :param param_name: Name of the parameter to find.

        :param media_type: Media type of the representation definition
            whose parameters are being named. Must be present unless
            this resource is bound to a representation.

        :raise NoBoundRepresentationError: If this resource is not
            bound to a representation and media_type was not provided.
        r1   rA   N)r   r5   r6   r   r7   r8   r   )r9   
param_namerr   r^   r   r<   s         r   get_parameterzResource.get_parameter  sh     99*E
'^^+33Jw4GH 	2I##F+z9 y11	2 r   c                 2   | j                   t        d      | j                  dk(  r|j                  dk7  rt	        d|j                  z        | j                   |j
                     }|D| j                  |j                  |j                        \  }}|t        k(  r|dv r	 t        |      }|S |S t	        d	| j                  z        # t        $ rF 	 t        j                  t        j                  |d      dd  }Y |S # t        $ r t        |      w xY ww xY w)
zFind the value of a parameter, given the Parameter object.

        :raise ValueError: If the parameter value can't be converted into
        its defined type.
        z,Resource is not bound to any representation.rj   plain8Don't know how to find value for a parameter of type %s.)dateTimedatez%Y-%m-%dr      zEPath traversal not implemented for a representation of media type %s.)ro   r   rr   r2   rb   rA   _dereference_namespacer5   r{   XML_SCHEMA_NS_URIr   r4   datetimetimestrptime)r9   	parameterrD   namespace_url	data_types        r   get_parameter_valuezResource.get_parameter_value  sE    &,>@ @??00 '))!*12 2 ''	7E +/+F+FMM9>>,3(y!%66!%994 ,U 3 L5L! #G$(OO#4 5 	5 & 	44$,$5$5"&--z"B1Q"G%JE L  * 4 #-U"33	4	4s    C 	D)C==DDc                     |d|v r|j                  dd      \  }}nd}|j                  t              }|j                  |d      }||fS )zSplits a value into namespace URI and value.

        :param tag: A tag to use as context when mapping namespace
        names to URIs.
        N:   r   )splitr8   NS_MAP)r9   r5   rD   	namespacens_mapr   s         r   r   zResource._dereference_namespace  sR     ${{32IuI

9d3e##r   c                 L    | j                   j                  j                  |      S )z-Given an ID, find a ResourceType for that ID.)rT   resource_typesr8   rc   s     r   rZ   zResource._definition_factory  s    ..22266r   c                 L    | j                   j                  j                  d      S )zReturn the URL that shows where a resource is 'really' defined.

        If a resource's capabilities are defined by reference, the
        <resource> tag's 'type' attribute will contain the URL to the
        <resource_type> that defines them.
        r{   r5   r7   r8   rg   s    r   rX   zResource._get_definition_url       xx""6**r   c                     | j                   *| j                  j                         }|j                         S |!| j                  |      }|j                         S t	        d      )a3  Get the most appropriate representation definition.

        If media_type is provided, the most appropriate definition is
        the definition of the representation of that media type.

        If this resource is bound to a representation, the most
        appropriate definition is the definition of that
        representation. Otherwise, the most appropriate definition is
        the definition of the representation served in response to a
        standard GET.

        :param media_type: Media type of the definition to find. Must
            be present unless the resource is bound to a
            representation.

        :raise NoBoundRepresentationError: If this resource is not
            bound to a representation and media_type was not provided.

        :return: A RepresentationDefinition
        zSResource is not bound to any representation, and no media media type was specified.)ro   rs   r_   rt   r   )r9   rr   r^   s      r   r   z(Resource._find_representation_definition  st    * * 77JJLJ ,,.. #;;JGJ
 ,,.. -,- -r   c              #      K   | j                         j                  }|j                  t        d            D ]  }|  yw)z+Iterate over this resource's <method> tags.r   N)r_   r5   r6   r   )r9   r^   r   s      r   r   zResource._method_tag_iter*  s?     ,,.22
$,,Z-AB 	J	s   ?A)NNTN)rj   TN)NNNNrO   )r%   r&   r'   r(   rU   propertyru   r   rd   r   rt   r   r   r   r   r   r   r   rZ   rX   r   r   __classcell__rx   s   @r   r	   r	      s    9 2615+/2Ih    " % % /A-1'+3,L JN)-B%. + +
&-5`$7+ /Fr   r	   c                   v    e Zd ZdZd Zed        Zed        Zed        Zed        Z	ddZ
	 	 dd	Z	 	 dd
Zy)r   z*A wrapper around an XML <method> tag.
    c                 V    || _         | j                   j                  | _        || _        y)zaInitialize with a <method> tag.

        :param method_tag: An ElementTree <method> tag.
        N)r3   rT   r5   )r9   r3   r   s      r   rU   zMethod.__init__4  s$    
 !==44r   c                 ^    t        | | j                  j                  t        d                  S )z@Return the definition of a request that invokes the WADL method.request)RequestDefinitionr5   findr   rg   s    r   r   zMethod.request=  s#     !txx}}Z	5J'KLLr   c                 r    t        | j                  | j                  j                  t	        d                  S )z9Return the definition of the response to the WADL method.r   )r   r3   r5   r   r   rg   s    r   r   zMethod.responseB  s.     "$--"&((--
:0F"GI 	Ir   c                 L    | j                   j                  j                  d      S )z)The XML ID of the WADL method definition.rd   r   rg   s    r   rd   z	Method.idH  s     xx""4((r   c                 h    | j                   j                  j                  d      j                         S )zThe name of the WADL method definition.

        This is also the name of the HTTP method (GET, POST, etc.)
        that should be used to invoke the WADL method.
        rA   r5   r7   r8   r   rg   s    r   rA   zMethod.nameM  s&     xx""6*0022r   Nc                 <     | j                   j                  |fi |S )4Return the request URL to use to invoke this method.)r   	build_url)r9   rI   rK   s      r   build_request_urlzMethod.build_request_urlV  s    %t||%%lFoFFr   c                 >     | j                   j                  ||fi |S )zBuild a representation to be sent when invoking this method.

        :return: A 2-tuple of (media_type, representation).
        )r   ro   )r9   rr   rI   rK   s       r   build_representationzMethod.build_representationZ  s*     +t||**9(79 	9r   c                    d}|| j                   j                  |      }|y|;t        |      dkD  r-| j                   }|y	 |j                  |j                  |d       |t        |      dk(  ry||j                  |      S | j                   j                  D ]0  }	 |j                  |j                  | j                        |d        y y# t
        $ r Y yw xY w# t
        $ r Y Nw xY w)a  Returns true if this method fits the given constraints.

        :param media_type: The method must accept this media type as a
                           representation.

        :param query_values: These key-value pairs must be acceptable
                           as values for this method's query
                           parameters. This need not be a complete set
                           of parameters acceptable to the method.

        :param representation_values: These key-value pairs must be
                           acceptable as values for this method's
                           representation parameters. Again, this need
                           not be a complete set of parameters
                           acceptable to the method.
        NFr   T)
r   rt   rE   rN   r   r4   r   representationsr=   r3   )r9   rr   query_valuesrepresentation_valuesro   r   s         r   r   zMethod.is_described_byc  s   $ !!\\GGN%#L(9A(=llG --((,? ")()Q.%!11%' '"ll:: 	N44"))$--8)52 	 '  "  s$   C ,C	CC	C)(C)rO   NN)NNN)r%   r&   r'   r(   rU   r   r   r   rd   rA   r   r   r   r   r   r   r   r   1  s     M M I I
 ) ) 3 3G /3*.9 =A.25r   r   c                   N    e Zd ZdZd Zed        Zed        Zd	dZd
dZ	d	dZ
y)r   zBA wrapper around the description of the request invoking a method.c                     || _         | j                   j                  | _        | j                  j                  | _        || _        y)zInitialize with a <request> tag.

        :param resource: The resource to which this request can be sent.
        :param request_tag: An ElementTree <request> tag.
        N)r   r3   rT   r5   )r9   r   request_tags      r   rU   zRequestDefinition.__init__  s5     ,,==44r   c                 &    | j                  dg      S )z,Return the query parameters for this method.query)r=   rg   s    r   r   zRequestDefinition.query_params  s     {{G9%%r   c              #      K   | j                   j                  t        d            D ]%  }t        | j                  | j
                  |       ' y w)Nro   )r5   r6   r   r   rT   r3   )r9   r^   s     r   r   z!RequestDefinition.representations  sH     ((**:6F+GH 	=J*  $--= =	=s   AANc                 P    | j                   D ]  }||j                  |k(  s|c S  y)z1Return the appropriate representation definition.N)r   rr   r9   rr   ro   s      r   rt   z/RequestDefinition.get_representation_definition  s5    "22 	&N!^%>%>*%L%%	& r   c                 j    | j                  |      }|t        d|z         |j                  |fi |S )zBuild a representation to be sent along with this request.

        :return: A 2-tuple of (media_type, representation).
        z,Cannot build representation of media type %s)rt   	TypeErrorr   )r9   rr   rI   rK   r^   s        r   ro   z RequestDefinition.representation  sH     77
C
J() * *z|???r   c                      | j                   | j                  |fi |}| j                  j                  }t	        |      dkD  r1d|v rd}nd}||t        t        |j                                     z   z  }|S )r   r   ?&)rN   r   r3   ru   rE   r   sorteditems)r9   rI   rK   rL   ru   appends         r   r   zRequestDefinition.build_url  s    5455|@/>@mm 1$cz6If-=-C-C-E&FGGGC
r   rO   r   )r%   r&   r'   r(   rU   r   r   r   rt   ro   r   r   r   r   r   r     sB    L	 & & = =

@r   r   c                   6    e Zd ZdZd	dZd Zd Zd Zd Zd Z	y)
r   z;A wrapper around the description of a response to a method.Nc                 P    |j                   | _         || _        || _        || _        y)zgInitialize with a <response> tag.

        :param response_tag: An ElementTree <response> tag.
        N)rT   r3   r5   headers)r9   r3   response_tagr   s       r   rU   zResponseDefinition.__init__  s'    
 $// r   c              #      K   t        d      }| j                  j                  |      D ]/  }t        | j                  j
                  | j                  |       1 yw)zGet an iterator over the representation definitions.

        These are the representations returned in response to an
        invocation of this method.
        ro   N)r   r5   r6   r   r3   rT   )r9   pathr   s      r   __iter__zResponseDefinition.__iter__  sY      *+"&(("2"24"8 	N*))4==:LN N	Ns   AAc                 D    t        | j                  | j                  |      S )zBind the response to a set of HTTP headers.

        A WADL response can have associated header parameters, but no
        other kind.
        )r   r3   r5   )r9   r   s     r   r   zResponseDefinition.bind  s     "$--7CCr   c                     | j                   j                  t        d            D ]M  }|j                  j	                  d      |k(  s"|j                  j	                  d      dk(  sAt        | |      c S  y)z,Find a header parameter within the response.r1   rA   r2   headerN)r5   r6   r   r7   r8   r   )r9   r   r<   s      r   r   z ResponseDefinition.get_parameter  si    ))*W*=> 	2I  $$V,
:$$((1X= y11	2 r   c                     | j                   t        d      |j                  dk7  rt        d|j                  z        | j                   j	                  |j
                        S )z:Find the value of a parameter, given the Parameter object.z,Response object is not bound to any headers.r   r   )r   r   r2   rb   r8   rA   )r9   r   s     r   r   z&ResponseDefinition.get_parameter_value  sc    <<,>@ @??h&%&__-. . ||	//r   c                 R    | j                   y| D ]  }|j                  |k(  s|c S  y)z8Get one of the possible representations of the response.N)r5   rr   r   s      r   rt   z0ResponseDefinition.get_representation_definition  s7    88" 	&N((J6%%	& r   rO   )
r%   r&   r'   r(   rU   r   r   r   r   rt   r   r   r   r   r     s%    E	ND	0r   r   c                   n     e Zd ZdZ fdZ fdZd Zed        Zd Z	d Z
ddZd	 Zd
 Zd Zd Z xZS )r   z2A definition of the structure of a representation.c                 H    t         t        |   |       || _        || _        y rO   )rk   r   rU   r3   r5   )r9   rT   r3   r   rx   s       r   rU   z!RepresentationDefinition.__init__  s!    &6{C %r   c                 0    t         t        |   ddg|      S )Nr   r   )rk   r   r=   )r9   r3   rx   s     r   r=   zRepresentationDefinition.params  s"    -t;g* 	*r   c                 ^    | j                  |      D cg c]  }|j                   c}S c c}w )z#Return the names of all parameters.)r=   rA   )r9   r3   r1   s      r   r   z(RepresentationDefinition.parameter_names"  s#    (,H(=>u

>>>s   *c                 P    | j                         j                  j                  d   S )z4The media type of the representation described here.r   )r_   r5   r7   rg   s    r   rr   z#RepresentationDefinition.media_type&  s$     &&(,,33K@@r   c                    t        t        t        j                  dz
              }d|z  }t	        j
                  t        j                        }d||z  z   dz   }||S |}d}	 dt        j                  |      z   dz   j                  d      }t        j                  ||t        j                  	      s	 |S |d
z   t        |      z   }|dz  }j)z;Make a random boundary that does not appear in `all_parts`.r   z%%0%ddz===============z==r   z^--z(--)?$ascii)flags.)rE   reprsysmaxsizerandom	randrangereescapeencodesearch	MULTILINEr   )	r9   	all_parts_width_fmttokenboundarybcounterpatterns	            r   _make_boundaryz'RepresentationDefinition._make_boundary+  s    T#++/*+&   -.5Oryy|+h6>>wGG99Wir||D  3W-AqLG r   c                     |D ]g  \  }}|j                  |j                  d             |j                  d       |j                  |j                  d             |j                  d       i |j                  d       y)z$Write MIME headers to a file object.UTF-8s   :    
Nwriter  )r9   bufr   keyrD   s        r   _write_headersz'RepresentationDefinition._write_headers=  se    ! 	JCIIcjj)*IIeIIell7+,IIg		
 			'r   c                     |j                  d       |j                  |j                  d             |r|j                  d       |j                  d       y)z,Write a multipart boundary to a file object.s   --r  r  Nr  )r9   r  r
  closings       r   _write_boundaryz(RepresentationDefinition._write_boundaryF  s>    		%		(//'*+IIe		'r   c                 6   g }|D ]Y  \  }}}t        j                         }|rd}dt        |      dt        |      d}nd}dt        |      z  }| j                  |dd|fd	|fg       |r9t	        |t
              st        d
t        |      z        |j                  |       nt	        |t              st        dt        |      z        t        j                  d|      }	|	dd D ]3  }
|j                  |
j                  d             |j                  d       5 |j                  |	d   j                  d             |j                  |j                                \ | j                  dj!                  |            }t        j                         }dt        |      z  }| j                  |dd|fg       |D ]6  }| j#                  ||       |j                  |       |j                  d       8 | j#                  ||d       ||j                         fS )aV  Generate a multipart/form-data message.

        This is very loosely based on the email module in the Python standard
        library.  However, that module doesn't really support directly embedding
        binary data in a form: various versions of Python have mangled line
        separators in different ways, and none of them get it quite right.
        Since we only need a tiny subset of MIME here, it's easier to implement
        it ourselves.

        :return: a tuple of two elements: the Content-Type of the message, and
            the entire encoded message as a byte string.
        zapplication/octet-streamzform-data; name="z"; filename="r@   ztext/plain; charset="utf-8"zform-data; name="%s")zMIME-Versionz1.0zContent-TypezContent-Dispositionzbytes payload expected: %szstring payload expected: %sz
\r\n|\r|\nNr  r  z"multipart/form-data; boundary="%s"T)r  )ioBytesIOr   r  rm   bytesr   r{   r  r   r  r   r  r   getvaluer  rF   r  )r9   partsencoded_parts	is_binaryrA   rD   r  ctypecdisplinesliner
  encoded_parts                r   _generate_multipart_formz1RepresentationDefinition._generate_multipart_formN  s	    &+ 	1"ItU**,C2
 $Kt. 6.t<''&.& 
 !%/#$@4;$NOO		% !%7#5UCE E6!#2J 'DIIdkk'23IIg&' 		%)**734  0=	1B &&w||M'BC jjl4uXFC#U#" 	 * 	L  h/IIl#IIg	 	S(D9clln$$r   c                 >   | j                         }|j                  | j                        } | j                  ||fi |}| j                  }|dk(  r&t        t        |j                                     }||fS |dk(  rwg }t               }	|D ]N  }
|j                  |
j                  |	      }||	us$|j                  |
j                  dk(  |
j                  |f       P | j                  |      \  }}||fS |dk(  rt        j                  |      }||fS t!        d|z        )zzBind the definition to parameter values, creating a document.

        :return: A 2-tuple (media_type, document).
        z!application/x-www-form-urlencodedzmultipart/form-databinaryrj   zUnsupported media type: '%s')r_   r=   r3   rN   rr   r   r   r   objectr8   rA   r   r{   r(  rp   dumpsr4   )r9   rI   rK   r^   r=   rL   rr   docr   missingr1   rD   s               r   r   zRepresentationDefinition.bind  s>   
 ,,.
""4==15455L5$35__
<<F#3#9#9#;<=C 3 00EhG N(,,UZZA'LL%**"8%**e!LMN #;;EBOJ
 3	 --**-.C 3 ;jHIIr   c                 L    | j                   j                  j                  |      S )z9Turn a representation ID into a RepresentationDefinition.)rT   representation_definitionsr8   rc   s     r   rZ   z,RepresentationDefinition._definition_factory  s    ::>>rBBr   c                 L    | j                   j                  j                  d      S )a  Find the URL containing the representation's 'real' definition.

        If a representation's structure is defined by reference, the
        <representation> tag's 'href' attribute will contain the URL
        to the <representation> that defines the structure.
        hrefr   rg   s    r   rX   z,RepresentationDefinition._get_definition_url  r   r   )F)r%   r&   r'   r(   rU   r=   r   r   rr   r  r  r  r(  r   rZ   rX   r   r   s   @r   r   r     sP    <&
*? A A$?%B4C+r   r   c                       e Zd ZdZd Zed        Zed        Zed        Zed        Z	ed        Z
d Zed	        Zed
        Zed        Zy)r   z5One of the parameters of a representation definition.c                 B    |j                   | _         || _        || _        y)a  Initialize with respect to a value container.

        :param value_container: Usually the resource whose representation
            has this parameter. If the resource is bound to a representation,
            you'll be able to find the value of this parameter in the
            representation. This may also be a server response whose headers
            define a value for this parameter.
        :tag: The ElementTree <param> tag for this parameter.
        N)rT   value_containerr5   )r9   r5  r5   s      r   rU   zParameter.__init__  s!     +66.r   c                 L    | j                   j                  j                  d      S )zThe name of this parameter.rA   r   rg   s    r   rA   zParameter.name       xx""6**r   c                 L    | j                   j                  j                  d      S )zThe style of this parameter.r2   r   rg   s    r   r2   zParameter.style  s     xx""7++r   c                 L    | j                   j                  j                  d      S )zThe XSD type of this parameter.r{   r   rg   s    r   r{   zParameter.type  r7  r   c                 L    | j                   j                  j                  d      S )a9  The value to which this parameter is fixed, if any.

        A fixed parameter must be present in invocations of a WADL
        method, and it must have a particular value. This is commonly
        used to designate one parameter as containing the name of the
        server-side operation to be invoked.
        fixedr   rg   s    r   rB   zParameter.fixed_value  s     xx""7++r   c                 n    | j                   j                  j                  dd      j                         dv S )z6Whether or not a value for this parameter is required.requiredfalse)1truer   rg   s    r   rG   zParameter.is_required  s2     ##J8>>@ ! 	"r   c                 8    | j                   j                  |       S )zThe value of this parameter in the bound representation/headers.

        :raise NoBoundRepresentationError: If this parameter's value
               container is not bound to a representation or a set of
               headers.
        )r5  r   rg   s    r   	get_valuezParameter.get_value  s     ##77==r   c                     | j                   j                  t        d            D cg c]  }t        | |       c}S c c}w )z7Return the set of acceptable values for this parameter.rM   )r5   r6   r   Option)r9   
option_tags     r   rC   zParameter.options  sC     $(88#3#3Jx4H#IK tZ( K 	K Ks   =c                 h    | j                   j                  t        d            }|yt        | |      S )zGet the link to another resource.

        The link may be examined and, if its type is of a known WADL
        description, it may be followed.

        :return: A Link object, or None.
        linkN)r5   r   r   r   )r9   link_tags     r   rG  zParameter.link  s1     88==F!34D(##r   c                 L    | j                   }|t        d      |j                  S )a  Follow a link from this parameter to a new resource.

        This only works for parameters whose WADL definition includes a
        <link> tag that points to a known WADL description.

        :return: A Resource object for the resource at the other end
        of the link.
        z(This parameter isn't a link to anything.)rG  r4   follow)r9   rG  s     r   linked_resourcezParameter.linked_resource  s(     yy<GHH{{r   N)r%   r&   r'   r(   rU   r   rA   r2   r{   rB   rG   rB  rC   rG  rK  r   r   r   r   r     s    ? + + , , + + , , " "
> K K
 $ $  r   r   c                   &    e Zd ZdZd Zed        Zy)rD  z0One of a set of possible values for a parameter.c                      || _         || _        y)z}Initialize the option.

        :param parameter: A Parameter.
        :param link_tag: An ElementTree <option> tag.
        N)r   r5   )r9   r   rE  s      r   rU   zOption.__init__  s     #r   c                 L    | j                   j                  j                  d      S )NrD   r   rg   s    r   rD   zOption.value   s    xx""7++r   N)r%   r&   r'   r(   rU   r   rD   r   r   r   rD  rD    s    : , ,r   rD  c                   N     e Zd ZdZ fdZed        Zed        Zd Zd Z	 xZ
S )r   zA link from one resource to another.

    Calling resolve_definition() on a Link will give you a Resource for the
    type of resource linked to. An alias for this is 'follow'.
    c                 \    t         t        |   |j                         || _        || _        y)zyInitialize the link.

        :param parameter: A Parameter.
        :param link_tag: An ElementTree <link> tag.
        N)rk   r   rU   rT   r   r5   )r9   r   rH  rx   s      r   rU   zLink.__init__,  s(     	dD"9#8#89"r   c                 P    | j                   st        d      | j                         S )z$Follow the link to another Resource.zfCannot follow a link when the target has no WADL description. Try using a general HTTP client instead.)
can_followr   r_   rg   s    r   rJ  zLink.follow6  s.      . / / &&((r   c                 D    	 | j                         }y# t        $ r Y yw xY w)zCan this link be followed within wadllib?

        wadllib can follow a link if it points to a resource that has
        a WADL definition.
        FT)rX   r   )r9   definition_urls     r   rR  zLink.can_follow?  s.    	!557N   		s    	c                     t        | j                  | j                  j                         | j                  j                  j                  |      j                        S )z,Turn a resource type ID into a ResourceType.)r	   rT   r   rB  r   r8   r5   rc   s     r   rZ   zLink._definition_factoryL  sG    dnn668++//3779 	9r   c                 j    | j                   j                  j                  d      }|t        d      |S )z(Find the URL containing the definition .rv   zIParameter is a link, but not to a resource with a known WADL description.)r5   r7   r8   r   )r9   r{   s     r   rX   zLink._get_definition_urlR  s6    xx""?3< = > >r   )r%   r&   r'   r(   rU   r   rJ  rR  rZ   rX   r   r   s   @r   r   r   %  s?     ) ) 
 
9r   r   c                       e Zd ZdZd Zy)r
   z,A wrapper around an XML <resource_type> tag.c                     || _         y)zvInitialize with a <resource_type> tag.

        :param resource_type_tag: An ElementTree <resource_type> tag.
        N)r5   )r9   resource_type_tags     r   rU   zResourceType.__init__^  s    
 %r   N)r%   r&   r'   r(   rU   r   r   r   r
   r
   [  s
    6%r   r
   c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	r   z1A WADL document made programmatically accessible.c                    || _         t        |d      r| j                  |      | _        n| j	                  |      | _        | j                  j                  t        d            | _        | j                  j                  j                  d      | _
        i | _        i | _        | j                  j                  t        d            D ]<  }|j                  j                  d      }|!t        | d|      }|| j                  |<   > | j                  j                  t        d            D ])  }|j                  d   }t        |      | j                  |<   + y)zParse WADL and find the most important parts of the document.

        :param markup_url: The URL from which this document was obtained.
        :param markup: The WADL markup itself, or an open filehandle to it.
        read	resourcesr   ro   rd   Nrv   )r}   hasattr_from_streamr-  _from_stringr   r   r]  r7   r8   resource_baser0  r   r6   r   r
   )r9   r}   markupro   rd   r^   rv   s          r   rU   zApplication.__init__i  s-    %66"((0DH((0DHz+'>?!^^2266v>*,' "hh..z:J/KL 	AN&&**40B~5$0
6@//3	A "XX--j.IJ 	BM%%d+B&2=&AD#	Br   c                     d}d}g }t        j                  ||      D ][  \  }}|dk(  r|j                  |       |dk(  r|j                          3|dk(  s9||}|j	                  t
        t        |             ] t        j                  |      S )zrTurns markup into a document.

        Just a wrapper around ElementTree which keeps track of namespaces.
        )startstart-nsend-nsNre  rf  rd  )ET	iterparser   popsetr   r!   ElementTree)r9   streameventsrootr   eventelems          r   r_  zApplication._from_stream  s    
 /<<7 	/KE4
"d#("

'!<Df.	/ ~~d##r   c                     t        |t              s|j                  d      }| j                  t	        j
                  |            S )zTurns markup into a document.r  )rm   r  r  r_  r  r  )r9   rb  s     r   r`  zApplication._from_string  s4    &%(]]7+F  F!344r   c                 ~    | j                  |      }| j                  j                  |      }|t        d|z        |S )z7Retrieve a resource type by the URL of its description.rW   )rY   r   r8   r[   )r9   resource_type_urlr]   rv   s       r   rn   zApplication.get_resource_type  sG    ##$56++//7 14EEFFr   c                    t        | j                        j                         }d|_        |j	                  d      rt        |      j                         }n|j                  |      }|j                  }d|_        ||k(  r|S t        d|z        )zA helper method for locating a part of a WADL document.

        :param url: The URL (with anchor) of the desired part of the
        WADL document.
        :return: The XML ID corresponding to the anchor.
        Nhttpz,Can't look up definition in another url (%s))r   r}   ensureNoSlashfragment
startswithresolverb   )r9   ru   
markup_urithis_uripossible_xml_ids        r   rY   zApplication.lookup_xml_id  s     )779
"
>>&!3x--/H "))#.H"++ z! #" " #-/2#3 4 	4r   c                    | j                   D cg c]  }|j                  d   |k(  r| }}t        |      dk  ryt        |      dkD  rt        d|z        t	        | t        | j                  |d      |d         S c c}w )zpLocate one of the resources described by this document.

        :param path: The path to the resource.
        r   r   Nz+More than one resource defined with path %sTr   )r]  r7   rE   r   r	   r   ra  )r9   r   r3   matchings       r   get_resource_by_pathz Application.get_resource_by_path  s     .2^^ 8v.$6  8 8x=1x=1I"# $ $%**D$7!F 	F8s   A<N)
r%   r&   r'   r(   rU   r_  r`  rn   rY   r  r   r   r   r   r   f  s&    ;B2$(54@Fr   r   )6r(   r{   __metaclass____all__r   email.utilsr   r  rp   r   r  r   r   urllib.parser   ImportErrorurllibxml.etree.cElementTreeetreecElementTreerg  xml.etree.ElementTreerk  lazr.urir   r   wadllibr   r   wadllib.iso_strptimer   r   r   r   r   r"   	Exceptionr   r   r+   r+  r-   r/   rQ   r	   r   r   r   r   r   rD  r   r
   r   r   r   r   <module>r     sx  "
    	   	 
 !&'''   .	6 ?
%
		 	
 	 Jv J?  ? D:$x :$zy' yx	gX gT6"4 6r?+ ?D^+79K ^+B[ [z,X ,"3# 3l%8 %nF( nFa!  ! !  '&&'s"   D 	D" DD"D32D3