
    =!gz]                        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"n # e#$ r 	 d dl$m"Z" n# e#$ r dZ"Y nw xY wY nw xY w ej%        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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;dS )*    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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__     I/var/www/html/nourish/venv/lib/python3.11/site-packages/drf_yasg/utils.pyr   r       s        mmDr   r   c                       e Zd ZdZdS )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"   %   s        wwDr   r"   c                 R    	
 
 	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 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                    	
 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<                                  s S t           dg           }t           di           } fd|                                D             }||z   }t           dd           

fd	t          
d
g           D             }||z   t           di           	}srÉs
J d            t                    t                    k    s
J d            t          t                    r
J d            r                                g}nd D             }t          fd|D                       s
J d            t          	fd|D                       r
J d            rt          |          t          |          k    s
J d            t                    dk    r|s
J d            n|p}t          
fd|D                       r
J d            t          	fd|D                       r
J d            	                    fd|D                        	 _        n|r
J d            	r
J d             _         S )Nc              3       K   | ]}|v V  	d S Nr   ).0hmextra_overridess     r    	<genexpr>z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>{   s(      QQr_,QQQQQQr   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                 0    g | ]\  }}|j         k    |S r   )r   )r'   mthnameview_methods      r    
<listcomp>z:swagger_auto_schema.<locals>.decorator.<locals>.<listcomp>   s*    ```934;K_C_C_3C_C_C_r   clsc                 4    g | ]}t          |          |S r   )hasattr)r'   mview_clss     r    r?   z:swagger_auto_schema.<locals>.decorator.<locals>.<listcomp>   s+     o o oqZabjlmZnZn o o o or   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                 6    g | ]}|                                 S r   lower)r'   r<   s     r    r?   z:swagger_auto_schema.<locals>.decorator.<locals>.<listcomp>   s     ;;;CCIIKK;;;r   c              3       K   | ]}|v V  	d S r&   r   )r'   r<   available_http_methodss     r    r*   z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>   s)      IIs44IIIIIIr   zhttp method not bound to viewc              3       K   | ]}|v V  	d S r&   r   r'   r<   existing_datas     r    r*   z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>   (      DDC3-/DDDDD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   V   K   | ]#}t          t          |d           d          V  $d S )NrF   )rB   getattr)r'   r<   rD   s     r    r*   z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>   s;      mm]`778S$#?#?AWXXmmmmmmr   z+swagger_auto_schema applied twice to methodc              3       K   | ]}|v V  	d S r&   r   rM   s     r    r*   z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>   rO   r   c              3   D   K   | ]}|                                 fV  d S r&   rH   )r'   r<   datas     r    r*   z9swagger_auto_schema.<locals>.decorator.<locals>.<genexpr>   s0       I I#))++t!4 I I I I I Ir   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   rE   listfilter_noner"   updaterQ   itemsbool
isinstancestrrI   alllenrF   )r>   r9   r:   mapping_methodsaction_http_methodsapi_view_http_methods_methodsrK   rT   rN   rD   r8   r0   r)   r6   r4   r-   methodmethodsr1   r.   r/   r5   r,   r+   r3   r2   r7   s   `      @@@@r    	decoratorz&swagger_auto_schema.<locals>.decoratorz   s   QQQQw7PQQQQQwwSwwwQ( 0!2(!2$%: "<M!W&7!8!8!8SWBV$`D)=$>$>$>\`:J T%5 6 6 6PT"&0DJJJD
 
 4  e##"-DO$$$ 	 "+/@"EE+y"55```````-? ;t44 o o o oGH>QSU,V,V o o o!69L!L-CRHH 
	kf 
	k)vv+vvv)==DLL0002T000!'3// W W 2W W W/ <"LLNN+;;7;;;IIIIIIIIIjjKjjjIDDDD8DDDDDjjFjjjD! 	4-..$7J2K2KKKKMgKKK)**Q.. q qqq qx q
 $='=mmmmdlmmmmm > >=> >mDDDD8DDDDDssFsssD   I I I I I I IIII/<K,, 5 555 5< %SS&SSS$/3K,r   r   )rc   rd   r8   r+   r,   r-   r.   r1   r/   r2   r0   r3   r6   r4   r5   r7   r)   re   s   ````````````````` r    swagger_auto_schemarf   *   s    `L L L L L L L L L L L L L L L L L L L L L\ 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    re   z,swagger_serializer_method.<locals>.decorator   s    0C-  r   r   )rk   re   s   ` r    swagger_serializer_methodrl      s$    ! ! ! ! !
 r   c                    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 s
|d	u s|dk    rdS t          |t                    rd	S t          |t          t          t
          f          rdS |                     d                              d          }|rd|d         v rd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)rV   createFListT)retrieverX   partial_updatedestroyInstance/{)rQ   r[   r
   r   r   r	   stripsplit)pathrc   viewrn   rp   rq   path_componentss          r    is_list_viewr      s    T8R((FT64((2FFVXt,,FT8T**F###v&F:J:JtDDDRVZ`dnZnZnu$'' t $+-=?PQRR u jjoo++C00O 3/""555u 4r   c                 b    | 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)rc   s    r    guess_response_statusr      s3    &&	8		))!!r   c                     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   6   K   | ]}|j         |j        f|fV  d S r&   )r=   in_)r'   params     r    r*   z&param_list_to_odict.<locals>.<genexpr>  s0      RRe5:uy159RRRRRRr   zduplicate Parameters found)r   r^   )
parametersresults     r    param_list_to_odictr   	  sK     RRzRRRRRFv;;#j//)))+G)))Mr   c                     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]
    )r   rX   rV   values)r   	overridess     r    merge_paramsr     sH     %Z00J))44555
!!##$$$r   c                 h   | dS d}t          | t                    r4 t          |           d |                                 D                       }t          | t          t
          f          r" t          |           d | D                       }|"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              3   ,   K   | ]\  }}||	||fV  d S r&   r   )r'   kvs      r    r*   zfilter_none.<locals>.<genexpr>2  s4      ^^tq!amPQP]QFP]P]P]P]^^r   c              3      K   | ]}||V  	d S r&   r   )r'   r   s     r    r*   zfilter_none.<locals>.<genexpr>4  s"      <<!amAmmmm<<r   )r[   dicttyperY   rV   tupler^   )objnew_objs     r    rW   rW   (  s     {tG#t _$s))^^syy{{^^^^^#e}%% =$s))<<s<<<<<s7||s3xx77Jr   c                    t          j        |           r6t          | 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   r[   r   
serializers    r    force_serializer_instancer   :  s     z"" *k&@AAvvC`cmcvCvvvAz||j+"<== T T7$z:J:J:SST T=r   c                    | dS t          j        |           r.t          | t          j                  sJ d| j        z              | S t          | t          j                  sJ dt          |           j        z              t          |           S )a6  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   L  s     tz"" *k&@AAvvC`cmcvCvvvAj+"<== T T7$z:J:J:SST T=
r   c                     | pg } g }| D ]r}t          j        |          r(|rt          ||          r|                    |           >|rt	          ||          r"|                    t          |                     s|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   appendr[   r   )classes_or_instancesexpected_base_classr   r   s       r    get_object_classesr   `  s     052F# ) )?3 	)& #*S:M*N*N #c"""& )*S:M*N*N )d3ii(((Mr   c                     t          |           } d | D             } d | pg 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                 <    g | ]}t          |t                    |S r   )r   r   )r'   pcs     r    r?   z get_consumes.<locals>.<listcomp>  s(    ZZZRBHX9Y9YZbZZZr   c                     g | ]	}|j         
S r   
media_type)r'   parsers     r    r?   z get_consumes.<locals>.<listcomp>  s    HHH6$HHHr   c                 0    g | ]}t          |          |S r   r   r'   encodings     r    r?   z get_consumes.<locals>.<listcomp>  s'    eeeHZ[cHdHdeHeeer   r   )r   r^   )parser_classesmedia_typesnon_form_media_typess      r    get_consumesr   w  st     (77NZZ>ZZZNHH>3GRHHHKee[eee
   A%%  r   c                 X    t          |           } d | pg 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                     g | ]	}|j         
S r   r   )r'   renderers     r    r?   z get_produces.<locals>.<listcomp>  s    NNN88&NNNr   c                 ^    g | ])t          fd t          j        D                       '*S )c              3       K   | ]}|v V  	d S r&   r   )r'   excludedr   s     r    r*   z*get_produces.<locals>.<listcomp>.<genexpr>  s(      iixh(2iiiiiir   )rU   r   EXCLUDED_MEDIA_TYPESr   s    @r    r?   z get_produces.<locals>.<listcomp>  sU     k k kiiiiCSChiiiiik8 k k kr   )r   )renderer_classesr   s     r    get_producesr     sT     **:;;NN7G7M2NNNKk kK k k kKr   c                     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
    coerce_to_stringF)r[   r   DecimalFieldr   rQ   rest_framework_settingsCOERCE_DECIMAL_TO_STRING)fields    r    decimal_as_floatr     sN     %122 hjH[6\6\ h5"46M6fgggg5r   c                 x   t          | dd          }t          |           j        }t          |d          r|j        }n||dk    rGt          | t          j                  r-t          	                    dt          |           z              d}n/|}|                    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)rQ   r   r   rB   r   r[   r   ModelSerializerloggerdebugr\   endswithr^   )r   serializer_metaserializer_namer   s       r    get_serializer_ref_namer     s     j&$77O:&&/O
++ 5"+	.	.	.:j+Je3f3f	.\_bcm_n_nnooo"\** 	5 3#l"3"3!3 34HOr   utf-8Fstrictc                     | At          | |||          } t          |           t          urd| z   } t          j        |           } | S )zi
    Force `s` into a ``str`` instance.

    Fix for https://github.com/axnsan12/drf-yasg/issues/159
    Nro   )r   r   r\   textwrapdedent)sr   strings_onlyerrorss       r    force_real_strr     sL     	}a<8877#QA OAHr   c                    |                      |          }t          |t                    r/t          |           rt	          |          }njt          |          }nZt          |t          j                  rt          |          }n0t          )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
    N)r@   )to_representationr[   r   r   floatr\   pytz
BaseTzInfor   ZoneInfor   loadsdumpsr   JSONEncoder)r   values     r    field_value_to_representationr     s     ##E**E%!! 
E"" 	%LLEEJJEE	E4?	+	+ E

		*UH4E"F"F	E

 :djH,@AAABBBr   c                 :   t          | dt          j                  }|t          j        urt          |          r	 t	          |d          r|                    |            t          |dd          r ||           }n
 |            }n9# t          $ r, t                              d| d           t          j        }Y nw xY w|t          j        urM|K	 t          | |          }n9# t          $ r, t                              d	| d           t          j        }Y nw xY 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_context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)
rQ   r   emptycallablerB   r   	Exceptionr   warningr   )r   r   s     r    get_field_defaultr     se    eY(9::Gk'''G 	,
,7M22 /''...7$6>> (%gennGG%giiG , , ,  MNS^b  d d d%+,
 ++++0C,7wGG , , ,  GHMX\  ^ ^ ^%+,
 Ns$   AB 3B=<B=C" "3DDr&   )r   Fr   )<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"   rf   rl   r   r   r   r   rW   r   r   r   r   r   r   r   r   r   r   r   r   r    <module>r     s?      # # # # # #              + + + + + + . . . . . . . . i i i i i i i i i i i i 3 3 3 3 3 3 5 5 5 5 5 5 K K K K K K / / / / / / / / ( ( ( ( ( ( * * * * * *OOOO   &&&&&&&    
	8	$	$	 	 	 	 	f 	 	 	
	 	 	 	 	F 	 	 	
  $TuSWjn*.TY]qu!%$$Y]qu-1^ ^ ^ ^B  "! ! !H" " "  % % %   $  $  (   .     0      *   "C C C2    s6   $A) )B/A65B6B =B?B  BB