o
    h]                     @   s  d dl 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	 d dl
mZ d dlmZmZ d dlmZmZmZ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! e"e#Z$G dd de%Z&G dd de%Z'dde'ddddddddddddd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$ Z0d:d%d&Z1d'd( Z2d)d* Z3d+d, Z4d-d. Z5d;d2d3Z6d4d5 Z7d6d7 Z8d8d9 Z9dS )<    N)OrderedDict)Decimal)models)	force_str)serializersstatus)DestroyModelMixinListModelMixinRetrieveModelMixinUpdateModelMixin)FileUploadParseris_form_media_type)api_settings)encodersjson)APIView   )swagger_settingsc                   @      e Zd ZdZdS )no_bodyzcUsed as a sentinel value to forcibly remove the body of a request via :func:`.swagger_auto_schema`.N__name__
__module____qualname____doc__ r   r   V/var/www/html/magazine_api/magazine_env/lib/python3.10/site-packages/drf_yasg/utils.pyr          r   c                   @   r   )unsetzmUsed as a sentinel value for function parameters not set by the caller where ``None`` would be a valid value.Nr   r   r   r   r   r      r   r   c                    s0    	
fdd}|S )a  Decorate a view method to customize the :class:`.Operation` object generated from it.

    `method` and `methods` are mutually exclusive and must only be present when decorating a view method that accepts
    more than one HTTP request method.

    The `auto_schema` and `operation_description` arguments take precedence over view- or method-level values.

    :param str method: for multi-method views, the http method the options should apply to
    :param list[str] methods: for multi-method views, the http methods the options should apply to
    :param drf_yasg.inspectors.SwaggerAutoSchema auto_schema: custom class to use for generating the Operation object;
        this overrides both the class-level ``swagger_schema`` attribute and the ``DEFAULT_AUTO_SCHEMA_CLASS``
        setting, and can be set to ``None`` to prevent this operation from being generated
    :param request_body: custom request body which will be used as the ``schema`` property of a
        :class:`.Parameter` with ``in: 'body'``.

        A Schema or SchemaRef is not valid if this request consumes form-data, because ``form`` and ``body`` parameters
        are mutually exclusive in an :class:`.Operation`. If you need to set custom ``form`` parameters, you can use
        the `manual_parameters` argument.

        If a ``Serializer`` class or instance is given, it will be automatically converted into a :class:`.Schema`
        used as a ``body`` :class:`.Parameter`, or into a list of ``form`` :class:`.Parameter`\ s, as appropriate.
    :type request_body: drf_yasg.openapi.Schema or drf_yasg.openapi.SchemaRef  or rest_framework.serializers.Serializer
        or type[no_body]

    :param rest_framework.serializers.Serializer query_serializer: if you use a ``Serializer`` to parse query
        parameters, you can pass it here and have :class:`.Parameter` objects be generated automatically from it.

        If any ``Field`` on the serializer cannot be represented as a ``query`` :class:`.Parameter`
        (e.g. nested Serializers, file fields, ...), the schema generation will fail with an error.

        Schema generation will also fail if the name of any Field on the `query_serializer` conflicts with parameters
        generated by ``filter_backends`` or ``paginator``.

    :param list[drf_yasg.openapi.Parameter] manual_parameters: a list of manual parameters to override the
        automatically generated ones

        :class:`.Parameter`\ s are identified by their (``name``, ``in``) combination, and any parameters given
        here will fully override automatically generated parameters if they collide.

        It is an error to supply ``form`` parameters when the request does not consume form-data.

    :param str operation_id: operation ID override; the operation ID must be unique across the whole API
    :param str operation_description: operation description override
    :param str operation_summary: operation summary string
    :param list[dict] security: security requirements override; used to specify which authentication mechanism
        is required to call this API; an empty list marks the endpoint as unauthenticated (i.e. removes all accepted
        authentication schemes), and ``None`` will inherit the top-level security requirements
    :param bool deprecated: deprecation status for operation
    :param responses: a dict of documented manual responses
        keyed on response status code. If no success (``2xx``) response is given, one will automatically be
        generated from the request body and http method. If any ``2xx`` response is given the automatic response is
        suppressed.

        * if a plain string is given as value, a :class:`.Response` with no body and that string as its description
          will be generated
        * if ``None`` is given as a value, the response is ignored; this is mainly useful for disabling default
          2xx responses, i.e. ``responses={200: None, 302: 'something'}``
        * if a :class:`.Schema`, :class:`.SchemaRef` is given, a :class:`.Response` with the schema as its body and
          an empty description will be generated
        * a ``Serializer`` class or instance will be converted into a :class:`.Schema` and treated as above
        * a :class:`.Response` object will be used as-is; however if its ``schema`` attribute is a ``Serializer``,
          it will automatically be converted into a :class:`.Schema`
    :type responses: dict[int or str, (drf_yasg.openapi.Schema or drf_yasg.openapi.SchemaRef or
        drf_yasg.openapi.Response or str or rest_framework.serializers.Serializer)]

    :param list[type[drf_yasg.inspectors.FieldInspector]] field_inspectors: extra serializer and field inspectors; these
        will be tried before :attr:`.ViewInspector.field_inspectors` on the :class:`.inspectors.SwaggerAutoSchema`
    :param list[type[drf_yasg.inspectors.FilterInspector]] filter_inspectors: extra filter inspectors; these will be
        tried before :attr:`.ViewInspector.filter_inspectors` on the :class:`.inspectors.SwaggerAutoSchema`
    :param list[type[drf_yasg.inspectors.PaginatorInspector]] paginator_inspectors: extra paginator inspectors; these
        will be tried before :attr:`.ViewInspector.paginator_inspectors` on the :class:`.inspectors.SwaggerAutoSchema`
    :param list[str] tags: tags override
    :param extra_overrides: extra values that will be saved into the ``overrides`` dict; these values will be available
        in the handling :class:`.inspectors.SwaggerAutoSchema` instance via ``self.overrides``
    c                    sn  t fddtjD rJ d
	rt	nd r&tnd r-tnd r4tnd dtturDd<  sMS tdg }tdi }fdd	| D }|| }td
d fdd	tdg D }||  tdi }srӈ sJ dt	t	ksJ dt
trJ dr g}ndd	 D }t fdd|D sJ dt fdd|D rJ d r$t	|t	|ksJ dt dkr|sJ dn|p }t fdd|D rJ dt fdd|D rJ dfdd|D  _S |r+J dr2J d_S )Nc                 3       | ]}| v V  qd S Nr   ).0Zhm)extra_overridesr   r   	<genexpr>r       z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>z"HTTP method names not allowed here)request_bodyquery_serializermanual_parametersoperation_idoperation_summary
deprecatedoperation_descriptionsecurity	responsesfilter_inspectorspaginator_inspectorsfield_inspectorstagsauto_schemabind_to_methodsmappingc                    s   g | ]\}}| j kr|qS r   )r   )r"   mthname)view_methodr   r   
<listcomp>   s    z:swagger_auto_schema.<locals>.decorator.<locals>.<listcomp>clsc                    s   g | ]	}t  |r|qS r   )hasattr)r"   mview_clsr   r   r9          http_method_names_swagger_auto_schemazI`method` or `methods` can only be specified on @action or @api_view viewsz specify either method or methodszR`methods` expects to receive a list of methods; use `method` for a single argumentc                 S   s   g | ]}|  qS r   lowerr"   r6   r   r   r   r9      s    c                 3   r    r!   r   rD   )available_http_methodsr   r   r$      r%   zhttp method not bound to viewc                 3   r    r!   r   rD   existing_datar   r   r$      r%   z"http method defined multiple timeszthis should never happenr   zon multi-method api_view or action, you must specify swagger_auto_schema on a per-method basis using one of the `method` or `methods` argumentsc                 3   s"    | ]}t t |d dV  qd S )NrA   )r;   getattrrD   r=   r   r   r$      s     z+swagger_auto_schema applied twice to methodc                 3   r    r!   r   rD   rF   r   r   r$      r%   c                 3   s    | ]	}|   fV  qd S r!   rB   rD   )datar   r   r$          zthe methods argument should only be specified when decorating an action; you should also ensure that you put the swagger_auto_schema decorator AFTER (above) the _route decorator)anyr   r@   listfilter_noner   updaterH   itemsbool
isinstancestrrC   alllenrA   )r8   r4   r5   Zmapping_methodsZaction_http_methodsZapi_view_http_methodsZ_methodsr3   r+   r#   r1   r/   r(   methodmethodsr,   r)   r*   r0   r'   r&   r.   r-   r2   )rE   rI   rG   r>   r8   r   	decoratorq   sv    
 	z&swagger_auto_schema.<locals>.decoratorr   )rV   rW   r3   r&   r'   r(   r)   r,   r*   r-   r+   r.   r1   r/   r0   r2   r#   rX   r   rU   r   swagger_auto_schema!   s   ,PNrY   c                    s    fdd}|S )z
    Decorates the method of a serializers.SerializerMethodField
    to hint as to how Swagger should be generated for this field.

    :param serializer_or_field: ``Serializer``/``Field`` class or instance
    :return:
    c                    s
    | _ | S r!   )Z_swagger_serializer)Zserializer_methodserializer_or_fieldr   r   rX      s   z,swagger_serializer_method.<locals>.decoratorr   )r[   rX   r   rZ   r   swagger_serializer_method   s   	r\   c                 C   s   t |dd}t ||dp|}t |dd}t |dd}|dv s&|du s&|dkr(d	S |d
v s4|d	u s4|dkr6dS t|tr=d	S t|tttfrGdS | dd}|rYd|d v rYdS d	S )zCheck if the given path/method appears to represent a list view (as opposed to a detail/instance view).

    :param str path: view path
    :param str method: http method
    :param APIView view: target view
    :rtype: bool
    action Ndetailsuffix)rL   createFListT)retrieverN   Zpartial_updatedestroyInstance/{)rH   rQ   r	   r
   r   r   stripsplit)pathrV   viewr]   r_   r`   Zpath_componentsr   r   r   is_list_view   s    	
rm   c                 C   s"   | dkrt jS | dkrt jS t jS )Npostdelete)r   ZHTTP_201_CREATEDZHTTP_204_NO_CONTENTZHTTP_200_OK)rV   r   r   r   guess_response_status   s
   rp   c                 C   s.   t dd | D }t|t| ksJ d|S )a  Transform a list of :class:`.Parameter` objects into an ``OrderedDict`` keyed on the ``(name, in_)`` tuple of
    each parameter.

    Raises an ``AssertionError`` if `parameters` contains duplicate parameters (by their name + in combination).

    :param list[drf_yasg.openapi.Parameter] parameters: the list of parameters
    :return: `parameters` keyed by ``(name, in_)``
    :rtype: dict[(str,str),drf_yasg.openapi.Parameter]
    c                 s   s     | ]}|j |jf|fV  qd S r!   )r7   in_)r"   paramr   r   r   r$   
  s    z&param_list_to_odict.<locals>.<genexpr>zduplicate Parameters found)r   rT   )
parametersresultr   r   r   param_list_to_odict   s   
ru   c                 C   s"   t | } | t | t|  S )a  Merge `overrides` into `parameters`. This is the same as appending `overrides` to `parameters`, but any element
    of `parameters` whose ``(name, in_)`` tuple collides with an element in `overrides` is replaced by it.

    Raises an ``AssertionError`` if either list contains duplicate parameters.

    :param list[drf_yasg.openapi.Parameter] parameters: initial parameters
    :param list[drf_yasg.openapi.Parameter] overrides: overriding parameters
    :return: merged list
    :rtype: list[drf_yasg.openapi.Parameter]
    )ru   rN   rL   values)rs   Z	overridesr   r   r   merge_params  s   rw   c                 C   sx   | du rdS d}t | trt| dd |  D }t | ttfr,t| dd | D }|dur:t|t| kr:|S | S )zRemove ``None`` values from tuples, lists or dictionaries. Return other objects as-is.

    :param obj: the object
    :return: collection with ``None`` values removed
    Nc                 s   s,    | ]\}}|d ur|d ur||fV  qd S r!   r   )r"   kvr   r   r   r$   )  s   * zfilter_none.<locals>.<genexpr>c                 s   s    | ]	}|d ur|V  qd S r!   r   )r"   ry   r   r   r   r$   +  rJ   )rQ   dicttyperO   rL   tuplerT   )objZnew_objr   r   r   rM     s   
rM   c                 C   sL   t | rt| tjsJ d| j |  S t| tjs$J dt| j | S )aY  Force `serializer` into a ``Serializer`` instance. If it is not a ``Serializer`` class or instance, raises
    an assertion error.

    :param serializer: serializer class or instance
    :type serializer: serializers.BaseSerializer or type[serializers.BaseSerializer]
    :return: serializer instance
    :rtype: serializers.BaseSerializer
    Serializer required, not %s-Serializer class or instance required, not %sinspectisclass
issubclassr   ZBaseSerializerr   rQ   r{   
serializerr   r   r   force_serializer_instance1  s   
	r   c                 C   sZ   | du rdS t | rt| tjsJ d| j | S t| tjs)J dt| j t| S )a5  Given a ``Serializer`` class or intance, return the ``Serializer`` class. If `serializer` is not a ``Serializer``
    class or instance, raises an assertion error.

    :param serializer: serializer class or instance, or ``None``
    :return: serializer class
    :rtype: type[serializers.BaseSerializer]
    Nr~   r   r   r   r   r   r   get_serializer_classC  s   
r   c                 C   sZ   | pg } g }| D ]"}t |r|rt||r|| q|r#t||r*|t| q|S )at  Given a list of instances or class objects, return the list of their classes.

    :param classes_or_instances: mixed list to parse
    :type classes_or_instances: list[type or object]
    :param expected_base_class: if given, only subclasses or instances of this type will be returned
    :type expected_base_class: type
    :return: list of classes
    :rtype: list
    )r   r   r   appendrQ   r{   )Zclasses_or_instancesZexpected_base_classrt   r}   r   r   r   get_object_classesW  s   


r   c                 C   sJ   t | } dd | D } dd | pg D }dd |D }t|dkr#|S |S )a  Extract ``consumes`` MIME types from a list of parser classes.

    :param list parser_classes: parser classes
    :type parser_classes: list[rest_framework.parsers.BaseParser or type[rest_framework.parsers.BaseParser]]
    :return: MIME types for ``consumes``
    :rtype: list[str]
    c                 S   s   g | ]	}t |ts|qS r   )r   r   )r"   Zpcr   r   r   r9   w  r?   z get_consumes.<locals>.<listcomp>c                 S      g | ]}|j qS r   
media_type)r"   parserr   r   r   r9   x      c                 S   s   g | ]}t |s|qS r   r   )r"   encodingr   r   r   r9   y  s    r   )r   rT   )Zparser_classesmedia_typesZnon_form_media_typesr   r   r   get_consumesn  s   r   c                 C   s,   t | } dd | p
g D }dd |D }|S )a/  Extract ``produces`` MIME types from a list of renderer classes.

    :param list renderer_classes: renderer classes
    :type renderer_classes: list[rest_framework.renderers.BaseRenderer or type[rest_framework.renderers.BaseRenderer]]
    :return: MIME types for ``produces``
    :rtype: list[str]
    c                 S   r   r   r   )r"   rendererr   r   r   r9     r   z get_produces.<locals>.<listcomp>c                    s(   g | ] t  fd dtjD s qS )c                 3   r    r!   r   )r"   excludedr   r   r   r$     r%   z*get_produces.<locals>.<listcomp>.<genexpr>)rK   r   ZEXCLUDED_MEDIA_TYPES)r"   r   r   r   r9     s    
)r   )Zrenderer_classesr   r   r   r   get_produces  s   r   c                 C   s,   t | tjst | tjrt| dtj S dS )zReturns true if ``field`` is a django-rest-framework DecimalField and its ``coerce_to_string`` attribute or the
    ``COERCE_DECIMAL_TO_STRING`` setting is set to ``False``.

    :rtype: bool
    Zcoerce_to_stringF)rQ   r   ZDecimalFieldr   rH   rest_framework_settingsZCOERCE_DECIMAL_TO_STRING)fieldr   r   r   decimal_as_float  s   r   c                 C   s|   t | dd}t| j}t|dr|j}|S |dkr,t| tjr,t	dt
|   d}|S |}|dr<|dtd  }|S )zGet serializer's ref_name (or None for ModelSerializer if it is named 'NestedSerializer')

    :param serializer: Serializer instance
    :return: Serializer's ``ref_name`` or ``None`` for inline serializer
    :rtype: str or None
    ZMetaNref_nameZNestedSerializerzDForcing inline output for ModelSerializer named 'NestedSerializer':

Serializer)rH   r{   r   r;   r   rQ   r   ZModelSerializerloggerdebugrR   endswithrT   )r   Zserializer_metaZserializer_namer   r   r   r   get_serializer_ref_name  s   


r   utf-8Fstrictc                 C   s8   | durt | |||} t| tkrd|  } t| } | S )zi
    Force `s` into a ``str`` instance.

    Fix for https://github.com/axnsan12/drf-yasg/issues/159
    Nr^   )r   r{   rR   textwrapdedent)sr   Zstrings_onlyerrorsr   r   r   force_real_str  s   
r   c                 C   sD   |  |}t|trt| rt|}nt|}ttj|t	j
dS )zConvert a python value related to a field (default, choices, etc.) into its OpenAPI-compatible representation.

    :param serializers.Field field: field associated with the value
    :param object value: value
    :return: the converted value
    )r:   )Zto_representationrQ   r   r   floatrR   r   loadsdumpsr   JSONEncoder)r   valuer   r   r   field_value_to_representation  s   


r   c                 C   s   t | dtj}|tjurft|r?zt|dr||  t |ddr&|| }n| }W n ty>   tjd| dd tj}Y nw |tjurf|durfzt	| |}W |S  tye   tjd	| dd tj}Y |S w |S )
z
    Get the default value for a field, converted to a JSON-compatible value while properly handling callables.

    :param field: field instance
    :return: default value
    defaultset_contextZrequires_contextFzfdefault for %s is callable but it raised an exception when called; 'default' will not be set on schemaT)exc_infoNzX'default' on schema for %s will not be set because to_representation raised an exception)
rH   r   emptycallabler;   r   	Exceptionr   warningr   )r   r   r   r   r   get_field_default  s8   




r   c                 C   s   t jdkr
t| tS t| tS )zCheck if a given object is a dict that maintains insertion order.

    :param obj: the dict object to check
    :rtype: bool
    )      )sysversion_inforQ   rz   r   )r}   r   r   r   dict_has_ordered_keys  s   


r   r!   )r   Fr   ):r   loggingr   r   collectionsr   decimalr   Z	django.dbr   Zdjango.utils.encodingr   Zrest_frameworkr   r   Zrest_framework.mixinsr   r	   r
   r   Zrest_framework.parsersr   Zrest_framework.requestr   Zrest_framework.settingsr   r   Zrest_framework.utilsr   r   Zrest_framework.viewsr   Zapp_settingsr   	getLoggerr   r   objectr   r   rY   r\   rm   rp   ru   rw   rM   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sT    



 "$	

!