o
    g2L                     @   s   d Z ddlZddlZddlmZ ddlmZ ddlmZ ddl	m
Z
mZ ddlmZ ddlmZmZ dd	lmZ dd
lmZ ddlmZ ddgZG dd deZG dd deZG dd deZdS )z:
    zeep.wsdl.messages.soap
    ~~~~~~~~~~~~~~~~~~~~~~~

    N)OrderedDict)etree)ElementMaker)
exceptionsxsd)as_qname)ConcreteMessageSerializedMessage)process_multiref)XmlParserContext)CompoundValueDocumentMessage
RpcMessagec                       s   e Zd ZdZejri Z fddZdd Zdd Z	d!d	d
Z
edd Zedd Zedd Zedd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Z  ZS )"SoapMessagea  Base class for the SOAP Document and RPC messages

    :param wsdl: The main wsdl document
    :type wsdl: zeep.wsdl.Document
    :param name:
    :param operation: The operation to which this message belongs
    :type operation: zeep.wsdl.bindings.soap.SoapOperation
    :param type: 'input' or 'output'
    :type type: str
    :param nsmap: The namespace mapping
    :type nsmap: dict

    c                    s>   t  ||| || _d | _|| _d| _d | _d | _d | _d S )NF)	super__init__nsmapabstracttype_is_body_wrappedbodyheaderenvelope)selfwsdlname	operationr   r   	__class__ P/home/ubuntu/webapp/venv/lib/python3.10/site-packages/zeep/wsdl/messages/soap.pyr   *   s   
zSoapMessage.__init__c                 O   s   d| j d i}|| jjj t| j d |d}| }|dd}| ||}|dur1|	| | j
rX| j
|i |}| jrG| j
|| n| }	|	|	 | j
|	| n	| }	|	|	 d| jjrld| jj ndi}
td|
|dS )	z+Create a SerializedMessage for this messagesoap-env	namespacer   _soapheadersN
SOAPActionz"%s"z"")pathheaderscontent)r   updater   types_prefix_map_customr   Envelopepop_serialize_headerappendr   r   renderBodyr   
soapactionr	   )r   argskwargsr   soapr   headers_valuer   
body_valuer   r'   r   r   r    	serialize5   s.   


zSoapMessage.serializec                 C   s  | j sdS | js
J |jd| jd}| |}|jd| jd}| |}|}|| | j di |}| jjjr:|S |j	}t
|dsD|S |du sNt|dkrPdS t|dkrX|S tt|j }t|tjr|jj}|jj}	t|dkrt|	dkr|d \}
}t||
}|S |S )	z[Deserialize the SOAP:Envelope and return a CompoundValue with the
        result.

        Nzsoap-env:Body
namespaceszsoap-env:Header__len__r      r   )r   r   findr   _deserialize_body_deserialize_headersr)   r   _elementr   hasattrlennextiter
__values__values
isinstancer   r   	_xsd_typeelements
attributesgetattr)r   r   r   body_resultr   headers_resultr4   resultchildrenrJ   	item_nameitem_elementretvalr   r   r    deserializea   s<   





zSoapMessage.deserializeFc                 C   s   | j sd S |rBt| j jtjr7zt| j jjdkr+| j jjd d jj| jj	ddW S W n
 t
y6   Y d S w | j jj| jj	ddS | jrR| jjj| jj	ddg}ng }| jsYJ | jjjrn|d| jjj| jj	dd  ddd |D S )	Nr<   r   F)schema
standalonez_soapheaders={%s}z, c                 s   s    | ]}|r|V  qd S Nr   ).0partr   r   r    	<genexpr>   s    z(SoapMessage.signature.<locals>.<genexpr>)r   rG   r   r   ComplexTyperB   rI   	signaturer   r*   AttributeErrorr   r   r@   r/   join)r   	as_outputpartsr   r   r    r[      s6   

zSoapMessage.signaturec                 C   s|   | d}| |j||||d}d}d}	|jd|jjd}
|
dur%| |
}|jd|jjd}| ||j|}	||	d|_	|S )a  Parse a wsdl:binding/wsdl:operation/wsdl:operation for the SOAP
        implementation.

        Each wsdl:operation can contain three child nodes:
         - input
         - output
         - fault

        Definition for input/output::

          <input>
            <soap:body parts="nmtokens"? use="literal|encoded"
                       encodingStyle="uri-list"? namespace="uri"?>

            <soap:header message="qname" part="nmtoken" use="literal|encoded"
                         encodingStyle="uri-list"? namespace="uri"?>*
              <soap:headerfault message="qname" part="nmtoken"
                                use="literal|encoded"
                                encodingStyle="uri-list"? namespace="uri"?/>*
            </soap:header>
          </input>

        And the definition for fault::

           <soap:fault name="nmtoken" use="literal|encoded"
                       encodingStyle="uri-list"? namespace="uri"?>

        r   )r   r   Nz	soap:bodyr9   zsoap:header)r   r   )
getr   r=   bindingr   _parse_bodyfindall_parse_headertarget_namespace_resolve_info)clsdefinitions
xmlelementr   r   r   r   obj	body_dataheader_datar   rI   r   r   r    parse   s   

zSoapMessage.parsec                 C   s(   | d| dd| d| ddS )zParse soap:body and return a dict with data to resolve it.

        <soap:body parts="nmtokens"? use="literal|encoded"?
                   encodingStyle="uri-list"? namespace="uri"?>

        rX   useliteralencodingStyler#   )rX   rn   rp   r#   )r`   )rg   ri   r   r   r    rb      s
   	
zSoapMessage._parse_bodyc           
      C   sf   g }|D ],}|  ||}g |d< |jd|jjd}|D ]}|  ||}	|d |	 q|| q|S )aF  Parse the soap:header and optionally included soap:headerfault elements

          <soap:header
            message="qname"
            part="nmtoken"
            use="literal|encoded"
            encodingStyle="uri-list"?
            namespace="uri"?
          />*

        The header can optionally contain one ore more soap:headerfault
        elements which can contain the same attributes as the soap:header::

           <soap:headerfault message="qname" part="nmtoken" use="literal|encoded"
                             encodingStyle="uri-list"? namespace="uri"?/>*

        faultszsoap:headerfaultr9   )_parse_header_elementrc   ra   r   r/   )
rg   xmlelementstnsr   rN   ri   datafault_elementsfault_element
fault_datar   r   r    rd      s   zSoapMessage._parse_headerc                 C   sX   |j }t|d |j|}z||d |d |d|ddW S  ty+   tdw )NmessagerX   rn   rp   r#   )ry   rX   rn   rp   r#   zInvalid soap:header(fault))attribr   r   r`   KeyErrorr   WsdlSyntaxError)rg   ri   rt   rJ   message_qnamer   r   r    rr     s   
z!SoapMessage._parse_header_elementc                 C   sn   | j }| ` |du s|js| jdkrdS || _t| jj}| |d ||| _| |d ||| _| 	 | _
dS )a   Resolve the data in the self._resolve_info dict (set via parse())

        This creates three xsd.Element objects:

            - self.header
            - self.body
            - self.envelope (combination of headers and body)

        XXX headerfaults are not implemented yet.

        Ninputr   r   )rf   r_   r   r   r   _resolve_headerr   _resolve_bodyr   _create_envelope_elementr   )r   rh   abstract_messageinfor_   r   r   r    resolve"  s   
zSoapMessage.resolvec                 C   s   t g }| js
J | jjjr|t d| jd  | jj |t d| jd  | jr0| jjnd t d| jd  t 	|S )zxCreate combined `envelope` complexType which contains both the
        elements from the body and the headers.

        z
{%s}headerr!   z{%s}bodyNz{%s}envelope)
r   Sequencer   r   r@   r/   Elementr   r   rZ   )r   all_elementsr   r   r    r   ?  s   


z$SoapMessage._create_envelope_elementc                 C   s  |sd S t |}t| jd |d}| }t|trK|D ]+}t|tr9t|dr1|j	
|| q|j
|| qt|tjrE|| qtd|S t|tr| jsWtd| jdi |}| jjjD ]\}}||v r}|| d ur}|
||| d|g qd|S td)Nr!   r"   _xsd_elmz#Invalid value given to _soapheaderszG_soapheaders only accepts a dictionary if the wsdl defines the headers.r   r   )copydeepcopyr   r   HeaderrG   listr   rA   r   r0   rH   r   _Elementr/   
ValueErrordictr   r   rI   )r   r6   r   r5   r   header_valuer   elmr   r   r    r.   W  s6   




zSoapMessage._serialize_headerc                 C      t  rV   NotImplementedError)r   ri   r   r   r    r>   {     zSoapMessage._deserialize_bodyc                 C   sJ   | j r|du r	i S t| jjd}| j j|| jj|d}|dur#d|iS i S )z1Deserialize the values in the SOAP:Header elementNsettingscontextr   )r   r   r   r   rm   r*   r   ri   r   rN   r   r   r    r?   ~  s   z SoapMessage._deserialize_headersc                 C   s   t | jd d}tjdd}|st|t|S |D ]:}|d j}|d }|d|}	|	| j	kr9||v r9||= |	j
| }
|
jrJ|
j }||_nt||
j}|| qt|t|S )Nr!   r   T)consume_otherry   rX   messages)r   QNamer   r   Allr   rZ   textr`   r   r_   elementclone	attr_namer   r/   )r   r   rh   r_   r   	containeritemmessage_name	part_namery   rX   r   r   r   r    r     s"   


zSoapMessage._resolve_headerc                 C   r   rV   r   )r   r   rh   r_   r   r   r    r     r   zSoapMessage._resolve_body)F)__name__
__module____qualname____doc__typingTYPE_CHECKINGrf   r   r8   rS   r[   classmethodrm   rb   rd   rr   r   r   r.   r>   r?   r   r   __classcell__r   r   r   r    r      s.    ,
.
2

"
$r   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )r   a/  In the document message there are no additional wrappers, and the
    message parts appear directly under the SOAP Body element.

    .. inheritance-diagram:: zeep.wsdl.messages.soap.DocumentMessage
       :parts: 1

    :param wsdl: The main wsdl document
    :type wsdl: zeep.wsdl.Document
    :param name:
    :param operation: The operation to which this message belongs
    :type operation: zeep.wsdl.bindings.soap.SoapOperation
    :param type: 'input' or 'output'
    :type type: str
    :param nsmap: The namespace mapping
    :type nsmap: dict


    c                    s   t  j|i | d S rV   )r   r   )r   r3   r4   r   r   r    r     s   zDocumentMessage.__init__c                 C   s>   | j s	t|d }t| jjd}| jj|| jj|d}d|iS )Nr   r   r   r   )r   r   r   r   r   r   rm   r*   r   r   r   r    r>     s
   z!DocumentMessage._deserialize_bodyc           	      C   s   t | jd d}|r|sd S |d r|d }|| jg}n)g }| D ]"\}}|jd ur9|j }|p6|j|_ntj	||j
d}|| q$t|dkr\d| _t	|tt|S d| _|d S )	Nr!   r1   rX   )r   type_r<   TFr   )r   r   r   r   itemsr   r   r   r   r   r   r/   rB   r   rZ   r   )	r   r   rh   r_   r   r   sub_elementsrX   r   r   r   r    r     s$   

zDocumentMessage._resolve_body)r   r   r   r   r   r>   r   r   r   r   r   r    r     s
    c                   @   s    e Zd ZdZdd Zdd ZdS )r   a  In RPC messages each part is a parameter or a return value and appears
    inside a wrapper element within the body.

    The wrapper element is named identically to the operation name and its
    namespace is the value of the namespace attribute.  Each message part
    (parameter) appears under the wrapper, represented by an accessor named
    identically to the corresponding parameter of the call.  Parts are arranged
    in the same order as the parameters of the call.

    .. inheritance-diagram:: zeep.wsdl.messages.soap.DocumentMessage
       :parts: 1


    :param wsdl: The main wsdl document
    :type wsdl: zeep.wsdl.Document
    :param name:
    :param operation: The operation to which this message belongs
    :type operation: zeep.wsdl.bindings.soap.SoapOperation
    :param type: 'input' or 'output'
    :type type: str
    :param nsmap: The namespace mapping
    :type nsmap: dict

    c           	      C   s   |sdS |d }| j dkrt|| jj}n	t|| jjj}g }| D ]\}}|jr3|	|j q%|	t
||j  q%t
|t
t
|S )a  Return an XSD element for the SOAP:Body.

        Each part is a parameter or a return value and appears inside a
        wrapper element within the body named identically to the operation
        name and its namespace is the value of the namespace attribute.

        Nr#   r~   )r   r   r   r   r   r   	localnamer   r   r/   r   r   rZ   r   )	r   r   rh   r_   r#   tag_namerI   r   msgr   r   r    r     s   
zRpcMessage._resolve_bodyc                 C   sL   t | t|d }| jr"t| jj}| jj|| jj|d}d|iS ddiS )zThe name of the wrapper element is not defined. The WS-I defines
        that it should be the operation name with the 'Response' string as
        suffix. But lets just do it really stupid for now and use the first
        element.

        r   r   r   N)r
   r   r   r   r   r   rm   r*   )r   body_elementresponse_elementr   rN   r   r   r    r>     s   zRpcMessage._deserialize_bodyN)r   r   r   r   r   r>   r   r   r   r    r     s    )r   r   r   collectionsr   lxmlr   lxml.builderr   zeepr   r   
zeep.utilsr   zeep.wsdl.messages.baser   r	   zeep.wsdl.messages.multirefr
   zeep.xsd.contextr   zeep.xsd.valueobjectsr   __all__r   r   r   r   r   r   r    <module>   s&       @