U
    d?                  
   @   s$  d dl Z zd dlmZ W n  ek
r8   d dlmZ Y nX d dlmZ d dlmZ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 G dd deZddddddddZdddddddZededededddiZ d Z!G d!d" d"e"Z#G d#d$ d$e"Z$d%d& Z%dS )'    N)Hashable)deepcopy)current_apprequest)	MultiDictFileStorage)
exceptions   )abort
SpecsError)marshal)Model)
HTTPStatusc                   @   s    e Zd ZdZdd Zdd ZdS )ParseResultz9
    The default result container as an Object dict.
    c                 C   s,   z
| | W S  t k
r&   t|Y nX d S N)KeyErrorAttributeError)selfname r   8/tmp/pip-unpacked-wheel-dt_sn2ih/flask_restx/reqparse.py__getattr__   s    
zParseResult.__getattr__c                 C   s   || |< d S r   r   )r   r   valuer   r   r   __setattr__   s    zParseResult.__setattr__N)__name__
__module____qualname____doc__r   r   r   r   r   r   r      s   r   zthe JSON bodyzthe post bodyzthe query stringz!the post body or the query stringzthe HTTP headerszthe request's cookieszan uploaded file)jsonformargsvaluesheaderscookiesfilesqueryformDataheaderbody)r    r   r"   r   r!   r$   integerstringbooleannumbervoid,c                   @   sd   e Zd ZdZddddedddddddddfd	d
Zdd Zdd Zdd ZdddZ	e
dd ZdS )Argumenta:  
    :param name: Either a name or a list of option strings, e.g. foo or -f, --foo.
    :param default: The value produced if the argument is absent from the request.
    :param dest: The name of the attribute to be added to the object
        returned by :meth:`~reqparse.RequestParser.parse_args()`.
    :param bool required: Whether or not the argument may be omitted (optionals only).
    :param string action: The basic type of action to be taken when this argument
        is encountered in the request. Valid options are "store" and "append".
    :param bool ignore: Whether to ignore cases where the argument fails type conversion
    :param type: The type to which the request argument should be converted.
        If a type raises an exception, the message in the error will be returned in the response.
        Defaults to  :class:`str`.
    :param location: The attributes of the :class:`flask.Request` object
        to source the arguments from (ex: headers, args, etc.), can be an
        iterator. The last item listed takes precedence in the result set.
    :param choices: A container of the allowable values for the argument.
    :param help: A brief description of the argument, returned in the
        response when the argument is invalid. May optionally contain
        an "{error_msg}" interpolation token, which will be replaced with
        the text of the error raised by the type converter.
    :param bool case_sensitive: Whether argument values in the request are
        case sensitive or not (this will convert all values to lowercase)
    :param bool store_missing: Whether the arguments default value should
        be stored if the argument is missing from the request.
    :param bool trim: If enabled, trims whitespace around the argument.
    :param bool nullable: If enabled, allows null value in argument.
    NF)r   r!   r   store)=Tc                 C   s^   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	|| _
|| _|| _|| _|| _d S r   )r   defaultdestrequiredignorelocationtypechoicesactionhelpcase_sensitive	operatorsstore_missingtrimnullable)r   r   r2   r3   r4   r5   r7   r6   r8   r9   r:   r<   r;   r=   r>   r?   r   r   r   __init___   s    zArgument.__init__c                 C   s   t | jtrP| jdkr$|jdd}nt|| jt }t|rB| }|dk	r|S nXt }| jD ]F}|dkrv|jdd}nt||d}t|r| }|dk	r\|| q\|S t S )z
        Pulls values off the request in the provided location
        :param request: The flask request object to parse arguments from
        >   r   get_jsonT)ZsilentN)
isinstancer6   strrA   getattrr   callableupdate)r   r   r   r!   lr   r   r   source   s&    

zArgument.sourcec                 C   s   |d kr| j stdd S t| jtr<t|tr<t|| jS t|trT| jtkrT|S z| || j|W S  t	k
r   z<| jt
jkr| t|| jW  Y S | || jW  Y S W n" t	k
r   | | Y  Y S X Y nX d S )NzMust not be null!)r?   
ValueErrorrB   r7   r   dictr   r   r   	TypeErrordecimalDecimalrC   )r   r   opr   r   r   convert   s"    zArgument.convertc                 C   sT   t |}| jr"dt | j|gn|}| j|i}|r@t||fS ttjd|d dS )ac  
        Called when an error is raised while parsing. Aborts the request
        with a 400 status and an error message

        :param error: the error that was raised
        :param bool bundle_errors: do not abort when first error occurs, return a
            dict with the name of the argument and the error message to be
            bundled
         Input payload validation failederrorsN)rC   r:   joinr   rI   r
   r   BAD_REQUEST)r   errorbundle_errorsZ	error_str	error_msgrS   r   r   r   handle_validation_error   s    

z Argument.handle_validation_errorc                    sp  t jddp|}|}g }d}d}jD ]v j ddd }||kr.t|drf||}n||g}|D ],}	t|	drj	r|	
 }	t|	d	rʈjs|	 }	tjd
rdd jD _z6jdkr fdd|	tD }	n|	 }	W nL tk
rL }
 z,jr$W Y qv|
| W Y 
    S d}
~
X Y nX jr|	jkrd|	|}||    S ||jkr|j| ||	 qvq.|sjrtjtrtjj}ndd jD }d|}d|}||S |s.tj r$  |fS j |fS jdkrB||fS jdks\t!|dkrh|d |fS ||fS )al  
        Parses argument value(s) from the request, converting according to
        the argument's type.

        :param request: The flask request object to parse arguments from
        :param bool bundle_errors: do not abort when first error occurs, return a
            dict with the name of the argument and the error message to be
            bundled
        ZBUNDLE_ERRORSFTr1    r	   getliststriplower__iter__c                 S   s   g | ]}|  qS r   )r]   ).0choicer   r   r   
<listcomp>   s     z"Argument.parse.<locals>.<listcomp>splitc                    s   g | ]} | qS r   )rO   )r_   voperatorr   r   r   ra      s   Nz0The value '{0}' is not a valid choice for '{1}'.c                 S   s   g | ]}t ||qS r   )_friendly_locationget)r_   locr   r   r   ra     s     z or z!Missing required parameter in {0}appendr0   r   )"r   configrg   rH   r<   r   replacehasattrr[   r>   r\   r;   r]   r8   r9   rb   
SPLIT_CHARrO   	Exceptionr5   rY   formatunparsed_argumentspopri   r4   rB   r6   rC   rf   rT   rE   r2   len)r   r   rW   rH   resultsZ
_not_foundZ_foundr   r!   r   rV   msgr6   	locationsrX   r   rd   r   parse   sj    




* 


zArgument.parsec                 C   s   | j dkrd S | jt| j dd}t| | | jr<d|d< | jrL| j|d< | jd k	rrt| jrh|  n| j|d< | j	dkrd	|d	 i|d
< d|kr|
d|d
 d< d|d	< d|d< | j	dkrd	|d	 i|d
< d|d	< d|d< | jr| j|d< |S )Ncookier%   )r   inTr4   descriptionr2   ri   r7   itemspatternarrayZmultiZcollectionFormatrb   csvenum)r6   r   	LOCATIONSrg   _handle_arg_typer4   r:   r2   rE   r9   rq   r8   )r   paramr   r   r   
__schema__  s0    






zArgument.__schema__)F)r   r   r   r   rC   r@   rH   rO   rY   rv   propertyr   r   r   r   r   r/   B   s,   
%
Rr/   c                   @   sX   e Zd ZdZeeddfddZdd Zddd	Zd
d Z	dd Z
dd Zedd ZdS )RequestParseraU  
    Enables adding and parsing of multiple arguments in the context of a single request.
    Ex::

        from flask_restx import RequestParser

        parser = RequestParser()
        parser.add_argument('foo')
        parser.add_argument('int_bar', type=int)
        args = parser.parse_args()

    :param bool trim: If enabled, trims whitespace on all arguments in this parser
    :param bool bundle_errors: If enabled, do not abort when first error occurs,
        return a dict with the name of the argument and the error message to be
        bundled and return all validation errors
    Fc                 C   s"   g | _ || _|| _|| _|| _d S r   )r    argument_classresult_classr>   rW   )r   r   r   r>   rW   r   r   r   r@   N  s
    zRequestParser.__init__c                 O   sl   t |dkr.t|d | jr.| j|d  n| j| j|| | jrh| jtkrh|d| j| jd _| S )a  
        Adds an argument to be parsed.

        Accepts either a single instance of Argument or arguments to be passed
        into :class:`Argument`'s constructor.

        See :class:`Argument`'s constructor for documentation on the available options.
        r	   r   r>   )rr   rB   r   r    ri   r>   r/   rg   )r   r    kwargsr   r   r   add_argument[  s    
zRequestParser.add_argumentNc           
      C   s   |dkrt }|  }|r,t| d|ni |_i }| jD ]H}||| j\}}t	|t
rj|| d}|st|jr<|||jp|j< q<|rttjd|d |r|jrd|j }d|}	t|	|S )aN  
        Parse all arguments from the provided request and return the results as a ParseResult

        :param bool strict: if req includes args not in parser, throw 400 BadRequest exception
        :return: the parsed results as :class:`ParseResult` (or any class defined as :attr:`result_class`)
        :rtype: ParseResult
        NrZ   rQ   rR   z, zUnknown arguments: {0})r   r   rJ   r   rH   rp   r    rv   rW   rB   rI   rF   r=   r3   r   r
   r   rU   rT   keysro   r   Z
BadRequest)
r   reqstrictresultrS   argr   found	argumentsrt   r   r   r   
parse_argsq  s0    



  


zRequestParser.parse_argsc                 C   s0   |  | j| j}t| j|_| j|_| j|_|S )zCCreates a copy of this RequestParser with the same set of arguments)	__class__r   r   r   r    r>   rW   )r   Zparser_copyr   r   r   copy  s
    zRequestParser.copyc                 O   sV   | j |f||}t| jdd D ],\}}|j|jkr$| j|= | j|  qRq$| S )z@Replace the argument matching the given name with a new version.N)r   	enumerater    r   ri   )r   r   r    r   Znew_argindexr   r   r   r   replace_argument  s    zRequestParser.replace_argumentc                 C   s6   t | jdd D ]\}}||jkr| j|=  q2q| S )z,Remove the argument matching the given name.N)r   r    r   )r   r   r   r   r   r   r   remove_argument  s
    
zRequestParser.remove_argumentc                 C   sT   g }t  }| jD ]&}|j}|r|| ||d  qd|krPd|krPtd|S )Nrx   r(   r&   z,Can't use formData and body at the same time)setr    r   ri   addr   )r   paramsru   r   r   r   r   r   r     s    

zRequestParser.__schema__)NF)r   r   r   r   r/   r   r@   r   r   r   r   r   r   r   r   r   r   r   r   <  s   

&
r   c                 C   s   t | jtr&| jtkr&t| j |d< n^t| jdrL| jjd |d< d|d< n8t| jdrh|| jj n| jdkr|d|d< nd	|d< d S )
Nr7   
__apidoc__r   r(   rx   r   r$   filer*   )	rB   r7   r   PY_TYPESrl   r   rF   r   r6   )r   r   r   r   r   r     s    


r   )&rL   collections.abcr   ImportErrorcollectionsr   r   Zflaskr   r   Zwerkzeug.datastructuresr   r   Zwerkzeugr   rS   r
   r   Zmarshallingr   modelr   Z_httpr   rJ   r   rf   r   intrC   boolfloatr   rm   objectr/   r   r   r   r   r   r   <module>   sZ         { 