U
    nËj=  ã                   @  sÈ   d dl mZ 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
mZmZmZ zd dlZW n ek
rx   dZY nX G dd„ deƒZG dd	„ d	ejƒZe d
¡ZG dd„ dƒZG dd„ deƒZdS )é    )ÚannotationsN)ÚRequest)ÚResponse)Ú	BaseRouteÚHostÚMountÚRoutec                   @  s    e Zd ZdZdddœdd„ZdS )ÚOpenAPIResponsezapplication/vnd.oai.openapiz
typing.AnyÚbytes)ÚcontentÚreturnc                 C  s6   t d k	stdƒ‚t|tƒs"tdƒ‚t j|dd� d¡S )Nz2`pyyaml` must be installed to use OpenAPIResponse.z<The schema passed to OpenAPIResponse should be a dictionary.F)Zdefault_flow_stylezutf-8)ÚyamlÚAssertionErrorÚ
isinstanceÚdictÚdumpÚencode)Úselfr   © r   ú5/tmp/pip-unpacked-wheel-pzfrzqh9/starlette/schemas.pyÚrender   s    zOpenAPIResponse.renderN)Ú__name__Ú
__module__Ú__qualname__Ú
media_typer   r   r   r   r   r	      s   r	   c                   @  s&   e Zd ZU ded< ded< ded< dS )ÚEndpointInfoÚstrÚpathÚhttp_methodú typing.Callable[..., typing.Any]ÚfuncN)r   r   r   Ú__annotations__r   r   r   r   r      s   
r   z:\w+}c                   @  s\   e Zd Zdddœdd„Zdddœdd„Zd	d	d
œdd„Zdddœdd„Zdddœdd„ZdS )ÚBaseSchemaGeneratorúlist[BaseRoute]údict[str, typing.Any]©Úroutesr   c                 C  s
   t ƒ ‚d S ©N)ÚNotImplementedError)r   r&   r   r   r   Ú
get_schema$   s    zBaseSchemaGenerator.get_schemazlist[EndpointInfo]c                   s   g }|D �]}t |ttfƒrf|jp$g }t |tƒr>|  |j¡‰ nd‰ ‡ fdd„|  |¡D ƒ}| |¡ qt |tƒr|j	szqqt
 |j¡s’t
 |j¡rÔ|  |j¡‰ |jp¨dgD ]&}|dkr¸qª| tˆ | ¡ |jƒ¡ qªq|  |j¡‰ dD ]4}t|j|ƒsöqät|j|ƒ}| tˆ | ¡ |ƒ¡ qäq|S )a
  
        Given the routes, yields the following information:

        - path
            eg: /users/
        - http_method
            one of 'get', 'post', 'put', 'patch', 'delete', 'options'
        - func
            method ready to extract the docstring
        Ú c                   s*   g | ]"}t d  ˆ |jf¡|j|jd�‘qS )r*   )r   r   r    )r   Újoinr   r   r    )Ú.0Zsub_endpoint©r   r   r   Ú
<listcomp>;   s   ûýz5BaseSchemaGenerator.get_endpoints.<locals>.<listcomp>ÚGETÚHEAD)ÚgetÚpostÚputÚpatchÚdeleteÚoptions)r   r   r   r&   Ú_remove_converterr   Úget_endpointsÚextendr   Zinclude_in_schemaÚinspectÚ
isfunctionÚendpointÚismethodÚmethodsÚappendr   ÚlowerÚhasattrÚgetattr)r   r&   Úendpoints_infoZrouteZsub_endpointsÚmethodr    r   r-   r   r8   '   s4    



úz!BaseSchemaGenerator.get_endpointsr   )r   r   c                 C  s   t  d|¡S )zì
        Remove the converter from the path.
        For example, a route like this:
            Route("/users/{id:int}", endpoint=get_user, methods=["GET"])
        Should be represented as `/users/{id}` in the OpenAPI schema.
        Ú})Ú_remove_converter_patternÚsub)r   r   r   r   r   r7   X   s    z%BaseSchemaGenerator._remove_converterr   )Úfunc_or_methodr   c                 C  sH   |j }|si S tdk	stdƒ‚| d¡d }t |¡}t|tƒsDi S |S )z`
        Given a function, parse the docstring as YAML and return a dictionary of info.
        Nz2`pyyaml` must be installed to use parse_docstring.z---éÿÿÿÿ)Ú__doc__r   r   ÚsplitZ	safe_loadr   r   )r   rH   Z	docstringÚparsedr   r   r   Úparse_docstringa   s    

z#BaseSchemaGenerator.parse_docstringr   r   )Úrequestr   c                 C  s   |j j}| j|d�}t|ƒS )N)r&   )Zappr&   r)   r	   )r   rN   r&   Úschemar   r   r   r	   y   s    z#BaseSchemaGenerator.OpenAPIResponseN)r   r   r   r)   r8   r7   rM   r	   r   r   r   r   r"   #   s
   1	r"   c                   @  s,   e Zd Zdddœdd„Zdddœdd	„Zd
S )ÚSchemaGeneratorr$   ÚNone)Úbase_schemar   c                 C  s
   || _ d S r'   )rR   )r   rR   r   r   r   Ú__init__€   s    zSchemaGenerator.__init__r#   r%   c                 C  sp   t | jƒ}| di ¡ |  |¡}|D ]F}|  |j¡}|s:q$|j|d krVi |d |j< ||d |j |j< q$|S )NÚpaths)r   rR   Ú
setdefaultr8   rM   r    r   r   )r   r&   rO   rC   r<   rL   r   r   r   r)   ƒ   s    

zSchemaGenerator.get_schemaN)r   r   r   rS   r)   r   r   r   r   rP      s   rP   )Ú
__future__r   r:   ÚreÚtypingZstarlette.requestsr   Zstarlette.responsesr   Zstarlette.routingr   r   r   r   r   ÚModuleNotFoundErrorr	   Ú
NamedTupler   ÚcompilerF   r"   rP   r   r   r   r   Ú<module>   s   
	
\