3
1R[                 @   s  d Z eZddddddddd	d
g
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yddlmZ W n  ek
r   ddlmZ Y nX ddljj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d Zdd Z dd Z!G dd
 d
e"Z#G dd de#Z$G dd de#Z%G dd de&Z'G d d! d!Z(G d"d# d#e'Z)G d$d de)Z*G d%d de'Z+G d&d' d'e'e(Z,G d(d de(Z-G d)d de)e(Z.G d*d de'Z/G d+d, d,e'Z0G d-d de)Z1G d.d	 d	e'Z2G d/d de'Z3dS )0a  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             C   s   d|  S )z)Scope a tag name with the WADL namespace.z&{http://research.sun.com/wadl/2006/10} )tag_namer   r   5/usr/lib/python3/dist-packages/wadllib/application.pywadl_tagE   s    r   c             C   s   dt |  S )z#Turn a tag name into an XPath path.z./)r   )r   r   r   r   
wadl_xpathJ   s    r   c              G   s(   i }x| D ]}|dk	r
|j | q
W |S )z<Merge any number of dictionaries, some of which may be None.N)update)Zdictsfinaldictr   r   r   _merge_dictsO   s
    
r   c               @   s   e Zd ZdZdS )r
   zAAn exception having to do with the state of the WADL application.N)__name__
__module____qualname____doc__r   r   r   r   r
   X   s   c               @   s   e Zd ZdZdS )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.
    N)r   r   r   r   r   r   r   r   r   ]   s   c               @   s   e Zd ZdZdS )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.
    N)r   r   r   r   r   r   r   r   r    g   s   r    c               @   s   e Zd ZdZdS )WADLBasez?A base class for objects that contain WADL-derived information.N)r   r   r   r   r   r   r   r   r!   o   s   r!   c               @   s$   e Zd ZdZdddZd	ddZdS )
HasParametersMixinzAA mixin class for objects that have associated Parameter objects.Nc                s\    dkr| j   dkrtd| jdkr,g S | jjtd}|dkrHg S  fdd|D S )z6Find subsidiary parameters that have the given styles.Nz&Could not find any particular resourceparamc                s&   g | ]}|j jd krt |qS )style)attribgetr   ).0	param_tag)resourcestylesr   r   
<listcomp>   s   z-HasParametersMixin.params.<locals>.<listcomp>)r)   
ValueErrortagfindallr   )selfr*   r)   Z
param_tagsr   )r)   r*   r   paramsv   s    
zHasParametersMixin.paramsTc       	      K   s  t ||}i }x|D ]}|j}|jdk	r`||krV|| |jkrVtd|| ||jf |j||< dd |jD }t|dkr||kr|| |krtd|| |dj|f |r|jr||krtd| ||kr|| ||< ||= qW t|dkrtd	d
j|j  |S )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.
        Nz=Value '%s' for parameter '%s' conflicts with fixed value '%s'c             S   s   g | ]
}|j qS r   )value)r'   optionr   r   r   r+      s    z<HasParametersMixin.validate_param_values.<locals>.<listcomp>r   z=Invalid value '%s' for parameter '%s': valid values are: "%s"z", "z$No value for required parameter '%s'zUnrecognized parameter(s): '%s'z', ')	r   namefixed_valuer,   optionslenjoinis_requiredkeys)	r/   r0   param_valuesZenforce_completenesskw_param_valuesvalidated_valuesr#   r3   r5   r   r   r   validate_param_values   s6    





z(HasParametersMixin.validate_param_values)N)T)r   r   r   r   r0   r=   r   r   r   r   r"   s   s   
r"   c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )WADLResolvableDefinitionz=A base class for objects whose definitions may be references.c             C   s   d| _ || _dS )zInitialize with a WADL application.

        :param application: A WADLDefinition. Relative links are
            assumed to be relative to this object's URL.
        N)_definitionapplication)r/   r@   r   r   r   __init__   s    z!WADLResolvableDefinition.__init__c             C   s^   | j dk	r| j S | j }|dkr*| | _ | S | jj|}| j|}|dkrTtd| || _ |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.
        NzNo such XML ID: "%s")r?   _get_definition_urlr@   lookup_xml_id_definition_factoryKeyError)r/   Z
object_urlxml_id
definitionr   r   r   resolve_definition   s    

z+WADLResolvableDefinition.resolve_definitionc             C   s
   t  dS )zxTransform an XML ID into a wadllib wrapper object.

        Which kind of object it is depends on the subclass.
        N)NotImplementedError)r/   idr   r   r   rD      s    z,WADLResolvableDefinition._definition_factoryc             C   s
   t  dS )zmFind the URL that identifies an external reference.

        How to do this depends on the subclass.
        N)rI   )r/   r   r   r   rB      s    z,WADLResolvableDefinition._get_definition_urlN)r   r   r   r   rA   rH   rD   rB   r   r   r   r   r>      s
   	"r>   c                   s   e Zd ZdZd' fdd	Zedd Zedd	 Zed
d Zd(ddZ	dd Z
d)ddZd*ddZd+ddZedd Zd,ddZdd Zdd Zdd  Zd!d" Zd-d#d$Zd%d& Z  ZS ).r   z/A resource, possibly bound to a representation.NTc                s   t t| j| || _t|tr2| jj|j| _n|| _d| _	|dk	rx|dkrl|rdt
jt|| _	qx|| _	ntd| || _|dk	r|dk	r|| _n| j| j| _dS )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.
        Nzapplication/jsonz?This resource doesn't define a representation for media type %s)superr   rA   _url
isinstancer   r@   get_resource_typer-   representationjsonloadsr   r    
media_typerepresentation_definitionget_representation_definition)r/   r@   urlresource_typerO   rR   representation_needs_processingrS   )	__class__r   r   rA      s(    
zResource.__init__c             C   s   | j S )z Return the URL to this resource.)rL   )r/   r   r   r   rU   )  s    zResource.urlc             C   sb   | j dkrdS | j jjd}|dk	r(|S | j jjd}|dk	r^t| jjj }t|d | S dS )z@Return the URL to the type definition for this resource, if any.NtyperJ   #)r-   r%   r&   r   r@   
markup_urlZensureSlashstr)r/   rU   Ztype_idbaser   r   r   type_url.  s    
zResource.type_urlc             C   s   | j jd S )zReturn the ID of this resource.rJ   )r-   r%   )r/   r   r   r   rJ   @  s    zResource.idapplication/jsonc             C   s   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   r@   rU   r-   )r/   rO   rR   rW   rS   r   r   r   bindE  s    zResource.bindc             C   sH   | j dj}x*|D ]"}|j j}|jjd|kr|S qW td| dS )z<Get a description of one of this resource's representations.ZGET	mediaTypez4No definition for representation with media type %s.N)
get_methodresponserH   r-   r%   r&   r    )r/   rR   Zdefault_get_responserO   representation_tagr   r   r   rT   [  s    

z&Resource.get_representation_definitionc             C   sX   xR| j  D ]F}|jjddj }|dks4||j kr
t| |}|j|||r
|S q
W dS )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.
        r3    N)_method_tag_iterr%   r&   lowerr   is_described_by)r/   Zhttp_methodrR   query_paramsZrepresentation_params
method_tagr3   methodr   r   r   rb   e  s    
zResource.get_methodc             C   s   | 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_definitionr0   )r/   rR   r   r   r   
parameters  s    
zResource.parametersc             C   s   | 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.
        )rl   parameter_names)r/   rR   r   r   r   rn     s    
zResource.parameter_namesc             c   s"   x| j  D ]}t| |V  q
W dS )z6An iterator over the methods defined on this resource.N)rf   r   )r/   rj   r   r   r   method_iter  s    zResource.method_iterc             C   sF   | j |}|j}x0|jtdD ]}|jjd|kr t| |S q W dS )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.
        r#   r3   N)rl   r-   r.   r   r%   r&   r   )r/   
param_namerR   rG   rd   r(   r   r   r   get_parameter  s    
zResource.get_parameterc             C   s   | j dkrtd| jdkr|jdkr4td|j | j |j }|dk	r| j|j|j\}}|t	kr|dkryt
|}W nP tk
r   ytjtj|dd	d
  }W n tk
r   t|Y nX Y nX |S td| j dS )zFind the value of a parameter, given the Parameter object.

        :raise ValueError: If the parameter value can't be converted into
        its defined type.
        Nz,Resource is not bound to any representation.zapplication/jsonplainz8Don'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.)rs   rt   )rO   r   rR   r$   rI   r3   _dereference_namespacer-   rY   XML_SCHEMA_NS_URIr   r,   datetimetimeZstrptime)r/   	parameterr1   namespace_urlZ	data_typer   r   r   get_parameter_value  s2    



zResource.get_parameter_valuec             C   sD   |dk	r"d|k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:   re   )splitr&   NS_MAP)r/   r-   r1   	namespacens_mapr{   r   r   r   rv     s    
zResource._dereference_namespacec             C   s   | j jj|S )z-Given an ID, find a ResourceType for that ID.)r@   resource_typesr&   )r/   rJ   r   r   r   rD     s    zResource._definition_factoryc             C   s   | 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.
        rY   )r-   r%   r&   )r/   r   r   r   rB     s    zResource._get_definition_urlc             C   s:   | j dk	r| jj }n|dk	r*| j|}ntd|j S )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
        NzSResource is not bound to any representation, and no media media type was specified.)rO   rS   rH   rT   r   )r/   rR   rG   r   r   r   rl     s    
z(Resource._find_representation_definitionc             c   s,   | j  j}x|jtdD ]
}|V  qW dS )z+Iterate over this resource's <method> tags.rk   N)rH   r-   r.   r   )r/   rG   rj   r   r   r   rf   '  s    
zResource._method_tag_iter)NNTN)r_   TN)NNNN)N)N)N)N)r   r   r   r   rA   propertyrU   r^   rJ   r`   rT   rb   rm   rn   ro   rq   r|   rv   rD   rB   rl   rf   __classcell__r   r   )rX   r   r      s.     1  

 
 


0	
#c               @   sf   e Zd ZdZdd Zedd Zedd Zedd	 Zed
d Z	dddZ
dddZdddZdS )r   z*A wrapper around an XML <method> tag.
    c             C   s   || _ | j j| _|| _dS )zaInitialize with a <method> tag.

        :param method_tag: An ElementTree <method> tag.
        N)r)   r@   r-   )r/   r)   rj   r   r   r   rA   1  s    
zMethod.__init__c             C   s   t | | jjtdS )z@Return the definition of a request that invokes the WADL method.request)RequestDefinitionr-   findr   )r/   r   r   r   r   :  s    zMethod.requestc             C   s   t | j| jjtdS )z9Return the definition of the response to the WADL method.rc   )r   r)   r-   r   r   )r/   r   r   r   rc   ?  s    zMethod.responsec             C   s   | j jjdS )z)The XML ID of the WADL method definition.rJ   )r-   r%   r&   )r/   r   r   r   rJ   E  s    z	Method.idc             C   s   | 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.
        r3   )r-   r%   r&   rg   )r/   r   r   r   r3   J  s    zMethod.nameNc             K   s   | j j|f|S )z4Return the request URL to use to invoke this method.)r   	build_url)r/   r:   r;   r   r   r   build_request_urlS  s    zMethod.build_request_urlc             K   s   | j j||f|S )zBuild a representation to be sent when invoking this method.

        :return: A 2-tuple of (media_type, representation).
        )r   rO   )r/   rR   r:   r;   r   r   r   build_representationW  s    zMethod.build_representationc             C   s   d}|dk	r$| j j|}|dkr$dS |dk	rtt|dkrt| j }|dkrJdS y|j|j|d W n tk
rr   dS X |dkst|dkrdS |dk	r|j|S x@| j jD ]4}y|j|j| j	|d dS  tk
r   Y qX qW dS )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   r6   r=   ri   r,   rh   representationsr0   r)   )r/   rR   Zquery_valuesZrepresentation_valuesrO   r   r   r   r   rh   `  s<    

zMethod.is_described_by)N)NN)NNN)r   r   r   r   rA   r   r   rc   rJ   r3   r   r   rh   r   r   r   r   r   .  s   		
 
 c               @   sN   e Zd ZdZdd Zedd Zedd Zdd	d
ZdddZ	dddZ
dS )r   zBA wrapper around the description of the request invoking a method.c             C   s$   || _ | j j| _| jj| _|| _dS )zInitialize with a <request> tag.

        :param resource: The resource to which this request can be sent.
        :param request_tag: An ElementTree <request> tag.
        N)rk   r)   r@   r-   )r/   rk   Zrequest_tagr   r   r   rA     s    

zRequestDefinition.__init__c             C   s   | j dgS )z,Return the query parameters for this method.query)r0   )r/   r   r   r   ri     s    zRequestDefinition.query_paramsc             c   s0   x*| j jtdD ]}t| j| j|V  qW d S )NrO   )r-   r.   r   r   r@   r)   )r/   rG   r   r   r   r     s    z!RequestDefinition.representationsNc             C   s*   x$| j D ]}|dks|j|kr|S qW dS )z1Return the appropriate representation definition.N)r   rR   )r/   rR   rO   r   r   r   rT     s    z/RequestDefinition.get_representation_definitionc             K   s,   | j |}|dkrtd| |j|f|S )zBuild a representation to be sent along with this request.

        :return: A 2-tuple of (media_type, representation).
        Nz,Cannot build representation of media type %s)rT   	TypeErrorr`   )r/   rR   r:   r;   rG   r   r   r   rO     s
    
z RequestDefinition.representationc             K   sT   | j | j|f|}| jj}t|dkrPd|kr4d}nd}||tt|j  7 }|S )z4Return the request URL to use to invoke this method.r   ?&)r=   ri   r)   rU   r6   r   sorteditems)r/   r:   r;   r<   rU   appendr   r   r   r     s    zRequestDefinition.build_url)N)NN)N)r   r   r   r   rA   r   ri   r   rT   rO   r   r   r   r   r   r     s   

r   c               @   sB   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dS )r   z;A wrapper around the description of a response to a method.Nc             C   s   |j | _ || _|| _|| _dS )zgInitialize with a <response> tag.

        :param response_tag: An ElementTree <response> tag.
        N)r@   r)   r-   headers)r/   r)   Zresponse_tagr   r   r   r   rA     s    zResponseDefinition.__init__c             c   s6   t d}x(| jj|D ]}t| jj| j|V  qW dS )zGet an iterator over the representation definitions.

        These are the representations returned in response to an
        invocation of this method.
        rO   N)r   r-   r.   r   r)   r@   )r/   pathrd   r   r   r   __iter__  s    zResponseDefinition.__iter__c             C   s   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   r)   r-   )r/   r   r   r   r   r`     s    zResponseDefinition.bindc             C   sH   xB| j jtdD ].}|jjd|kr|jjddkrt| |S qW dS )z,Find a header parameter within the response.r#   r3   r$   headerN)r-   r.   r   r%   r&   r   )r/   rp   r(   r   r   r   rq     s
    z ResponseDefinition.get_parameterc             C   s8   | j dkrtd|jdkr*td|j | j j|jS )z:Find the value of a parameter, given the Parameter object.Nz,Response object is not bound to any headers.r   z8Don't know how to find value for a parameter of type %s.)r   r   r$   rI   r&   r3   )r/   rz   r   r   r   r|     s    


z&ResponseDefinition.get_parameter_valuec             C   s.   | j dkrdS x| D ]}|j|kr|S qW dS )z8Get one of the possible representations of the response.N)r-   rR   )r/   rR   rO   r   r   r   rT   	  s    


z0ResponseDefinition.get_representation_definition)N)
r   r   r   r   rA   r   r`   rq   r|   rT   r   r   r   r   r     s   

c                   sz   e Zd ZdZ fddZ fddZdd Zedd	 Zd
d Z	dd Z
dddZdd Zdd Zdd Zdd Z  ZS )r   z2A definition of the structure of a representation.c                s    t t| j| || _|| _d S )N)rK   r   rA   r)   r-   )r/   r@   r)   rd   )rX   r   r   rA     s    z!RepresentationDefinition.__init__c                s   t t| jddg|S )Nr   rr   )rK   r   r0   )r/   r)   )rX   r   r   r0     s    
zRepresentationDefinition.paramsc             C   s   dd | j |D S )z#Return the names of all parameters.c             S   s   g | ]
}|j qS r   )r3   )r'   r#   r   r   r   r+   !  s    z<RepresentationDefinition.parameter_names.<locals>.<listcomp>)r0   )r/   r)   r   r   r   rn     s    z(RepresentationDefinition.parameter_namesc             C   s   | j  jjd S )z4The media type of the representation described here.ra   )rH   r-   r%   )r/   r   r   r   rR   #  s    z#RepresentationDefinition.media_typec       	      C   s   t ttjd }d| }tjtj}d||  d }|dkrB|S |}d}xHdtj| d	 jd
}tj	||tj
dsxP |d t| }|d7 }qLW |S )z;Make a random boundary that does not appear in `all_parts`.r~   z%%0%dd=   z==Nr   z^--z(--)?$ascii)flags.z===============)r6   reprsysmaxsizerandomZ	randrangereescapeencodesearch	MULTILINEr\   )	r/   Z	all_partsZ_widthZ_fmttokenboundarybZcounterpatternr   r   r   _make_boundary(  s    z'RepresentationDefinition._make_boundaryc             C   sT   xD|D ]<\}}|j |jd |j d |j |jd |j d qW |j d dS )z$Write MIME headers to a file object.zUTF-8s   : s   
N)writer   )r/   bufr   keyr1   r   r   r   _write_headers:  s    
z'RepresentationDefinition._write_headersFc             C   s6   |j d |j |jd |r(|j d |j d dS )z,Write a multipart boundary to a file object.s   --zUTF-8s   
N)r   r   )r/   r   r   closingr   r   r   _write_boundaryC  s
    

z(RepresentationDefinition._write_boundaryc             C   s  g }x|D  ]\}}}t j }|r>d}dt|t|f }nd}dt| }| j|dd|fd|fg |rt|tstd	t| |j| njt|t	std
t| t
jd|}	x.|	dd D ]}
|j|
jd |jd qW |j|	d jd |j|j  qW | jdj|}t j }dt| }| j|dd|fg x.|D ]&}| j|| |j| |jd qLW | j||d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="%s"; filename="%s"ztext/plain; charset="utf-8"zform-data; name="%s"MIME-Version1.0zContent-TypezContent-Dispositionzbytes payload expected: %szstr payload expected: %sz
\r\n|\r|\nNr~   zUTF-8s   
z"multipart/form-data; boundary="%s"T)r   )r   r   r   )r   r   )ioBytesIOr   r   rM   bytesr   rY   r   r\   r   r   r   r   getvaluer   r7   r   )r/   partsZencoded_partsZ	is_binaryr3   r1   r   ZctypeZcdisplinesliner   Zencoded_partr   r   r   _generate_multipart_formK  sJ    



z1RepresentationDefinition._generate_multipart_formc             K   s   | j  }|j| j}| j||f|}| j}|dkrDtt|j }n~|dkrg }t }	x:|D ]2}
|j	|
j
|	}||	k	r\|j|
jdk|
j
|f q\W | j|\}}n |dkrtj|}ntd| ||fS )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binaryzapplication/jsonzUnsupported media type: '%s')rH   r0   r)   r=   rR   r   r   r   objectr&   r3   r   rY   r   rP   dumpsr,   )r/   r:   r;   rG   r0   r<   rR   docr   Zmissingr#   r1   r   r   r   r`     s&    
zRepresentationDefinition.bindc             C   s   | j jj|S )z9Turn a representation ID into a RepresentationDefinition.)r@   representation_definitionsr&   )r/   rJ   r   r   r   rD     s    z,RepresentationDefinition._definition_factoryc             C   s   | 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.
        Zhref)r-   r%   r&   )r/   r   r   r   rB     s    z,RepresentationDefinition._get_definition_url)F)r   r   r   r   rA   r0   rn   r   rR   r   r   r   r   r`   rD   rB   r   r   r   )rX   r   r     s   	
@c               @   s   e Zd ZdZdd Zedd Zedd Zedd	 Zed
d Z	edd Z
dd Zedd Zedd Zedd ZdS )r   z5One of the parameters of a representation definition.c             C   s   |j | _ || _|| _dS )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)r@   value_containerr-   )r/   r   r-   r   r   r   rA     s    
zParameter.__init__c             C   s   | j jjdS )zThe name of this parameter.r3   )r-   r%   r&   )r/   r   r   r   r3     s    zParameter.namec             C   s   | j jjdS )zThe style of this parameter.r$   )r-   r%   r&   )r/   r   r   r   r$     s    zParameter.stylec             C   s   | j jjdS )zThe XSD type of this parameter.rY   )r-   r%   r&   )r/   r   r   r   rY     s    zParameter.typec             C   s   | 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.
        Zfixed)r-   r%   r&   )r/   r   r   r   r4     s    	zParameter.fixed_valuec             C   s   | j jjddj dkS )z6Whether or not a value for this parameter is required.ZrequiredZfalse1true)r   r   )r-   r%   r&   rg   )r/   r   r   r   r8     s    zParameter.is_requiredc             C   s   | 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.
        )r   r|   )r/   r   r   r   	get_value  s    zParameter.get_valuec                s    fdd j jtdD S )z7Return the set of acceptable values for this parameter.c                s   g | ]}t  |qS r   )Option)r'   
option_tag)r/   r   r   r+     s   z%Parameter.options.<locals>.<listcomp>r2   )r-   r.   r   )r/   r   )r/   r   r5     s    
zParameter.optionsc             C   s&   | j jtd}|dkrdS 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)r-   r   r   r   )r/   link_tagr   r   r   r     s    	zParameter.linkc             C   s   | j }|dkr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.
        Nz(This parameter isn't a link to anything.)r   r,   follow)r/   r   r   r   r   linked_resource  s    
zParameter.linked_resourceN)r   r   r   r   rA   r   r3   r$   rY   r4   r8   r   r5   r   r   r   r   r   r   r     s   	c               @   s$   e Zd ZdZdd Zedd ZdS )r   z0One of a set of possible values for a parameter.c             C   s   || _ || _dS )z}Initialize the option.

        :param parameter: A Parameter.
        :param link_tag: An ElementTree <option> tag.
        N)rz   r-   )r/   rz   r   r   r   r   rA     s    zOption.__init__c             C   s   | j jjdS )Nr1   )r-   r%   r&   )r/   r   r   r   r1     s    zOption.valueN)r   r   r   r   rA   r   r1   r   r   r   r   r     s   	r   c                   sH   e Zd ZdZ fddZedd Zedd Zdd	 Zd
d Z	  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                s"   t t| j|j || _|| _dS )zyInitialize the link.

        :param parameter: A Parameter.
        :param link_tag: An ElementTree <link> tag.
        N)rK   r   rA   r@   rz   r-   )r/   rz   r   )rX   r   r   rA   (  s    zLink.__init__c             C   s   | 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
   rH   )r/   r   r   r   r   2  s    zLink.followc             C   s&   y| j  }W n tk
r    dS X dS )zCan this link be followed within wadllib?

        wadllib can follow a link if it points to a resource that has
        a WADL definition.
        FT)rB   r
   )r/   Zdefinition_urlr   r   r   r   ;  s
    zLink.can_followc             C   s    t | j| jj | jjj|jS )z,Turn a resource type ID into a ResourceType.)r   r@   rz   r   r   r&   r-   )r/   rJ   r   r   r   rD   H  s    zLink._definition_factoryc             C   s"   | j jjd}|dkrtd|S )z(Find the URL containing the definition .rV   NzIParameter is a link, but not to a resource with a known WADL description.)r-   r%   r&   r
   )r/   rY   r   r   r   rB   N  s    zLink._get_definition_url)r   r   r   r   rA   r   r   r   rD   rB   r   r   r   )rX   r   r   !  s   
	c               @   s   e Zd ZdZdd ZdS )r	   z,A wrapper around an XML <resource_type> tag.c             C   s
   || _ dS )zvInitialize with a <resource_type> tag.

        :param resource_type_tag: An ElementTree <resource_type> tag.
        N)r-   )r/   Zresource_type_tagr   r   r   rA   Z  s    zResourceType.__init__N)r   r   r   r   rA   r   r   r   r   r	   W  s   c               @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )r   z1A WADL document made programmatically accessible.c             C   s   || _ t|dr| j|| _n| j|| _| jjtd| _| jjj	d| _
i | _i | _xB| jjtdD ].}|jj	d}|dk	rjt| d|}|| j|< qjW x0| jjtdD ]}|jd }t|| j|< qW dS )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   rJ   NrV   )r[   hasattr_from_streamr   _from_stringr   r   r   r%   r&   resource_baser   r   r.   r   r	   )r/   r[   markuprO   rJ   rG   rV   r   r   r   rA   e  s"    


zApplication.__init__c             C   sz   d}d}g }xbt j||D ]R\}}|dkr6|j| q|dkrH|j  q|dkr|dkr\|}|jtt| qW t j|S )zrTurns markup into a document.

        Just a wrapper around ElementTree which keeps track of namespaces.
        startstart-nsend-nsN)r   r   r   )ETZ	iterparser   popsetr   r   ZElementTree)r/   streamZeventsrootr   Zeventelemr   r   r   r   ~  s    
zApplication._from_streamc             C   s$   t |ts|jd}| jtj|S )zTurns markup into a document.zUTF-8)rM   r   r   r   r   r   )r/   r   r   r   r   r     s    

zApplication._from_stringc             C   s.   | j |}| jj|}|dkr*td| |S )z7Retrieve a resource type by the URL of its description.NzNo such XML ID: "%s")rC   r   r&   rE   )r/   Zresource_type_urlrF   rV   r   r   r   rN     s
    
zApplication.get_resource_typec             C   s^   t | jj }d|_|jdr,t |j }n
|j|}|j}d|_||krN|S td| dS )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.
        NZhttpz,Can't look up definition in another url (%s))r   r[   ZensureNoSlashZfragment
startswithZresolverI   )r/   rU   Z
markup_uriZthis_uriZpossible_xml_idr   r   r   rC     s    

zApplication.lookup_xml_idc                sV    fdd| j D }t|dk r$dS t|dkr<td  t| t| j d|d S )zpLocate one of the resources described by this document.

        :param path: The path to the resource.
        c                s   g | ]}|j d   kr|qS )r   )r%   )r'   r)   )r   r   r   r+     s    z4Application.get_resource_by_path.<locals>.<listcomp>r~   Nz+More than one resource defined with path %sTr   )r   r6   r
   r   r   r   )r/   r   Zmatchingr   )r   r   get_resource_by_path  s    z Application.get_resource_by_pathN)
r   r   r   r   rA   r   r   rN   rC   r   r   r   r   r   r   b  s    )4r   rY   Z__metaclass____all__rx   Zemail.utilsr   r   rP   r   r   r   ry   Zurllib.parser   ImportErrorZurllibZxml.etree.cElementTreeZetreeZcElementTreer   Zlazr.urir   r   Zwadllibr   r   Zwadllib.iso_strptimer   r   rw   r   r   r   	Exceptionr
   r   r    r   r!   r"   r>   r   r   r   r   r   r   r   r   r	   r   r   r   r   r   <module>   sf   	
B=  >j9B !]6