U
    d2                     @   s   d dl Z d dlZd dl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lmZ ddlmZmZ dd	lmZmZmZ dd
lmZ ddlmZ eddZG dd deZdd Zdd ZdS )    N)
namedtupleOrderedDict)request)http_method_funcs   )
HTTPStatusabort)marshalmarshal_with)ModelOrderedModelSchemaModelRequestParser)mergeResourceRoutezresource urls route_doc kwargsc                   @   s  e Zd ZdZd=ddZedd Zdd	 Zd
d Zdd Z	d>ddZ
dd Zdd Zdd Zd?ddZd@ddZdd Zdd Zdd Zd d! Zd"d# Zd$d% Zdejdfd&d'Zd(d) Zd*d+ Zd,d- ZdAd/d0ZdBd1d2ZdCd3d4Zd5d6 Zd7d8 Z d9d: Z!ed;d< Z"dS )D	Namespaceak  
    Group resources together.

    Namespace is to API what :class:`flask:flask.Blueprint` is for :class:`flask:flask.Flask`.

    :param str name: The namespace name
    :param str description: An optional short description
    :param str path: An optional prefix path. If not provided, prefix is ``/+name``
    :param list decorators: A list of decorators to apply to each resources
    :param bool validate: Whether or not to perform validation on this namespace
    :param bool ordered: Whether or not to preserve order on models and marshalling
    :param Api api: an optional API to attache to the namespace
    NFc           	      K   s   || _ || _|| _d | _|| _i | _i | _|r2|ng | _g | _t	 | _
d | _|| _|| _g | _d|krv| j|d  ttd | j  | _d S )Napi.)namedescription_pathZ_schema	_validatemodelsurls
decorators	resourcesr   error_handlersdefault_error_handlerauthorizationsorderedapisappendlogging	getLogger__name__logger)	selfr   r   pathr   validater    r!   kwargs r,   9/tmp/pip-unpacked-wheel-dt_sn2ih/flask_restx/namespace.py__init__#   s"    zNamespace.__init__c                 C   s   | j pd| j dS )N/)r   r   rstripr(   r,   r,   r-   r)   A   s    zNamespace.pathc                 O   sR   | di }| jt|||| | jD ]$}|| |}|j| |f|| q(dS )a/  
        Register a Resource for a given API Namespace

        :param Resource resource: the resource ro register
        :param str urls: one or more url routes to match for the resource,
                         standard flask routing rules apply.
                         Any url variables will be passed to the resource method as args.
        :param str endpoint: endpoint name (defaults to :meth:`Resource.__name__.lower`
            Can be used to reference this route in :class:`fields.Url` fields
        :param list|tuple resource_class_args: args to be forwarded to the constructor of the resource.
        :param dict resource_class_kwargs: kwargs to be forwarded to the constructor of the resource.

        Additional keyword arguments not specified above will be passed as-is
        to :meth:`flask.Flask.add_url_rule`.

        Examples::

            namespace.add_resource(HelloWorld, '/', '/hello')
            namespace.add_resource(Foo, '/foo', endpoint="foo")
            namespace.add_resource(FooSpecial, '/special/foo', endpoint="foo")
        	route_docN)popr   r#   r   r"   ns_urlsZregister_resource)r(   resourcer   r+   r2   r   r4   r,   r,   r-   add_resourceE   s
    
zNamespace.add_resourcec                    s    fdd}|S )z1
        A decorator to route resources.
        c                    s:     dd }|d k	r$| | d< j| f  | S )Ndocr2   )r3   
_build_docr6   )clsr7   r+   r(   r   r,   r-   wrapperf   s
    z Namespace.route.<locals>.wrapperr,   )r(   r   r+   r;   r,   r:   r-   routea   s    zNamespace.routec                 C   s   |dkrdS t | t| tD ]j}||kr || dkr:q t ||  t||  d|| kr t|| d ttfs || d g|| d< q tt|di |S )NFexpect
__apidoc__)unshortcut_params_descriptionhandle_deprecationsr   
isinstancelisttupler   getattr)r(   r9   r7   Zhttp_methodr,   r,   r-   r8   p   s     
 zNamespace._build_docc                    s8   t |tr| d< t |tr |nd fdd}|S )zAA decorator to add some api documentation to the decorated objectidTc                    s    | r nd| _| S )NF)r8   r>   )Z
documentedr+   r(   showr,   r-   r;      s
     
zNamespace.doc.<locals>.wrapper)rA   strbool)r(   Zshortcutr+   r;   r,   rF   r-   r7      s
    
zNamespace.docc                 C   s   |  d|S )z>A decorator to hide a resource or a method from specificationsFr7   r(   funcr,   r,   r-   hide   s    zNamespace.hidec                 O   s   t || dS )zd
        Properly abort the current request

        See: :func:`~flask_restx.errors.abort`
        Nr   r(   argsr+   r,   r,   r-   r	      s    zNamespace.abortc                 C   s$   || j |< | jD ]}||j |< q|S N)r   r"   )r(   r   Z
definitionr   r,   r,   r-   	add_model   s    

zNamespace.add_modelc                 K   s6   | j r
tnt}|||||d}|j| | ||S )z
        Register a model

        :param bool strict - should model validation raise error when non-specified param
                             is provided?

        .. seealso:: :class:`Model`
        )maskstrict)r!   r   r   r>   updaterQ   )r(   r   modelrR   rS   r+   r9   r,   r,   r-   rU      s    	zNamespace.modelc                 C   s   t ||}| ||S )zG
        Register a model

        .. seealso:: :class:`Model`
        )r   rQ   )r(   r   ZschemarU   r,   r,   r-   schema_model   s    
zNamespace.schema_modelc                 C   s@   t |tr&||g }tj|f| }nt|||}| ||S )zr
        Extend a model (Duplicate all fields)

        :deprecated: since 0.9. Use :meth:`clone` instead
        )rA   rB   r   extendrQ   )r(   r   parentfieldsparentsrU   r,   r,   r-   rW      s
    

zNamespace.extendc                 G   s   t j|f| }| ||S )z
        Clone a model (Duplicate all fields)

        :param str name: the resulting model name
        :param specs: a list of models from which to clone the fields

        .. seealso:: :meth:`Model.clone`

        )r   clonerQ   r(   r   specsrU   r,   r,   r-   r[      s    
zNamespace.clonec                 G   s   t j|f| }| ||S )z~
        Inherit a model (use the Swagger composition pattern aka. allOf)

        .. seealso:: :meth:`Model.inherit`
        )r   inheritrQ   r\   r,   r,   r-   r^      s    zNamespace.inheritc                 O   s8   g }| d| j|d}|D ]}|| q| jf |S )z
        A decorator to Specify the expected input model

        :param ModelBase|Parse inputs: An expect model or request parser
        :param bool validate: whether to perform validation or not

        r*   )r*   r=   )getr   r#   r7   )r(   inputsr+   r=   paramsparamr,   r,   r-   r=      s
    zNamespace.expectc                 C   s   t  S )z%Instanciate a :class:`~RequestParser`r   r1   r,   r,   r-   parser   s    zNamespace.parserc                 C   s   t t|di ddi|_|S )z/Allow to specify nested lists for documentationr>   as_listT)r   rD   r>   )r(   fieldr,   r,   r-   rd      s    zNamespace.as_listc                    s    fdd}|S )a  
        A decorator specifying the fields to use for serialization.

        :param bool as_list: Indicate that the return type is a list (for the documentation)
        :param int code: Optionally give the expected HTTP response code if its different from 200

        c                    s^   t  rgfnfiddd}tt| di || _tfdji| S )NrR   T)	responsesZ__mask__r>   r!   )rH   r_   r   rD   r>   r   r!   )rL   r7   rd   coder   rY   r+   r(   r,   r-   r;      s     
z'Namespace.marshal_with.<locals>.wrapperr,   )r(   rY   rd   rh   r   r+   r;   r,   rg   r-   r      s    zNamespace.marshal_withc                 K   s   | j |df|S )zHA shortcut decorator for :meth:`~Api.marshal_with` with ``as_list=True``T)r   )r(   rY   r+   r,   r,   r-   marshal_list_with  s    zNamespace.marshal_list_withc                 O   s
   t ||S )z(A shortcut to the :func:`marshal` helper)r
   rN   r,   r,   r-   r
     s    zNamespace.marshalc                    s4   t  r&t tr& fdd}|S  _ S dS )z>A decorator to register an error handler for a given exceptionc                    s   | j  < | S rP   )r   )rL   	exceptionr(   r,   r-   r;     s    
z'Namespace.errorhandler.<locals>.wrapperN)inspectisclass
issubclass	Exceptionr   )r(   rk   r;   r,   rj   r-   errorhandler  s
    zNamespace.errorhandlerqueryc                 K   s$   |}||d< ||d< | j ||idS )z
        A decorator to specify one of the expected parameters

        :param str name: the parameter name
        :param str description: a small description
        :param str _in: the parameter location `(query|header|formData|body|cookie)`
        inr   )ra   rJ   )r(   r   r   Z_inr+   rb   r,   r,   r-   rb   #  s    zNamespace.paramc                 K   s   | j t||||fidS )z
        A decorator to specify one of the expected responses

        :param int code: the HTTP status code
        :param str description: a small description about the response
        :param ModelBase model: an optional response model

        )rf   )r7   rH   )r(   rh   r   rU   r+   r,   r,   r-   response0  s    	zNamespace.responsec                 K   s"   d|i}| | | j||idS )z
        A decorator to specify one of the expected headers

        :param str name: the HTTP header name
        :param str description: a description about the header

        r   )headersrT   r7   )r(   r   r   r+   headerr,   r,   r-   rv   ;  s    
zNamespace.headerc                 C   s   | j |dS )z9A decorator to specify the MIME types the API can produce)producesrJ   )r(   	mimetypesr,   r,   r-   rw   G  s    zNamespace.producesc                 C   s   | j dd|S )z8A decorator to mark a resource or a method as deprecatedT)
deprecatedrJ   rK   r,   r,   r-   ry   K  s    zNamespace.deprecatedc                 O   s    |D ]}| | q| j|dS )a  
        A decorator to expose vendor extensions.

        Extensions can be submitted as dict or kwargs.
        The ``x-`` prefix is optionnal and will be added if missing.

        See: http://swagger.io/specification/#specification-extensions-128
        )vendorru   )r(   rO   r+   argr,   r,   r-   rz   O  s    	zNamespace.vendorc                 C   s   t  S )z6Store the input payload in the current request context)r   Zget_jsonr1   r,   r,   r-   payload\  s    zNamespace.payload)NNNNNF)N)NNNF)NN)Nrq   )N)N)#r&   
__module____qualname____doc__r.   propertyr)   r6   r<   r8   r7   rM   r	   rQ   rU   rV   rW   r[   r^   r=   rc   rd   r   OKr   ri   r
   rp   rb   rs   rv   rw   ry   rz   r|   r,   r,   r,   r-   r      sP         




		  



r   c                 C   s<   d| kr8| d   D ]"\}}t|trd|i| d |< qd S )Nra   r   )itemsrA   rH   )datar   r   r,   r,   r-   r?   b  s    
r?   c                 C   sl   d| kr4t jdtdd | dg | dg | d< d| krht jdtdd | dg | dg | d< d S )Nrc   z6The parser attribute is deprecated, use expect instead   )
stacklevelr=   bodyz4The body attribute is deprecated, use expect instead)warningswarnDeprecationWarningr_   r3   rJ   r,   r,   r-   r@   i  s    r@   )rl   r   r$   collectionsr   r   Zflaskr   Zflask.viewsr   Z_httpr   errorsr	   Zmarshallingr
   r   rU   r   r   r   Zreqparser   utilsr   r   objectr   r?   r@   r,   r,   r,   r-   <module>   s"   
  P