
    Nwgbj                        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	m
Z
mZmZmZmZmZmZ d dlmZ d dlmZ d dlmZmZmZmZ d d	lmZmZ d d
lmZmZ d dl m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z'm(Z(  G d de#      Z) G d de%      Z*y)    N)Decimal)
attrgetter)urljoin)DecimalValidatorEmailValidatorMaxLengthValidatorMaxValueValidatorMinLengthValidatorMinValueValidatorRegexValidatorURLValidator)models)	force_str)RemovedInDRF316Warning
exceptions	renderersserializers)
inflectionuritemplate)_UnvalidatedFieldempty)api_settings   )BaseSchemaGenerator)ViewInspector)get_pk_descriptionis_list_viewc                        e Zd Zd Zd ZddZy)SchemaGeneratorc                 ~    | j                   xs d| j                  xs dd}| j                  | j                  |d<   |S )N )titleversiondescription)r"   r#   r$   )selfinfos     U/var/www/horilla/myenv/lib/python3.12/site-packages/rest_framework/schemas/openapi.pyget_infozSchemaGenerator.get_info   sF     ZZ%2||)r

 '"&"2"2D    c                     i }|D ]c  }||   D ]Y  }d||   |   vr||   |   d   }||v r5t        j                  dj                  ||   d   ||   d   |||             ||d||<   [ e y )NoperationIdzYou have a duplicated operationId in your OpenAPI schema: {operation_id}
	Route: {route1}, Method: {method1}
	Route: {route2}, Method: {method2}
	An operationId has to be unique across your schema. Your schema may not work in other tools.routemethod)route1method1route2method2operation_id)r,   r-   )warningswarnformat)r%   pathsidsr,   r-   r2   s         r'   check_duplicate_operation_idz,SchemaGenerator.check_duplicate_operation_id(   s     	E,  eV(<<$U|F3MB3&MMy  #&|#4W#=$'$5h$?#($*)5    #$%L!%	r)   Nc                    | j                          i }i }| j                  |rdn|      \  }}|D ]  \  }}}	| j                  |||	      s|	j                  j	                  ||      }
|	j                  j                  ||      }|j                         D ]7  }||vr||   ||   k(  rt        j                  dj                  |             9 |j                  |       |j                  d      r|dd }t        | j                  xs d|      }|j                  |i        |
||   |j                         <   	 | j!                  |       d| j#                         |d}t%        |      dkD  rd|i|d	<   |S )
z,
        Generate a OpenAPI schema.
        NzASchema component "{}" has been overridden with a different value./r   z3.0.2)openapir&   r6   r   schemas
components)_initialise_endpoints_get_paths_and_endpointshas_view_permissionsschemaget_operationget_componentskeysr3   r4   r5   update
startswithr   url
setdefaultlowerr8   r(   len)r%   requestpubliccomponents_schemasr6   _view_endpointspathr-   view	operationr=   krA   s                 r'   
get_schemazSchemaGenerator.get_schemaB   s    	""$  99&$gV>"0 	4D&$,,T64@11$?I33D&AJ__& m..%a(JqM9ahhijklm %%j1 s#ABx488?sD1DT2&*3E$K'+	4. 	))%0 MMO
 !"Q&-$F<  r)   )NF)__name__
__module____qualname__r(   r8   rT    r)   r'   r   r      s    
4/r)   r   c                        e Zd Zd# fd	Zg Zg ZddddddZd Zd	 Zd
 Z	d Z
d Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd  Zd! Z d" Z! xZ"S )$
AutoSchemac                     |rt        d |D              st        d      || _        || _        || _        t
        |           y)a  
        :param operation_id_base: user-defined name in operationId. If empty, it will be deducted from the Model/Serializer/View name.
        :param component_name: user-defined component's name. If empty, it will be deducted from the Serializer's class name.
        c              3   <   K   | ]  }t        |t                y wN
isinstancestr).0tags     r'   	<genexpr>z&AutoSchema.__init__.<locals>.<genexpr>}   s     ASJsC0A   z'tags must be a list or tuple of string.N)all
ValueError_tagsoperation_id_basecomponent_namesuper__init__)r%   tagsrh   ri   	__class__s       r'   rk   zAutoSchema.__init__x   sC    
 ADAAFGG
!2,r)   retrievecreaterE   partialUpdatedestroy)getpostputpatchdeletec                 p   i }| j                  ||      |d<   | j                  ||      |d<   g }|| j                  ||      z  }|| j                  ||      z  }|| j	                  ||      z  }||d<   | j                  ||      }|r||d<   | j                  ||      |d<   | j                  ||      |d<   |S )Nr+   r$   
parametersrequestBody	responsesrl   )get_operation_idget_descriptionget_path_parametersget_pagination_parametersget_filter_parametersget_request_bodyget_responsesget_tags)r%   rP   r-   rR   rx   request_bodys         r'   rB   zAutoSchema.get_operation   s    	#'#8#8v#F	- #'#7#7f#E	- 
d..tV<<
d44T6BB
d00v>>
",	,,,T6:'3Im$!%!3!3D&!A	+ MM$7	&r)   c                 4   | j                   | j                   S |j                  j                  }t        j                  dt        j
                        }|j                  d|      }|dk(  r.t        dj                  |j                  j                              |S )z
        Compute the component's name from the serializer.
        Raise an exception if the serializer's class name is "Serializer" (case-insensitive).
        
serializerr!   z"{}" is an invalid class name for schema generation. Serializer's class name should be unique and explicit. e.g. "ItemSerializer")	ri   rm   rU   recompile
IGNORECASEsub	Exceptionr5   )r%   r   ri   patterns       r'   get_component_namezAutoSchema.get_component_name   s    
 *&&& $--66**\2==9 R8R`
,,556  r)   c                    |j                         dk(  ri S | j                  ||      }| j                  ||      }i }t        |t        j
                        r4| j                  |      }| j                  |      }|j                  ||       t        |t        j
                        r4| j                  |      }| j                  |      }|j                  ||       |S )zN
        Return components with their properties from the serializer.
        rv   )	rI   get_request_serializerget_response_serializerr_   r   
Serializerr   map_serializerrH   )r%   rP   r-   request_serializerresponse_serializerr=   ri   contents           r'   rC   zAutoSchema.get_components   s    
 <<>X%I!88vF"::4H
(+*@*@A!445GHN))*<=G!!.':);+A+AB!445HIN))*=>G!!.':r)   c                 f    |j                  d      }|d   dj                  d |dd  D              z   S )NrN   r   r!   c              3   <   K   | ]  }|j                           y wr]   )r"   )ra   xs     r'   rc   z,AutoSchema._to_camel_case.<locals>.<genexpr>   s     &IQqwwy&Ird   r   )splitjoin)r%   	snake_strr=   s      r'   _to_camel_casezAutoSchema._to_camel_case   s6    __S)
 !}rww&I*QR.&IIIIr)   c                 |   t        t        | j                  dd      dd      }| j                  | j                  }n||j                  }n| j	                  ||      =| j	                  ||      j
                  j                  }|j                  d      r|dd }n{| j                  j
                  j                  }|j                  d      r|dd }n|j                  d      r|dd	 }|j                  |j                               r|dt        |        }|d
k(  r"t        sJ d       t        j                  |      }|S )za
        Compute the base part for operation ID from the model, serializer or view name.
        querysetNmodelr   iAPIViewiViewlistz:`inflection` must be installed for OpenAPI schema support.)getattrrQ   rh   rU   get_serializerrm   endswithr"   rJ   r   	pluralize)r%   rP   r-   actionr   names         r'   get_operation_id_basez AutoSchema.get_operation_id_base   s'    		:t<gtL!!-))D >>D   v.:&&tV4>>GGD}}\*DSz 99&&//D}}Y'CRyv&CRy }}V\\^,Mc&k\*V[[[:''-Dr)   c                 *   t        | j                  d|j                               }t        ||| j                        rd}n=|| j                  vr| j                  |      }n| j                  |j                            }| j                  |||      }||z   S )z^
        Compute an operation ID from the view type and get_operation_id_base method.
        r   r   )r   rQ   rI   r   method_mappingr   r   )r%   rP   r-   method_namer   r   s         r'   r{   zAutoSchema.get_operation_id   s     dii6<<>Bfdii0F 3 33((5F((8F))$?}r)   c                    t         sJ d       t        t        | j                  dd      dd      }g }t        j                  |      D ]{  }d}|Z	 |j                  j                  |      }|"|j                  rt        |j                        }n||j                  rt        ||      }|dd|dd	id
}|j                  |       } |S # t        $ r d}Y jw xY w)zL
        Return a list of parameters from templated path variables.
        z;`uritemplate` must be installed for OpenAPI schema support.r   Nr   r!   rP   Ttypestring)r   inrequiredr$   rA   )r   r   rQ   	variables_meta	get_fieldr   	help_textr   primary_keyr   append)	r%   rP   r-   r   rx   variabler$   model_field	parameters	            r'   r}   zAutoSchema.get_path_parameters  s     YYY{		:t<gtL
#--d3 	)HK '"'++"7"7"AK *{/D/D"+K,A,A"BK ,1H1H"4UK"HK ! *HI i(/	)2 ' ! '"&K's   CCCc                     | j                  ||      sg S g }| j                  j                  D ]%  }| |       j                  | j                        z  }' |S r]   )allows_filtersrQ   filter_backendsget_schema_operation_parameters)r%   rP   r-   rx   filter_backends        r'   r   z AutoSchema.get_filter_parameters3  sY    ""40I
"ii77 	VN.*JJ499UUJ	Vr)   c                     t        | j                  dd      yt        | j                  d      r| j                  j                  dv S |j	                         dv S )z
        Determine whether to include filter Fields in schema.

        Default implementation looks for ModelViewSet or GenericAPIView
        actions/methods that cause filtering on the default implementation.
        r   NFr   )r   rn   rE   partial_updaterq   )rr   rt   ru   rv   )r   rQ   hasattrr   rI   r%   rP   r-   s      r'   r   zAutoSchema.allows_filters;  sQ     499/6>499h'99##'bbb||~!BBBr)   c                     | j                   }t        |||      sg S | j                         }|sg S |j                  |      S r]   )rQ   r   get_paginatorr   )r%   rP   r-   rQ   	paginators        r'   r~   z$AutoSchema.get_pagination_parametersH  sC    yyD&$/I&&(	I88>>r)   c                    t        t        j                  |j                              }t	        d |D              rd}nAt	        d |D              rd}n,t	        d |D              rd}nt	        d |D              rd}nd }d	|i}|r||d
<   |S )Nc              3   <   K   | ]  }t        |t                y wr]   )r_   boolra   choices     r'   rc   z-AutoSchema.map_choicefield.<locals>.<genexpr>V  s     >Fz&$'>rd   booleanc              3   <   K   | ]  }t        |t                y wr]   )r_   intr   s     r'   rc   z-AutoSchema.map_choicefield.<locals>.<genexpr>X       ?VFC(?rd   integerc              3   R   K   | ]  }t        |t        t        t        f       ! y wr]   )r_   r   floatr   r   s     r'   rc   z-AutoSchema.map_choicefield.<locals>.<genexpr>Z  s     QvFS%$9:Qs   %'numberc              3   <   K   | ]  }t        |t                y wr]   r^   r   s     r'   rc   z-AutoSchema.map_choicefield.<locals>.<genexpr>]  r   rd   r   enumr   )r   dictfromkeyschoicesre   )r%   fieldr   r   mappings        r'   map_choicefieldzAutoSchema.map_choicefieldT  s    t}}U]]34>g>>D?w??DQQQD?w??DD
 G
 "GFOr)   c                 0	   t        |t        j                        rd| j                  |j                        dS t        |t        j
                        r| j                  |      }d|d<   |S t        |t        j                        rd| j                  |j                        dS t        |t        j                        rvt        |dd      r| j                  |j                        S t        |j                  dd       }|4|j                  j                  }t        |t        j                         rdd	iS t        |t        j"                        rd| j%                  |      dS t        |t        j&                        r| j%                  |      S t        |t        j(                        r?di d}t        |j                  t*              s| j                  |j                        |d
<   |S t        |t        j,                        rdddS t        |t        j.                        rdddS t        |t        j0                        rdddS t        |t        j2                        rdddS t        |t        j4                        rdddS t        |t        j6                        r$ddi}|j8                  dk7  r|j8                  |d<   |S t        |t        j:                        rt        |dt<        j>                        rddd}nddi}|j@                  r$tC        d|j@                  dz
  dz  z   dz         |d<   |jD                  r'tG        |jD                  dz        dz   |d<   |d    |d<   | jI                  ||       |S t        |t        jJ                        rddi}| jI                  ||       |S t        |t        jL                        rYdd	i}| jI                  ||       tG        |jO                  dd            d kD  stG        |jO                  dd            d kD  rd!|d<   |S t        |t        jP                        rdd"dS t        jR                  d#t        jT                  dt        jV                  dt        jX                  di}d|jO                  |jZ                  d      iS )$Narrayr   itemsobjectr   pk_fieldF)r   r   r   r   r   date)r   r5   z	date-timeemailuriuuidbothr5   coerce_to_stringdecimalr   .r   01
multipleOf9maximumminimumr   iint64binaryr   ).r_   r   ListSerializerr   childr   ManyRelatedField	map_fieldchild_relationPrimaryKeyRelatedFieldr   r   r   r   pkr   	AutoFieldMultipleChoiceFieldr   ChoiceField	ListFieldr   	DateFieldDateTimeField
EmailFieldURLField	UUIDFieldIPAddressFieldprotocolDecimalFieldr   COERCE_DECIMAL_TO_STRINGdecimal_placesr   max_whole_digitsr   _map_min_max
FloatFieldIntegerFieldrr   	FileFieldBooleanField	JSONField	DictFieldHStoreFieldrm   )r%   r   datar   r   r   r   FIELD_CLASS_SCHEMA_TYPEs           r'   r   zAutoSchema.map_fieldp  se    e[778,,U[[9  e[334&&u-D#DLK e[99:(<(<=  e[??@uj%0~~ENN~;;ENNGT:E #kknnk6+;+;<"I.. e[<<=--e4 
 e[445''.. e[223G ekk+<=#'>>%++#> N e[223   
 e[667 %  e[334 ! 
 e[112  
 e[223   
 e[778G ~~'$)NN!Ne[556u0,2W2WX$' H ##(-cU5I5IA5MQT4T.TWZ.Z([%%%%()?)?#)E%F%J	"&-i&8%8	"eW-Ne[334G eW-Ne[556	G eW-7;;y!,-
:c'++iYZB[>\_i>i$+!Ne[223 "  $$i!!8!!8##X	#
 /33EOOXNOOr)   c                 r    |j                   r|j                   |d<   |j                  r|j                  |d<   y y )Nr   r   )	max_value	min_value)r%   r   r   s      r'   r  zAutoSchema._map_min_max   s1    ??!&GI??!&GI r)   c                    g }i }|j                   j                         D ]'  }t        |t        j                        r|j
                  r,|j                  s |j                  | j                  |             | j                  |      }|j                  rd|d<   |j                  rd|d<   |j                  rd|d<   |j                  7|j                  t        k7  r$t        |j                        s|j                  |d<   |j                   rt#        |j                         |d<   | j%                  ||       ||| j                  |      <   * d|d}|r||d	<   |S )
NTreadOnly	writeOnlynullabledefaultr$   r   )r   
propertiesr   )fieldsvaluesr_   r   HiddenFieldr   partialr   get_field_namer   	read_only
write_only
allow_nullr  r   callabler   r`   map_field_validators)r%   r   r   r  r   rA   results          r'   r   zAutoSchema.map_serializer  s;   
&&--/ 	<E%!8!89~~j&8&8 3 3E :;^^E*F%)z"&*{#%)z"}}(U]]e-CHUZUbUbLc$)MMy!(+EOO(<}%%%eV45;Jt**512)	<. $
 !)F:r)   c                    |j                   D ]  }t        |t              rd|d<   t        |t              rd|d<   t        |t              r*|j
                  j                  j                  dd      |d<   ht        |t              r.d}t        |t        j                        rd}|j                  ||<   t        |t              r.d	}t        |t        j                        rd
}|j                  ||<   t        |t              r|j                  |d<   t        |t              r|j                  |d<   &t        |t              s8t!        |dt"        j$                        rU|j&                  r$t)        d|j&                  dz
  dz  z   dz         |d<   |j*                  s|j*                  }|j&                  |j&                  dkD  r||j&                  z  }t-        |dz        dz   |d<   |d    |d<    y)z&
        map field validators
        r   r5   r   z\Zz\zr   	maxLengthmaxItems	minLengthminItemsr   r   r   r   r   r   r   r   Nr   r   )
validatorsr_   r   r   r   regexr   replacer   r   r   limit_valuer
   r	   r   r   r   r   r  r  r   
max_digitsr   )r%   r   rA   v	attr_namedigitss         r'   r$  zAutoSchema.map_field_validators*  s    !! "	;A !^,#*x !\*#(x !^, %&GGOO$;$;E5$Iy!A12'	e[%:%:; *I$%MMy!A12'	e[%:%:; *I$%MMy!A01$%MMy!A01$%MMy!A/0'9<;`;`a##+08H8H18LPS7S1SVY1Y+ZF<(<<\\F''38H8H18L!"2"22(+FSL(9A(=F9%)/	):(:F9%E"	;r)   c                     |j                   S )z
        Override this method if you want to change schema field name.
        For example, convert snake_case field name to camelCase.
        )
field_name)r%   r   s     r'   r  zAutoSchema.get_field_nameR  s    
 r)   c                 D    t        | j                  dd       }|r |       S y )Npagination_class)r   rQ   )r%   r6  s     r'   r   zAutoSchema.get_paginatorY  s%    "499.@$G#%%r)   c                 f    t        t        t        d      | j                  j                              S )N
media_type)r   mapr   rQ   parser_classesr   s      r'   map_parserszAutoSchema.map_parsers_  s#    C
<0$))2J2JKLLr)   c                     g }| j                   j                  D ]8  }t        |t        j                        r|j                  |j                         : |S r]   )rQ   renderer_classes
issubclassr   BrowsableAPIRendererr   r8  )r%   rP   r-   media_typesrenderers        r'   map_rendererszAutoSchema.map_renderersb  sO    		22 	4H(I$B$BCx223		4
 r)   c                     | j                   }t        |d      sy 	 |j                         S # t        j                  $ r= t        j                  dj                  |j                  j                  ||             Y y w xY w)Nr   zt{}.get_serializer() raised an exception during schema generation. Serializer fields will not be generated for {} {}.)
rQ   r   r   r   APIExceptionr3   r4   r5   rm   rU   )r%   rP   r-   rQ   s       r'   r   zAutoSchema.get_serializerk  ss    yyt-.	&&((&& 	MM 1 "6$.."9"964HJ 	s   + AA;:A;c                 &    | j                  ||      S )zr
        Override this method if your view uses a different serializer for
        handling request body.
        r   r   s      r'   r   z!AutoSchema.get_request_serializerz      
 ""400r)   c                 &    | j                  ||      S )zu
        Override this method if your view uses a different serializer for
        populating response data.
        rF  r   s      r'   r   z"AutoSchema.get_response_serializer  rG  r)   c                 F    ddj                  | j                  |            iS )Nz$refz#/components/schemas/{})r5   r   r%   r   s     r'   get_referencezAutoSchema.get_reference  s%    1889P9PQ[9\]^^r)   c                    |dvri S | j                  ||      | _        | j                  ||      }t        |t        j
                        si }n| j                  |      }d| j                  D ci c]  }|d|i	 c}iS c c}w )N)PUTPATCHPOSTr   rA   )r;  request_media_typesr   r_   r   r   rK  )r%   rP   r-   r   item_schemacts         r'   r   zAutoSchema.get_request_body  s    11I#'#3#3D&#A 00v>
*k&<&<=K,,Z8K 22 X{++
 	
s   -A=c                    |dk(  rdddiiS | j                  ||      | _        | j                  ||      }t        |t        j
                        si }n| j                  |      }t        ||| j                        r)d|d}| j                         }|r|j                  |      }n|}|dk(  rdnd	}|| j                  D ci c]  }|d
|i	 c}ddiS c c}w )NDELETE204r$   r!   r   r   rO  201200rA   )r   r$   )rB  response_media_typesr   r_   r   r   rK  r   rQ   r   get_paginated_response_schema)	r%   rP   r-   r   rQ  response_schemar   status_coderR  s	            r'   r   zAutoSchema.get_responses  s   X!2  %)$6$6tV$D!11$?
*k&<&<=K,,Z8Kfdii0$O **,I"+"I"I/"Z)O%/eU #77 ?33  "	
 	
s   =Cc                     | j                   r| j                   S |j                  d      r|dd  }|j                  d      d   j                  dd      gS )Nr:   r   r   rN   -)rg   rF   r   r-  r   s      r'   r   zAutoSchema.get_tags  sO    ::::
 ??38D

3"**3455r)   c                 \    t        j                  dt        d       | j                  |      S )NzkMethod `_get_reference()` has been renamed to `get_reference()`. The old name will be removed in DRF v3.16.   )
stacklevel)r3   r4   r   rK  rJ  s     r'   _get_referencezAutoSchema._get_reference  s+    9"q	

 !!*--r)   )NNN)#rU   rV   rW   rk   rP  rX  r   rB   r   rC   r   r   r{   r}   r   r   r~   r   r   r  r   r$  r  r   r;  rB  r   r   r   rK  r   r   r   ra  __classcell__)rm   s   @r'   rZ   rZ   v   s    
   N(.2J$L "HC
?8NP`1"H&;P M11_
('
R6.r)   rZ   )+r   r3   r   r   operatorr   urllib.parser   django.core.validatorsr   r   r   r	   r
   r   r   r   	django.dbr   django.utils.encodingr   rest_frameworkr   r   r   r   rest_framework.compatr   r   rest_framework.fieldsr   r   rest_framework.settingsr   
generatorsr   
inspectorsr   utilsr   r   r   rZ   rX   r)   r'   <module>ro     sg    	         +  : : 0 + % 3W) Wxe	. e	.r)   