
    +}&ib                        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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! 	 d dl"Z" ejJ                  e&      Z' G d de(      Z) G d de(      Z*dde*dddddddddddddddfdZ+d Z,d Z-d Z.d Z/d Z0d Z1d Z2d Z3d%dZ4d Z5d Z6d  Z7d! Z8d&d"Z9d# Z:d$ Z;y# e#$ r 	 d dl$m"Z" n# e#$ r dZ"Y nw xY wY w xY w)'    N)OrderedDict)Decimal)models)	force_str)serializersstatus)DestroyModelMixinListModelMixinRetrieveModelMixinUpdateModelMixin)FileUploadParser)is_form_media_type)api_settings)encodersjson)APIView   )swagger_settings)zoneinfoc                       e Zd ZdZy)no_bodyzgUsed as a sentinel value to forcibly remove the body of a request via
    :func:`.swagger_auto_schema`.N__name__
__module____qualname____doc__     F/usr/local/footviz/venv/lib/python3.12/site-packages/drf_yasg/utils.pyr   r   %   s    % 	r   r   c                       e Zd ZdZy)unsetzqUsed 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!   ,   s    ( 	r   r!   c                 Z    	
 
 	f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 list[str] produces: produces override
    :param list[str] consumes: consumes 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                 H  
 t        fdt        j                  D              rJ d       rt              nd rt              nd rt              nd  rt               nd dt	              t
        urd<   j                         s| S t        | dg       }t        | di       }|j                         D cg c]  \  }}|| j                  k(  s| }}}||z   }t        | dd       t        dg       D cg c]  }t        |      r| }}||z   
t        | d	i       }	sr
sJ d
       t              t              k7  sJ d       t        t              rJ d       rj                         g}	nD cg c]  }|j                          }	}t        
fd|	D              sJ d       t        fd|	D              rJ d       
rt        |      t        |      k7  sJ d       t!        
      dkD  r	|	sJ d       |	xs 
}	t        fd|	D              rJ d       t        fd|	D              rJ d       j                  fd|	D               | _        | S |	rJ d       rJ d       | _        | S c c}}w c c}w c c}w )Nc              3   &   K   | ]  }|v  
 y wNr   ).0hmextra_overridess     r   	<genexpr>z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>   s     Qr_,Q   z"HTTP method names not allowed here)consumes
deprecatedfield_inspectorsfilter_inspectorsmanual_parametersoperation_descriptionoperation_idoperation_summarypaginator_inspectorsproducesquery_serializerrequest_body	responsessecuritytagsauto_schemabind_to_methodsmappingcls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              3   &   K   | ]  }|v  
 y wr%   r   )r&   mthavailable_http_methodss     r   r)   z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>   s     Is44Ir*   zhttp method not bound to viewc              3   &   K   | ]  }|v  
 y wr%   r   r&   rA   existing_datas     r   r)   z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>        DC3-/Dr*   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   L   K   | ]  }t        t        |d       d        y w)Nr?   )hasattrgetattr)r&   rA   view_clss     r   r)   z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>  s*       #t46LMs   !$z+swagger_auto_schema applied twice to methodc              3   &   K   | ]  }|v  
 y wr%   r   rD   s     r   r)   z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>  rF   r*   c              3   B   K   | ]  }|j                         f  y wr%   )lower)r&   rA   datas     r   r)   z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>  s      I#))+t!4 Is   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!   updaterI   itemsr   rH   bool
isinstancestrrM   alllenr?   )!view_methodr;   r<   rA   namemapping_methodsaction_http_methodsmapi_view_http_methods_methodsrB   rN   rE   rJ   r:   r+   r,   r(   r-   r.   r/   methodmethodsr0   r1   r2   r3   r4   r5   r6   r7   r8   r9   s!             @@@@r   	decoratorz&swagger_auto_schema.<locals>.decorator   sK   Qw7P7PQQ 	
0	
Q !$:J%5 6PT<M&7!8SW!2%:(!2# %))=$>  0(" "&DJD#
& 4 e#"-DO$ "+/@"E+y"5!(
CDK<P<P4PC
 
 .? ;t4 X':B?!
x# !
 !
 "79L!L-CRHf) ) =DL0T2TT0!'3/ 6/ "LLN+3:;CCIIK;;III /I D8DD 4D "-.$7J2KK *K )*Q. 6x $='= #  = ==  D8DD =D    I II/<K,    ?<
 %S&SS$/3K,U
!
. <s   J'JJJr   )r`   ra   r:   r6   r5   r/   r1   r0   r2   r8   r,   r7   r-   r.   r3   r9   r4   r+   r(   rb   s   ``````````````````` r   swagger_auto_schemarc   3   s!    zm m m^ r   c                       f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 r%   )_swagger_serializer)serializer_methodserializer_or_fields    r   rb   z,swagger_serializer_method.<locals>.decorator+  s    0C-  r   r   )rh   rb   s   ` r   swagger_serializer_methodri   "  s    !
 r   c                 ^   t        |dd      }t        |dd      }t        |dd      }|dv s	|du s|dk(  ry	|d
v s|j                         dk7  s	|d	u s|dk(  ryt        |t              ry	t        |t        t
        t        f      ry| j                  d      j                  d      }|rd|d   v ryy	)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 detailNsuffix)rP   createFListT)retrieverR   partial_updatedestroygetInstance/{)	rI   rM   rU   r
   r   r   r	   stripsplit)pathr`   viewrk   rm   rn   path_componentss          r   is_list_viewr~   3  s     T8R(FT8T*FT8T*F##v&F:J 	EE<<>U"T>Z$' $+-=?PQR jjo++C0O3/""55 r   c                 v    | dk(  rt         j                  S | dk(  rt         j                  S t         j                  S )Npostdelete)r   HTTP_201_CREATEDHTTP_204_NO_CONTENTHTTP_200_OK)r`   s    r   guess_response_statusr   \  s6    &&&	8	)))!!!r   c                 f    t        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              3   P   K   | ]  }|j                   |j                  f|f   y wr%   )rZ   in_)r&   params     r   r)   z&param_list_to_odict.<locals>.<genexpr>p  s"     Re5::uyy159Rs   $&zduplicate Parameters found)r   rX   )
parametersresults     r   param_list_to_odictr   e  s5     RzRRFv;#j/)G+GG)Mr   c                 ~    t        |       } | j                  t        |             t        | j                               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]
    )r   rR   rP   values)r   	overridess     r   merge_paramsr   u  s6     %Z0J))45
!!#$$r   c                    | yd}t        | t              r& t        |       d | j                         D              }t        | t        t
        f      r t        |       d | D              }|t        |      t        |       k7  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              3   6   K   | ]  \  }}|	|||f  y wr%   r   )r&   kvs      r   r)   zfilter_none.<locals>.<genexpr>  s%      
q!amQF
s   
	c              3   &   K   | ]	  }||  y wr%   r   )r&   r   s     r   r)   zfilter_none.<locals>.<genexpr>  s     <!amA<s   )rU   dicttyperS   rP   tuplerX   )objnew_objs     r   rQ   rQ     s     {G#t$s) 
"yy{
 
 #e}%$s)<s<<s7|s3x7Jr   c                    t        j                  |       r5t        | t        j                        sJ d| j
                  z          |        S t        | t        j                        sJ dt        |       j
                  z         | 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   BaseSerializerr   rU   r   
serializers    r   force_serializer_instancer     s}     z"*k&@&@A 	
)J,?,??	
A |j+"<"<= 7$z:J:S:SS= r   c                    | yt        j                  |       r0t        | t        j                        sJ d| j
                  z         | S t        | t        j                        sJ dt        |       j
                  z         t        |       S )a:  Given a ``Serializer`` class or instance, 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   s    r   get_serializer_classr     s     z"*k&@&@A 	
)J,?,??	
A j+"<"<= 7$z:J:S:SS= 
r   c                     | xs g } g }| D ]a  }t        j                  |      r!|rt        ||      s'|j                  |       9|rt	        ||      sH|j                  t        |             c |S )a|  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   appendrU   r   )classes_or_instancesexpected_base_classr   r   s       r   get_object_classesr     sl     052F# )??3&*S:M*Nc"&*S:M*Nd3i() Mr   c                 
   t        |       } | D cg c]  }t        |t              r| } }| xs g D cg c]  }|j                   }}|D cg c]  }t	        |      r| }}t        |      dk(  r|S |S c c}w c c}w c c}w )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]
    r   )r   r   r   
media_typer   rX   )parser_classespcparsermedia_typesencodingnon_form_media_typess         r   get_consumesr     s     (7N#:b:J+KN  4B3GRH6$$HKH!,4Fx4P   A%
  # Is   A6A6A;B B c                     t        |       } | xs g D cg c]  }|j                   }}|D cg c]&  t        fdt        j                  D              s( }}|S c c}w c c}w )a7  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              3   &   K   | ]  }|v  
 y wr%   r   )r&   excludedr   s     r   r)   zget_produces.<locals>.<genexpr>  s      
%-H 
r*   )r   r   rO   r   EXCLUDED_MEDIA_TYPES)renderer_classesrendererr   r   s      `r   get_producesr     s|     **:;7G7M2N88&&NKN $ 
1A1V1V
 
 	K   Os
   A+A#c                     t        | t        j                        st        | t        j                        rt	        | dt
        j                         S y)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
    coerce_to_stringF)rU   r   DecimalFieldr   rI   rest_framework_settingsCOERCE_DECIMAL_TO_STRING)fields    r   decimal_as_floatr     sN     %112jv""7 %'>'W'W
 
 	
 r   c                 J   t        | dd      }t        |       j                  }t        |d      r|j                  }|S |dk(  r?t        | t        j                        r%t        j                  dt        |       z          d}|S |}|j                  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
    MetaNref_nameNestedSerializerzDForcing inline output for ModelSerializer named 'NestedSerializer':

Serializer)rI   r   r   rH   r   rU   r   ModelSerializerloggerdebugrV   endswithrX   )r   serializer_metaserializer_namer   s       r   get_serializer_ref_namer   #  s     j&$7O:&//O
+"++ O 
.	.:K//4 	S*o	
 
 O #\* 43|#4"45HOr   c                 z    | 8t        | |||      } t        | t              sd| z   } t        j                  |       } | S )zi
    Force `s` into a ``str`` instance.

    Fix for https://github.com/axnsan12/drf-yasg/issues/159
    rl   )r   rU   rV   textwrapdedent)sr   strings_onlyerrorss       r   force_real_strr   >  sA     	}a<8!S!QA OOAHr   c                    | j                  |      }t        |t              r#t        |       rt	        |      }n]t        |      }nQt        |t        j                        rt        |      }n+t        %t        |t        j                        rt        |      }t        j                  t        j                  |t        j                              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=   )to_representationrU   r   r   floatrV   pytz
BaseTzInfor   ZoneInfor   loadsdumpsr   JSONEncoder)r   values     r   field_value_to_representationr   O  s     ##E*E%!E"%LEJE	E4??	+E
		*UH4E4E"FE
 ::djjH,@,@ABBr   c                    t        | dt        j                        }|t        j                  urit        |      r;	 t	        |d      r|j                  |        t        |dd      r	 ||       }n |       }|t        j                  ur|	 t        | |      }|S |S # t        $ r+ t        j                  d| d       t        j                  }Y Xw xY w# t        $ r, t        j                  d| d       t        j                  }Y |S w xY w)	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_contextrequires_contextFzfdefault for %s is callable but it raised an exception when called; 'default' will not be set on schemaT)exc_infozX'default' on schema for %s will not be set because to_representation raised an exception)
rI   r   emptycallablerH   r   	Exceptionr   warningr   )r   r   s     r   get_field_defaultr   i  s    eY(9(9:Gk'''G,7M2''.7$6>%enG%iG ++++0C	,7wG N7N+  ,B!	   &++,  ,<!	   &++N,s#   :B 	C 1CC1DDr%   )zutf-8Fstrict)<r   loggingr   collectionsr   decimalr   r   	django.dbr   django.utils.encodingr   rest_frameworkr   r   rest_framework.mixinsr	   r
   r   r   rest_framework.parsersr   rest_framework.requestr   rest_framework.settingsr   r   rest_framework.utilsr   r   rest_framework.viewsr   app_settingsr   r   ImportError	backports	getLoggerr   r   objectr   r!   rc   ri   r~   r   r   r   rQ   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>r      s1      #    + .  4 5 K / ( * 
		8	$	f 		F 	 	%l^"&R" %"**00 <* 6"C4']  & s6   $C C6C&%C6&C0-C6/C00C65C6