3
Ah`;                 @   s   d 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 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 Zdd Zdd ZejdZG dd dZG dd dZdS )z]
generators.py   # Top-down schema generation

See schemas.__init__.py for package overview.
    N)import_module)settings)simplify_regex)PermissionDenied)Http404)
URLPatternURLResolver)
exceptions)clone_request)api_settings)_get_pkc             C   s   | j jj }t|jS )N)Z_metaZconcrete_modelr   name)modelmeta r   P/tmp/pip-build-9m32_hle/djangorestframework/rest_framework/schemas/generators.pyget_pk_name   s    
r   c             C   s*   ddl m} t| dd}|dk	o(t||S )zT
    Return `True` if the given view callback is a REST framework view/viewset.
    r   )APIViewclsN)Zrest_framework.viewsr   getattr
issubclass)callbackr   r   r   r   r   is_api_view   s    r   c             C   s(   | \}}}ddddddj |d}|fS )Nr               )GETPOSTPUTPATCHDELETE   )get)endpointpathmethodr   Zmethod_priorityr   r   r   endpoint_ordering$   s    
r'   z/<(?:(?P<converter>[^>:]+):)?(?P<parameter>\w+)>c               @   s<   e Zd ZdZdddZdddZdd	 Zd
d Zdd ZdS )EndpointEnumeratorzR
    A class to determine the available API endpoints that a project exposes.
    Nc             C   s>   |d kr4|d krt j}t|tr*t|}n|}|j}|| _d S )N)r   ZROOT_URLCONF
isinstancestrr   Zurlpatternspatterns)selfr+   urlconfurlsr   r   r   __init__9   s    

zEndpointEnumerator.__init__ c             C   s   |dkr| j }g }x|D ]}|t|j }t|trz| j|}|j}| j||rxL| j|D ]}|||f}	|j	|	 q\W qt|t
r| j|j|d}
|j|
 qW t|tdS )zZ
        Return a list of all available API endpoints by inspecting the URL conf.
        N)r+   prefix)key)r+   r*   patternr)   r   get_path_from_regexr   should_include_endpointget_allowed_methodsappendr   get_api_endpointsZurl_patternsextendsortedr'   )r,   r+   r1   Zapi_endpointsr3   
path_regexr%   r   r&   r$   Znested_endpointsr   r   r   r8   H   s$    




z$EndpointEnumerator.get_api_endpointsc             C   s   t |}tjtd|S )zG
        Given a URL conf regex, return a URI template string.
        z{\g<parameter>})r   resub_PATH_PARAMETER_COMPONENT_RE)r,   r;   r%   r   r   r   r4   d   s    z&EndpointEnumerator.get_path_from_regexc             C   sT   t |sdS |jjdkrdS d|jkr8|jd dkr8dS |jdsL|jdrPdS dS )zI
        Return `True` if the given endpoint should be included.
        FNschemaz	.{format}z
.{format}/T)r   r   r?   
initkwargsendswith)r,   r%   r   r   r   r   r5   q   s    
z*EndpointEnumerator.should_include_endpointc             C   sL   t |dr4t|j}t|jj}dd ||@ D }n
|j j}dd |D S )zL
        Return a list of the valid HTTP methods for this endpoint.
        actionsc             S   s   g | ]}|j  qS r   )upper).0r&   r   r   r   
<listcomp>   s    z:EndpointEnumerator.get_allowed_methods.<locals>.<listcomp>c             S   s   g | ]}|dkr|qS )OPTIONSHEAD)rF   rG   r   )rD   r&   r   r   r   rE      s    )hasattrsetrB   r   http_method_namesZallowed_methods)r,   r   rB   rJ   methodsr   r   r   r6      s    


z&EndpointEnumerator.get_allowed_methods)NN)Nr0   )	__name__
__module____qualname____doc__r/   r8   r4   r5   r6   r   r   r   r   r(   5   s   

r(   c               @   sR   e Zd ZeZdZdddZdd Zdd Zddd	Z	d
d Z
dddZdd ZdS )BaseSchemaGeneratorNc             C   sN   |r|j d r|d7 }tj| _|| _|| _|| _|| _|| _|| _	d | _
d S )N/)rA   r   ZSCHEMA_COERCE_PATH_PKcoerce_path_pkr+   r-   titledescriptionversionurl	endpoints)r,   rS   rV   rT   r+   r-   rU   r   r   r   r/      s    zBaseSchemaGenerator.__init__c             C   s(   | j d kr$| j| j| j}|j | _ d S )N)rW   endpoint_inspector_clsr+   r-   r8   )r,   Z	inspectorr   r   r   _initialise_endpoints   s    
z)BaseSchemaGenerator._initialise_endpointsc             C   s\   g }g }xJ| j D ]@\}}}| j|||}| j|||}|j| |j|||f qW ||fS )zY
        Generate (path, method, view) given (path, method, callback) for paths.
        )rW   create_viewcoerce_pathr7   )r,   requestpathsZview_endpointsr%   r&   r   viewr   r   r   _get_paths_and_endpoints   s    
z,BaseSchemaGenerator._get_paths_and_endpointsc             C   s   |j f t|di }f |_i |_d|_d|_t|dd|_t|dd}|dk	rn|dkr^d|_n|j|j	 |_|dk	rt
|||_|S )zC
        Given a callback, return an actual view instance.
        r@   NrB   rF   metadata)r   r   argskwargsZformat_kwargr\   Z
action_mapactionr#   lowerr
   )r,   r   r&   r\   r^   rB   r   r   r   rZ      s    zBaseSchemaGenerator.create_viewc             C   sJ   | j  sd|kr|S tt|dddd}|r6t|}nd}|jdd| S )z
        Coerce {pk} path arguments into the name of the model field,
        where possible. This is cleaner for an external representation.
        (Ie. "this is an identifier", not "this is a database primary key")
        z{pk}ZquerysetNr   idz{%s})rR   r   r   replace)r,   r%   r&   r^   r   
field_namer   r   r   r[      s    
zBaseSchemaGenerator.coerce_pathFc             C   s   t dd S )Nz0.get_schema() must be implemented in subclasses.)NotImplementedError)r,   r\   publicr   r   r   
get_schema   s    zBaseSchemaGenerator.get_schemac             C   s@   |j dkrdS y|j|j  W n tjttfk
r:   dS X dS )zY
        Return `True` if the incoming request has the correct view permissions.
        NTF)r\   Zcheck_permissionsr	   ZAPIExceptionr   r   )r,   r%   r&   r^   r   r   r   has_view_permissions   s    
z(BaseSchemaGenerator.has_view_permissions)NNNNNN)N)NF)rL   rM   rN   r(   rX   rR   r/   rY   r_   rZ   r[   rj   rk   r   r   r   r   rP      s   


rP   )rO   r<   	importlibr   Zdjango.confr   Zdjango.contrib.admindocs.viewsr   Zdjango.core.exceptionsr   Zdjango.httpr   Zdjango.urlsr   r   Zrest_frameworkr	   Zrest_framework.requestr
   Zrest_framework.settingsr   Zrest_framework.utils.model_metar   r   r   r'   compiler>   r(   rP   r   r   r   r   <module>   s$   
]