o
    ÞháR  ã                   @   sÄ   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
 eƒ Ze e¡Zdd„ Zddd	„ZG d
d„ dƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZdS )é    N)Úserializersé   )Úopenapi)Úforce_real_strÚget_field_defaultÚget_object_classesÚis_list_viewc                 C   sJ   t | |ƒ}t |¡rt |dd ƒr|dfS ddlm} |t|| |d ƒtƒfS )NÚ__self__Tr   )Úgetattr_static)ÚgetattrÚinspectÚismethodr
   Ú
isinstanceÚstaticmethod)Úcls_or_instanceÚmethod_nameÚmethodr
   © r   úX/var/www/html/premium_crap/venv/lib/python3.10/site-packages/drf_yasg/inspectors/base.pyÚis_callable_method   s
   
r   c                 C   sn   t | |ƒr)zt| |ƒ\}}|r|ƒ W S W n ty(   tjdt| ƒjdd� Y nw |r5t | |ƒr5t| |ƒS |S )aþ  Call a view method which might throw an exception. If an exception is thrown, log an informative error message
    and return the value of fallback_attr, or default if not present. The method must be callable without any arguments
    except cls or self.

    :param view: view class or instance; if a class is passed, instance methods won't be called
    :type view: rest_framework.views.APIView or type[rest_framework.views.APIView]
    :param str method_name: name of a method on the view
    :param str fallback_attr: name of an attribute on the view to fall back on, if calling the method fails
    :param default: default value if all else fails
    :return: view method's return value, or value of view's fallback_attr, or default
    :rtype: any or None
    z…view's %s raised exception during schema generation; use `getattr(self, 'swagger_fake_view', False)` to detect and short-circuit thisT)Úexc_info)Úhasattrr   Ú	ExceptionÚloggerÚwarningÚtypeÚ__name__r   )Úviewr   Úfallback_attrÚdefaultÚview_methodÚis_callabaler   r   r   Úcall_view_method   s   
ÿ

þÿ
r"   c                   @   s6   e Zd Zdd„ Zdd„ Zddd„Zdd	„ Zd
d„ ZdS )ÚBaseInspectorc                 C   s"   || _ || _|| _|| _|| _dS )aš  
        :param rest_framework.views.APIView view: the view associated with this endpoint
        :param str path: the path component of the operation URL
        :param str method: the http method of the operation
        :param openapi.ReferenceResolver components: referenceable components
        :param rest_framework.request.Request request: the request made against the schema view; can be None
        N)r   Úpathr   Ú
componentsÚrequest)Úselfr   r$   r   r%   r&   r   r   r   Ú__init__7   s
   
zBaseInspector.__init__c                 K   s   |S )ap  After an inspector handles an object (i.e. returns a value other than :data:`.NotHandled`), all inspectors
        that were probed get the chance to alter the result, in reverse order. The inspector that handled the object
        is the first to receive a ``process_result`` call with the object it just returned.

        This behavior is similar to the Django request/response middleware processing.

        If this inspector has no post-processing to do, it should just ``return result`` (the default implementation).

        :param result: the return value of the winning inspector, or ``None`` if no inspector handled the object
        :param str method_name: name of the method that was called on the inspector
        :param obj: first argument passed to inspector method
        :param kwargs: additional arguments passed to inspector method
        :return:
        r   )r'   Úresultr   ÚobjÚkwargsr   r   r   Úprocess_resultE   s   zBaseInspector.process_resultNc           
      K   sÔ   |pi }g }|D ]C}t  |¡sJ dƒ‚t|tƒsJ dƒ‚|| j| j| j| j| jfi |¤Ž}| 	|¡ t
||dƒ}|du r=q||fi |¤Ž}	|	turK nqt d|||¡ d}	t|ƒD ]}|j|	||fi |¤Ž}	qZ|	S )af  Probe a list of inspectors with a given object. The first inspector in the list to return a value that
        is not :data:`.NotHandled` wins.

        :param list[type[BaseInspector]] inspectors: list of inspectors to probe
        :param str method_name: name of the target method on the inspector
        :param obj: first argument to inspector method
        :param dict initkwargs: extra kwargs for instantiating inspector class
        :param kwargs: additional arguments to inspector method
        :return: the return value of the winning inspector, or ``None`` if no inspector handled the object
        z(inspector must be a class, not an objectz&inspectors must subclass BaseInspectorNz@%s ignored because no inspector in %s handled it (operation: %s))r   ÚisclassÚ
issubclassr#   r   r$   r   r%   r&   Úappendr   Ú
NotHandledr   r   Úreversedr,   )
r'   Ú
inspectorsr   r*   Ú
initkwargsr+   Útried_inspectorsÚ	inspectorr   r)   r   r   r   Úprobe_inspectorsV   s*   "
ÿÿzBaseInspector.probe_inspectorsc                 C   ó   t t| jddg ƒƒS )z¯Get the renderer classes of this view by calling `get_renderers`.

        :return: renderer classes
        :rtype: list[type[rest_framework.renderers.BaseRenderer]]
        Úget_renderersÚrenderer_classes©r   r"   r   ©r'   r   r   r   Úget_renderer_classes{   ó   z"BaseInspector.get_renderer_classesc                 C   r7   )z¥Get the parser classes of this view by calling `get_parsers`.

        :return: parser classes
        :rtype: list[type[rest_framework.parsers.BaseParser]]
        Úget_parsersÚparser_classesr:   r;   r   r   r   Úget_parser_classesƒ   r=   z BaseInspector.get_parser_classes©N)r   Ú
__module__Ú__qualname__r(   r,   r6   r<   r@   r   r   r   r   r#   6   s    
%r#   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚPaginatorInspectorz�Base inspector for paginators.

    Responsible for determining extra query parameters and response structure added by given paginators.
    c                 C   ó   t S )a  Get the pagination parameters for a single paginator **instance**.

        Should return :data:`.NotHandled` if this inspector does not know how to handle the given `paginator`.

        :param BasePagination paginator: the paginator
        :rtype: list[openapi.Parameter]
        ©r0   )r'   Ú	paginatorr   r   r   Úget_paginator_parameters’   ó   z+PaginatorInspector.get_paginator_parametersc                 C   rE   )ad  Add appropriate paging fields to a response :class:`.Schema`.

        Should return :data:`.NotHandled` if this inspector does not know how to handle the given `paginator`.

        :param BasePagination paginator: the paginator
        :param openapi.Schema response_schema: the response schema that must be paged.
        :rtype: openapi.Schema
        rF   )r'   rG   Úresponse_schemar   r   r   Úget_paginated_responseœ   ó   	z)PaginatorInspector.get_paginated_responseN)r   rB   rC   Ú__doc__rH   rK   r   r   r   r   rD   Œ   s    
rD   c                   @   s   e Zd ZdZdd„ ZdS )ÚFilterInspectorz€Base inspector for filter backends.

    Responsible for determining extra query parameters added by given filter backends.
    c                 C   rE   )a.  Get the filter parameters for a single filter backend **instance**.

        Should return :data:`.NotHandled` if this inspector does not know how to handle the given `filter_backend`.

        :param BaseFilterBackend filter_backend: the filter backend
        :rtype: list[openapi.Parameter]
        rF   )r'   Úfilter_backendr   r   r   Úget_filter_parameters®   rI   z%FilterInspector.get_filter_parametersN)r   rB   rC   rM   rP   r   r   r   r   rN   ¨   s    rN   c                       s@   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Z‡  Z	S )ÚFieldInspectorz6Base inspector for serializers and serializer fields. c                    s"   t t| ƒ |||||¡ || _d S rA   )ÚsuperrQ   r(   Úfield_inspectors)r'   r   r$   r   r%   r&   rS   ©Ú	__class__r   r   r(   ¼   s   
zFieldInspector.__init__c                 C   sB   t |ddƒ}t |di ƒ}|r| ¡ D ]\}}t|||ƒ qdS dS )aV  Set fields from the ``swagger_schema_fields`` attribute on the Meta class. This method is called
        only for serializers or fields that are converted into ``openapi.Schema`` objects.

        :param serializer_or_field: serializer or field instance
        :param openapi.Schema schema: the schema object to be modified in-place
        ÚMetaNÚswagger_schema_fields)r   ÚitemsÚsetattr)r'   Úserializer_or_fieldÚschemaÚmetarW   ÚattrÚvalr   r   r   Úadd_manual_fieldsÀ   s   þz FieldInspector.add_manual_fieldsc                 K   rE   )a  Convert a drf Serializer or Field instance into a Swagger object.

        Should return :data:`.NotHandled` if this inspector does not know how to handle the given `field`.

        :param rest_framework.serializers.Field field: the source field
        :param type[openapi.SwaggerDict] swagger_object_type: should be one of Schema, Parameter, Items
        :param bool use_references: if False, forces all objects to be declared inline
           instead of by referencing other components
        :param kwargs: extra attributes for constructing the object;
           if swagger_object_type is Parameter, ``name`` and ``in_`` should be provided
        :return: the swagger object
        :rtype: openapi.Parameter or openapi.Items or openapi.Schema or openapi.SchemaRef
        rF   ©r'   ÚfieldÚswagger_object_typeÚuse_referencesr+   r   r   r   Úfield_to_swagger_objectÍ   s   z&FieldInspector.field_to_swagger_objectc                 K   s&   | j | jd|d| jif||dœ|¤ŽS )zþHelper method for recursively probing `field_inspectors` to handle a given field.

        All arguments are the same as :meth:`.field_to_swagger_object`.

        :rtype: openapi.Parameter or openapi.Items or openapi.Schema or openapi.SchemaRef
        rd   rS   )rb   rc   ©r6   rS   r`   r   r   r   Úprobe_field_inspectorsÝ   s   ÿþþz%FieldInspector.probe_field_inspectorsc                    s¶   ˆt jt jt jfv sJ ‚tˆt jƒrJ dƒ‚ˆjrtˆjƒnd‰ˆt jkr'ˆnd‰tˆddƒ}|r5t|ƒnd‰ ˆt jkr>ˆ nd‰ d‡ ‡‡‡‡‡fdd„	}ˆt jkrTt jnt j}||fS )a[  Helper method to extract generic information from a field and return a partial constructor for the
        appropriate openapi object.

        All arguments are the same as :meth:`.field_to_swagger_object`.

        The return value is a tuple consisting of:

        * a function for constructing objects of `swagger_object_type`; its prototype is: ::

            def SwaggerType(existing_object=None, **instance_kwargs):

          This function creates an instance of `swagger_object_type`, passing the following attributes to its init,
          in order of precedence:

            - arguments specified by the ``kwargs`` parameter of :meth:`._get_partial_types`
            - ``instance_kwargs`` passed to the constructor function
            - ``title``, ``description``, ``required``, ``x-nullable`` and ``default`` inferred from the field,
              where appropriate

          If ``existing_object`` is not ``None``, it is updated instead of creating a new object.

        * a type that should be used for child objects if `field` is of an array type. This can currently have two
          values:

            - :class:`.Schema` if `swagger_object_type` is :class:`.Schema`
            - :class:`.Items` if `swagger_object_type` is  :class:`.Parameter` or :class:`.Items`

        :rtype: (function,type[openapi.Schema] or type[openapi.Items])
        z,passed field is already a SwaggerDict objectNÚ	help_textTc                    s  d|vrˆt jkrˆj|d< d|vr&ˆt jkr&tˆƒ}|d tjfvr&||d< |r7| dd ¡t jkr7| 	dˆ¡ ˆ d urA| 	dˆ ¡ t
ˆdd ƒrKd|d< | ˆ¡ | d urot| ˆƒs[J ‚t| ¡ ƒD ]
\}}t| ||ƒ qa| }nˆd	i |¤Ž}ˆt jkr�ˆ ˆ|¡ |S )
NÚrequiredr   r   ÚtitleÚdescriptionÚ
allow_nullTÚ
x_nullabler   )r   Ú	Parameterrh   ÚItemsr   r   ÚemptyÚgetÚ
TYPE_ARRAYÚ
setdefaultr   Úupdater   ÚsortedrX   rY   ÚSchemar_   )Úexisting_objectÚuse_field_titleÚinstance_kwargsr   Úkeyr^   r)   ©rj   ra   r+   r'   rb   ri   r   r   ÚSwaggerType  s,   


z6FieldInspector._get_partial_types.<locals>.SwaggerType)NT)	r   ru   rm   rn   r   ÚSwaggerDictÚlabelr   r   )r'   ra   rb   rc   r+   rg   r{   Úchild_swagger_typer   rz   r   Ú_get_partial_typesé   s   "z!FieldInspector._get_partial_types)
r   rB   rC   rM   r(   r_   rd   rf   r   Ú__classcell__r   r   rT   r   rQ   ¹   s    rQ   c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚSerializerInspectorc                 C   rE   )a-  Convert a DRF Serializer instance to an :class:`.openapi.Schema`.

        Should return :data:`.NotHandled` if this inspector does not know how to handle the given `serializer`.

        :param serializers.BaseSerializer serializer: the ``Serializer`` instance
        :rtype: openapi.Schema
        rF   ©r'   Ú
serializerr   r   r   Ú
get_schema6  rI   zSerializerInspector.get_schemac                 C   rE   )a�  Convert a DRF serializer into a list of :class:`.Parameter`\ s.

        Should return :data:`.NotHandled` if this inspector does not know how to handle the given `serializer`.

        :param serializers.BaseSerializer serializer: the ``Serializer`` instance
        :param str in_: the location of the parameters, one of the `openapi.IN_*` constants
        :rtype: list[openapi.Parameter]
        rF   ©r'   rƒ   Úin_r   r   r   Úget_request_parameters@  rL   z*SerializerInspector.get_request_parametersN)r   rB   rC   r„   r‡   r   r   r   r   r�   5  s    
r�   c                       sŒ   e Zd ZdZdZdZg Zg Zg Z‡ fdd„Z	dd„ Z
dd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )ÚViewInspector)ÚPUTÚPATCHÚPOSTÚDELETE)r‰   rŠ   r‹   )ÚGETc                    s@   t t| ƒ |||||¡ || _|  d¡ |  d¡ |  d¡ dS )zì
        Inspector class responsible for providing :class:`.Operation` definitions given a view, path and method.

        :param dict overrides: manual overrides as passed to :func:`@swagger_auto_schema <.swagger_auto_schema>`
        rS   Úfilter_inspectorsÚpaginator_inspectorsN)rR   rˆ   r(   Ú	overridesÚ_prepend_inspector_overrides)r'   r   r$   r   r%   r&   r�   rT   r   r   r(   Z  s
   

zViewInspector.__init__c                    sB   | j  |d ¡‰ ˆ r‡ fdd„t| |ƒD ƒ}t| |ˆ | ƒ d S d S )Nc                    s   g | ]}|ˆ vr|‘qS r   r   )Ú.0Úinsp©Úextra_inspectorsr   r   Ú
<listcomp>i  s    z>ViewInspector._prepend_inspector_overrides.<locals>.<listcomp>)r�   rp   r   rY   )r'   r2   Údefault_inspectorsr   r”   r   r‘   f  s
   þz*ViewInspector._prepend_inspector_overridesc                 C   s   t dƒ‚)aw  Get an :class:`.Operation` for the given API endpoint (path, method).
        This includes query, body parameters and response schemas.

        :param tuple[str] operation_keys: an array of keys describing the hierarchical layout of this view in the API;
          e.g. ``('snippets', 'list')``, ``('snippets', 'retrieve')``, etc.
        :rtype: openapi.Operation
        z-ViewInspector must implement get_operation()!)ÚNotImplementedError)r'   Úoperation_keysr   r   r   Úget_operationl  s   zViewInspector.get_operationc                 C   s   t | j| j| jƒS )aÁ  Determine whether this view is a list or a detail view. The difference between the two is that
        detail views depend on a pk/id path parameter. Note that a non-detail view does not necessarily imply a list
        response (:meth:`.has_list_response`), nor are list responses limited to non-detail views.

        For example, one might have a `/topic/<pk>/posts` endpoint which is a detail view that has a list response.

        :rtype: bool)r   r$   r   r   r;   r   r   r   r   v  s   zViewInspector.is_list_viewc                 C   s   |   ¡ o| j ¡ | jv S )zçDetermine whether this view returns multiple objects. By default this is any non-detail view
        (see :meth:`.is_list_view`) whose request method is one of :attr:`.implicit_list_response_methods`.

        :rtype: bool
        )r   r   ÚupperÚimplicit_list_response_methodsr;   r   r   r   Úhas_list_response€  s   zViewInspector.has_list_responsec                 C   ó   t | jddƒo
|  ¡ S )zoDetermine whether filter backend parameters should be included for this request.

        :rtype: bool
        Úfilter_backendsN©r   r   r�   r;   r   r   r   Úshould_filterˆ  ó   zViewInspector.should_filterc                 C   s@   |   ¡ sg S g }t| jdƒD ]}||  | jd|ƒ ¡pg 7 }q|S )zqReturn the parameters added to the view by its filter backends.

        :rtype: list[openapi.Parameter]
        rŸ   rP   )r¡   r   r   r6   rŽ   )r'   ÚfieldsrO   r   r   r   rP   �  s   z#ViewInspector.get_filter_parametersc                 C   rž   )zŠDetermine whether paging parameters and structure should be added to this operation's request and response.

        :rtype: bool
        rG   Nr    r;   r   r   r   Úshould_page�  r¢   zViewInspector.should_pagec                 C   s(   |   ¡ sg S |  | jdt| jdƒ¡pg S )zkReturn the parameters added to the view by its paginator.

        :rtype: list[openapi.Parameter]
        rH   rG   )r¤   r6   r�   r   r   r;   r   r   r   Úget_pagination_parameters¤  s   

ÿÿz'ViewInspector.get_pagination_parametersc                 C   s   |   | jd|d| ji¡S )a#  Convert a serializer to an OpenAPI :class:`.Schema`.

        :param serializers.BaseSerializer serializer: the ``Serializer`` instance
        :returns: the converted :class:`.Schema`, or ``None`` in case of an unknown serializer
        :rtype: openapi.Schema or openapi.SchemaRef
        r„   rS   re   r‚   r   r   r   Úserializer_to_schema¯  s   ÿz"ViewInspector.serializer_to_schemac                 C   s    | j | jd|d| ji|d�pg S )a(  Convert a serializer to a possibly empty list of :class:`.Parameter`\ s.

        :param serializers.BaseSerializer serializer: the ``Serializer`` instance
        :param str in_: the location of the parameters, one of the `openapi.IN_*` constants
        :rtype: list[openapi.Parameter]
        r‡   rS   )r†   re   r…   r   r   r   Úserializer_to_parametersº  s   þýz&ViewInspector.serializer_to_parametersc                 C   s   | j | jdt| jdƒ|d�S )a+  Add appropriate paging fields to a response :class:`.Schema`.

        :param openapi.Schema response_schema: the response schema that must be paged.
        :returns: the paginated response class:`.Schema`, or ``None`` in case of an unknown pagination scheme
        :rtype: openapi.Schema
        rK   rG   )rJ   )r6   r�   r   r   )r'   rJ   r   r   r   rK   Æ  s   
ÿz$ViewInspector.get_paginated_response)r   rB   rC   Úbody_methodsÚimplicit_body_methodsrœ   rS   rŽ   r�   r(   r‘   rš   r   r�   r¡   rP   r¤   r¥   r¦   r§   rK   r€   r   r   rT   r   rˆ   L  s&    

rˆ   )NN)r   ÚloggingÚrest_frameworkr   Ú r   Úutilsr   r   r   r   Úobjectr0   Ú	getLoggerr   r   r   r"   r#   rD   rN   rQ   r�   rˆ   r   r   r   r   Ú<module>   s    


V|