U
    Ç½„bG  ã                   @   s*  d dl 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
 ddlmZ e e¡Zdd	„ Zd
d„ ZeedœZG dd„ deƒZG dd„ deƒZdZG dd„ dejƒZe eej¡ e eej¡ e eej¡ e eej¡ dd„ ZG dd„ dej ƒZ!e! "ee!j#¡ dd„ Z$G dd„ deƒZ%dS )é    N)ÚOrderedDict)Úforce_bytes)Úyamlé   )Úopenapi©ÚSwaggerValidationErrorc              
   C   sv   zddl m} ddlm} W n tk
r2   Y d S X z|| ƒ W n0 |k
rp } ztt|ƒƒ|‚W 5 d }~X Y nX d S )Nr   )Úparse)ÚValidationError)Z	flex.corer	   Zflex.exceptionsr
   ÚImportErrorr   Ústr)ÚspecZvalidate_flexr
   Úex© r   ú3/tmp/pip-unpacked-wheel-o6yr43pd/drf_yasg/codecs.pyÚ_validate_flex   s    r   c              
   C   sZ   ddl m} ddlm} z|| ƒ W n0 |k
rT } ztt|ƒƒ|‚W 5 d }~X Y nX d S )Nr   r   )Úvalidate_spec)Zswagger_spec_validator.commonr   Z"swagger_spec_validator.validator20r   r   )r   ZSSVErrZvalidate_ssvr   r   r   r   Ú _validate_swagger_spec_validator   s    r   )ZflexZssvc                   @   sD   e Zd ZdZdd„ Zedd„ ƒZdd„ Zdd	„ Zd
d„ Z	dd„ Z
dS )Ú_OpenAPICodecNc                 C   s
   || _ d S ©N©Z_validators)ÚselfÚ
validatorsr   r   r   Ú__init__/   s    z_OpenAPICodec.__init__c                 C   s   | j S )z List of validator names to applyr   )r   r   r   r   r   2   s    z_OpenAPICodec.validatorsc                 C   s¬   t |tjƒstdƒ‚|  |¡}i }| jD ]J}zt| t |¡ƒ W q( t	k
rp } zt
|ƒ||< W 5 d}~X Y q(X q(|ržt	d |¡||| ƒ}t t
|ƒ¡ |‚t|  |¡ƒS )a4  Transform an :class:`.Swagger` object to a sequence of bytes.

        Also performs validation and applies settings.

        :param openapi.Swagger document: Swagger spec object as generated by :class:`.OpenAPISchemaGenerator`
        :return: binary encoding of ``document``
        :rtype: bytes
        z%Expected a `openapi.Swagger` instanceNzspec validation failed: {})Ú
isinstancer   ZSwaggerÚ	TypeErrorÚgenerate_swagger_objectr   Ú
VALIDATORSÚcopyÚdeepcopyr   r   ÚformatÚloggerÚwarningr   Ú
_dump_dict)r   Údocumentr   ÚerrorsZ	validatorÚeÚexcr   r   r   Úencode7   s    	

 z_OpenAPICodec.encodec                 C   s   t |  |¡ƒS )zDDump an error message into an encoding-appropriate sequence of bytes)r   r#   )r   Úerrr   r   r   Úencode_errorT   s    z_OpenAPICodec.encode_errorc                 C   s   t dƒ‚dS )z»Dump the given dictionary into its string representation.

        :param dict spec: a python dict
        :return: string representation of ``spec``
        :rtype: str or bytes
        zoverride this methodN)ÚNotImplementedError©r   r   r   r   r   r#   X   s    z_OpenAPICodec._dump_dictc                 C   s   |  ¡ S )zÛGenerates the root Swagger object.

        :param openapi.Swagger swagger: Swagger spec object as generated by :class:`.OpenAPISchemaGenerator`
        :return: swagger spec as dict
        :rtype: OrderedDict
        )Zas_odict)r   Zswaggerr   r   r   r   a   s    z%_OpenAPICodec.generate_swagger_object)Ú__name__Ú
__module__Ú__qualname__Ú
media_typer   Úpropertyr   r(   r*   r#   r   r   r   r   r   r   ,   s   
	r   c                       s*   e Zd ZdZd‡ fdd„	Zdd„ Z‡  ZS )ÚOpenAPICodecJsonúapplication/jsonFc                    s    t t| ƒ |¡ || _|| _d S r   )Úsuperr2   r   Úprettyr0   )r   r   r5   r0   ©Ú	__class__r   r   r   n   s    zOpenAPICodecJson.__init__c                 C   s<   | j r.tj|ddd�}|d dkr*|d7 }|S t |¡S dS )z-Dump ``spec`` into JSON.

        :rtype: stré   )ú,z: )ÚindentÚ
separatorséÿÿÿÿÚ
N)r5   ÚjsonÚdumps)r   r   Úoutr   r   r   r#   s   s    zOpenAPICodecJson._dump_dict)Fr3   ©r-   r.   r/   r0   r   r#   Ú__classcell__r   r   r6   r   r2   k   s   r2   ztag:yaml.org,2002:mapc                       s<   e Zd ZdZdd„ Zd‡ fdd„	Zddd	„Zd
d„ Z‡  ZS )ÚSaneYamlDumperzYYamlDumper class usable for dumping ``OrderedDict`` and list instances in a standard way.c                 C   s   dS )zDisable YAML references.Tr   )r   Údatar   r   r   Úignore_aliases†   s    zSaneYamlDumper.ignore_aliasesFc                    s   t t| ƒjf |ddœ|—ŽS )zLhttps://stackoverflow.com/a/39681672

        Indent list elements.
        F)ÚflowÚ
indentless)r4   rC   Úincrease_indent)r   rF   rG   Úkwargsr6   r   r   rH   Š   s    zSaneYamlDumper.increase_indentNc                 C   sÆ   t }g }tj|||d�}| jdk	r.|| j| j< d}t|dƒrD| ¡ }|D ]V\}}|  |¡}	|  |¡}
t|	tj	ƒrv|	j
rzd}t|
tj	ƒrŒ|
j
r�d}| |	|
f¡ qH|dkrÂ| jdk	r¼| j|_n||_|S )zýhttps://gist.github.com/miracle2k/3184458

        Make PyYAML output an OrderedDict.

        It will do so fine if you use yaml.dump(), but that generates ugly, non-standard YAML code.

        To use yaml.safe_dump(), you need the following.
        )Ú
flow_styleNTÚitemsF)ÚYAML_MAP_TAGr   ZMappingNodeZ	alias_keyZrepresented_objectsÚhasattrrK   Zrepresent_datar   Z
ScalarNodeÚstyleÚappendÚdefault_flow_stylerJ   )r   ÚmappingrJ   ÚtagÚvalueÚnodeZ
best_styleZitem_keyZ
item_valueZnode_keyZ
node_valuer   r   r   Úrepresent_odict‘   s*    	





zSaneYamlDumper.represent_odictc                 C   s$   d|kr| j d|dd�S |   d|¡S )Nr=   ztag:yaml.org,2002:strú|)rN   )Zrepresent_scalar)r   Útextr   r   r   Úrepresent_text±   s    zSaneYamlDumper.represent_text)FF)N)	r-   r.   r/   Ú__doc__rE   rH   rU   rX   rB   r   r   r6   r   rC   ƒ   s
   
 rC   c                 C   s   t j| td|rdndd�S )a   Dump the given data dictionary into a sane format:

        * OrderedDicts are dumped as regular mappings instead of non-standard !!odict
        * multi-line mapping style instead of json-like inline style
        * list elements are indented into their parents
        * YAML references/aliases are disabled

    :param dict data: the data to be dumped
    :param bool binary: True to return a utf-8 encoded binary object, False to return a string
    :return: the serialized YAML
    :rtype: str or bytes
    Fzutf-8N)ZDumperrP   Úencoding)r   ÚdumprC   )rD   Úbinaryr   r   r   Úyaml_sane_dump½   s    r]   c                   @   s   e Zd Zddd„ZdS )ÚSaneYamlLoaderFc                 C   s   |   |¡ t|  |¡ƒS r   )Zflatten_mappingr   Zconstruct_pairs)r   rT   Údeepr   r   r   Úconstruct_odictÎ   s    
zSaneYamlLoader.construct_odictN)F)r-   r.   r/   r`   r   r   r   r   r^   Í   s   r^   c                 C   s   t j| td�S )z³Load the given YAML stream while preserving the input order for mapping items.

    :param stream: YAML stream (can be a string or a file-like object)
    :rtype: OrderedDict
    )ÚLoader)r   Úloadr^   )Ústreamr   r   r   Úyaml_sane_loadÖ   s    rd   c                       s*   e Zd ZdZd‡ fdd„	Zdd„ Z‡  ZS )ÚOpenAPICodecYamlúapplication/yamlc                    s   t t| ƒ |¡ || _d S r   )r4   re   r   r0   )r   r   r0   r6   r   r   r   â   s    zOpenAPICodecYaml.__init__c                 C   s   t |dd�S )z/Dump ``spec`` into YAML.

        :rtype: bytesT)r\   )r]   r,   r   r   r   r#   æ   s    zOpenAPICodecYaml._dump_dict)rf   rA   r   r   r6   r   re   ß   s   re   )&r   r>   ÚloggingÚcollectionsr   Zcoreapi.compatr   Zruamelr   Ú r   r%   r   Ú	getLoggerr-   r!   r   r   r   Úobjectr   r2   rL   Z
SafeDumperrC   Zadd_representerÚbytesrX   r   rU   Zadd_multi_representerr]   Z
SafeLoaderr^   Zadd_constructorr`   rd   re   r   r   r   r   Ú<module>   s4   
þ?4	