o
    j;                     @   sp  d Z ddlmZ ddlZeeZddlmZ ddl	m
Z
 zddlZddlmZ W n ey8   ddlZeZY nw ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm Z  G dd dej!Z"e#e$e%e
j&e
j'h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,de,iZ-dd Z.dS )a!  The ``spyne.protocol.json`` package contains the Json-related protocols.
Currently, only :class:`spyne.protocol.json.JsonDocument` is supported.

Initially released in 2.8.0-rc.

Missing Types
=============

The JSON standard does not define every type that Spyne supports. These include
Date/Time types as well as arbitrary-length integers and arbitrary-precision
decimals. Integers are parsed to ``int``\s or ``long``\s seamlessly but
``Decimal``\s are only parsed correctly when they come off as strings.

While it's possible to e.g. (de)serialize floats to ``Decimal``\s by adding
hooks to ``parse_float`` [#]_ (and convert later as necessary), such
customizations apply to the whole incoming document which pretty much messes up
``AnyDict`` serialization and deserialization.

It also wasn't possible to work with ``object_pairs_hook`` as Spyne's parsing
is always "from outside to inside" whereas ``object_pairs_hook`` is passed
``dict``\s basically in any order "from inside to outside".

.. [#] http://docs.python.org/2/library/json.html#json.loads
    )absolute_importN)chain)six)JSONDecodeErrorValidationError)ResourceNotFoundError)BINARY_ENCODING_BASE64)Date)Time)DateTime)Double)Integer)Boolean)Fault)HierDictDocumentc                       s   e Zd Z fddZ  ZS )JsonEncoderc              
      sV   z	t t| |W S  ty* } ztjtjkrt| t	|W  Y d }~S d }~ww N)
superr   default	TypeErrorloggerlevelloggingDEBUG	exceptionlist)selfoe	__class__ S/var/www/html/LicenciasMiG/venv/lib/python3.10/site-packages/spyne/protocol/json.pyr   M   s   
zJsonEncoder.default)__name__
__module____qualname__r   __classcell__r"   r"   r    r#   r   L   s    r   c                	       s   e Zd ZdZdZdZeejZe	d e
ZdZdddddedddf	 fdd	Zd	d
 Zdd Zdd Z fddZedd Zejdd ZdddZdddZ  ZS )JsonDocumentaQ  An implementation of the json protocol that uses simplejson package when
    available, json package otherwise.

    :param ignore_wrappers: Does not serialize wrapper objects.
    :param complex_as: One of (list, dict). When list, the complex objects are
        serialized to a list of values instead of a dict of key/value pairs.
    zapplication/jsonTjsonNFc
              
      s   t t| ||||||||	 t| d| _| j| jt< | j	| jt
< | j| jt< | j| jt< | j| jt
< | j| jt< || _|
| _d S )Nmessage)r   r(   __init__r   __getattribute___JsonDocument__message_ret_number_from_unicode_handlersr   	_ret_boolr   r   _ret_to_unicode_handlersdefault_string_encodingkwargs)r   app	validator	mime_typeignore_uncapignore_wrappers
complex_asorderedr3   polymorphicr4   r    r"   r#   r+   p   s   
zJsonDocument.__init__c                 C   s   |S r   r"   r   clsvaluer"   r"   r#   r1      s   zJsonDocument._retc                 C   s&   t |tr	t||dv rt|S |S N)TF)
isinstanceNON_NUMBER_TYPESr   intr=   r"   r"   r#   r.      s
   
zJsonDocument._ret_numberc                 C   s   |d u s|dv r
|S t |r@   r   r=   r"   r"   r#   r0      s   zJsonDocument._ret_boolc                    sN   t t| ||| t|tttfr#t|tj	r|
||s%t||d S d S r   )r   r(   validate
issubclassr   r
   r   rA   r   string_typesvalidate_stringr   )r   keyr>   valr    r"   r#   rD      s   


zJsonDocument.validatec                 C   s   | j S r   )r-   r   r"   r"   r#   r*      s   zJsonDocument.messagec                 C   s(   || j u rd| jvrt| jd< || _d S )Nr>   )RESPONSEr4   r   r-   )r   rI   r"   r"   r#   r*      s   

c              
   C   s|   z*d |j}t|tjs|du r| j}|dur||}tj|fi | j	|_
W dS  ty= } ztdt|d}~ww )z2Sets ``ctx.in_document``  using ``ctx.in_string``.    NzClient.JsonDecodeError)join	in_stringrA   r   	text_typer3   decoder)   loadsr4   in_documentr   r   repr)r   ctxin_string_encodingrN   r   r"   r"   r#   create_in_document   s   
zJsonDocument.create_in_documentutf8c                    s>    du rfdd|j D |_dS  fdd|j D |_dS )z3Sets ``ctx.out_string`` using ``ctx.out_document``.Nc                 3   s$    | ]}t j|fi  jV  qd S r   )r)   dumpsr4   .0r   rJ   r"   r#   	<genexpr>   s    z1JsonDocument.create_out_string.<locals>.<genexpr>c                 3   s*    | ]}t j|fi j V  qd S r   )r)   rX   r4   encoderY   out_string_encodingr   r"   r#   r[      s
    
)out_document
out_stringr   rT   r^   r"   r]   r#   create_out_string   s   
zJsonDocument.create_out_stringr   rW   )r$   r%   r&   __doc__r7   
text_basedsetr   typeaddr	   default_binary_encoding_decimal_as_stringdictr+   r1   r.   r0   rD   propertyr*   setterrV   rb   r'   r"   r"   r    r#   r(   \   s.    




r(   c                       s"   e Zd ZdZd fdd	Z  ZS )HybridHttpJsonDocumentaQ  This protocol lets you have the method name as the last fragment in the
    request url. Eg. instead of sending a HTTP POST request to

        http://api.endpoint/json/

    containing: ::

        {
            "method_name": {
                "arg1" : 42,
                "arg2" : "foo"
            }
        }

    you will have to send the request to

        http://api.endpoint/json/method_name

    containing: ::

        {
            "arg1" : 42,
            "arg2" : "foo"
        }

    Part of request data comes from HTTP and part of it comes from Json, hence
    the name.
    Nc                    s4   t t| | |j dd }||ji|_d S )N/)r   rn   rV   	transportget_pathsplitrR   )r   rT   rU   url_fragmentr    r"   r#   rV      s   z)HybridHttpJsonDocument.create_in_documentr   )r$   r%   r&   rd   rV   r'   r"   r"   r    r#   rn      s    rn   c                       sB   e Zd ZdZeejZed  fddZd fdd	Z	  Z
S )	JsonPaV  The JsonP protocol puts the reponse document inside a designated
    javascript function call. The input protocol is identical to the
    JsonDocument protocol.

    :param callback_name: The name of the function call that will wrapp all
        response documents.

    For other arguents, see :class:`spyne.protocol.json.JsonDocument`.
    jsonpc                    s    t t| j|i | || _d S r   )r   ru   r+   callback_name)r   rw   argsr4   r    r"   r#   r+      s   
zJsonP.__init__rW   c                    sX   t t| j||d |d u rt| jdf|jd|_d S t| j|dg|jdg|_d S )N)r^   ()z);   (s   );)r   ru   rb   r   rw   r`   r\   ra   r    r"   r#   rb      s   

zJsonP.create_out_stringrc   )r$   r%   r&   rd   rf   r   rg   rh   r+   rb   r'   r"   r"   r    r#   ru      s    


ru   c                   @   s>   e Zd ZdZdZdZdZdZej	fddZ
dd	 Zd
d ZdS )_SpyneJsonRpc1   verbodyheadfaultc                 C   s   |j }t|tst|d|| j}|d u rt|d|| j}|| j}|d u r7|d u r7t||fdd|j_	|d urH||_
d|j_	d S t|tsRt|dt|dks]t|d|| j|_t|jtso|jg|_| \\|_|_
d S )	NzInvalid RequestzUnknown VersionzRequest data not foundFTzRequest body not foundr|   zNeed len(body) == 1)rR   rA   rk   r   getVERSIONBODYFAULTprotocolerrorin_body_doclenHEADin_header_docr   itemsmethod_request_string)r   rT   r*   indocr}   r~   errr"   r"   r#   decompose_incoming_envelope  s,   






z*_SpyneJsonRpc1.decompose_incoming_envelopec           	      C   sR  || j | jfv s
J | jd| |jd u rt|j|jjr,d |_	| 
|t|j|_nt|| j u r:|jj}|jj}n|| ju rG|jj}|jj}|jd ur|d urd gt| }tt|j|D ]\}\}}|d urx|t|k rx| 
|||||< q_t|dkr|d |_n||_|jd u rd gt|j |_	n	| 
|||j|_	| jd| d S )Nbefore_deserializer|   r   after_deserialize)REQUESTrK   event_manager
fire_event
descriptorr   r   r   r   	in_object_doc_to_objectr   r   in_error	in_header
in_message
out_headerout_messager   r   	enumeratezip
_type_info)	r   rT   r*   header_class
body_classheadersi
header_doc
head_classr"   r"   r#   deserialize5  s@   






z_SpyneJsonRpc1.deserializec                 C   s  || j | jfv s
J | jd| d| ji|_|jd ur)tt|j| |j| j	< n|| j u r7|j
j}|j
j}n|| ju rD|j
j}|j
j}|j}| }| |}t|}t|j}		 zt|}
W n	 tyh   Y nw zt|	}W n tyz   d }Y nw ||
||| qY| || |j| j< |_|jd ur|d urt|jttfr|j}n|jf}g  |_}t||D ]\}}|| || qt|dkr||j| j < n|d |j| j < | jd| d S )Nbefore_serializer}   Tr|   r   after_serialize)!r   rK   r   r   versionr_   	out_errorr   to_dictr   r   r   r   r   r   r   get_cls_attrsiter
out_objectnextStopIteration	_safe_set_object_to_docr   out_body_docrA   r   tupleout_header_docr   appendr   r   )r   rT   r*   header_message_classbody_message_classout_type_infor   bm_attrskeysvalueskvout_headersr   r   r   r"   r"   r#   	serialize`  sb   








z_SpyneJsonRpc1.serializeN)r$   r%   r&   r   r   r   r   r   r(   r   r   r   r   r"   r"   r"   r#   r{     s    +r{   spynec                 O   s*   | t v sJ dtt  t |  |i |S )Nz-Unknown JsonRpc flavor. Accepted ones are: %r)_json_rpc_flavorsr   )flavourrx   r4   r"   r"   r#   JsonRpc  s   r   )/rd   
__future__r   r   	getLoggerr$   r   	itertoolsr   
spyne.utilr   
simplejsonr)   simplejson.decoderr   ImportError
ValueErrorspyne.errorr   r   spyne.model.binaryr	   spyne.model.primitiver
   r   r   r   r   r   spyne.model.faultr   spyne.protocol.dictdocr   JSONEncoderr   r   r   rk   rO   binary_typerB   r(   rn   ru   r{   r   r   r"   r"   r"   r#   <module>   sD   
i'$ 