o
    -gbj                     @   s  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 de#Z)G dd de%Z*dS )    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                   @   s&   e Zd Zdd Zdd Zd	ddZdS )
SchemaGeneratorc                 C   s.   | j pd| jpdd}| jd ur| j|d< |S )N )titleversiondescription)r   r    r!   )selfinfo r$   _/var/www/html/django-vendor/venv/lib/python3.10/site-packages/rest_framework/schemas/openapi.pyget_info   s   

zSchemaGenerator.get_infoc                 C   s   i }|D ]:}|| D ]3}d|| | vrq
|| | d }||v r6t dj|| d || d |||d ||d||< q
qd S )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)   r.   r$   r$   r%   check_duplicate_operation_id(   s,   

z,SchemaGenerator.check_duplicate_operation_idNFc                 C   s  |    i }i }| |rdn|\}}|D ]^\}}}	| |||	s"q|	j||}
|	j||}| D ]}||vr;q4|| || krDq4td	| q4|
| |dr]|dd }t| jpbd|}||i  |
|| | < q| | d|  |d}t|dkrd|i|d	< |S )
z,
        Generate a OpenAPI schema.
        NzASchema component "{}" has been overridden with a different value./r   z3.0.2)openapir#   r2   r   schemas
components)_initialise_endpoints_get_paths_and_endpointshas_view_permissionsschemaget_operationget_componentskeysr/   r0   r1   update
startswithr   url
setdefaultlowerr4   r&   len)r"   requestpubliccomponents_schemasr2   _view_endpointspathr)   view	operationr8   kr<   r$   r$   r%   
get_schemaB   s<   


zSchemaGenerator.get_schema)NF)__name__
__module____qualname__r&   r4   rO   r$   r$   r$   r%   r      s    r   c                       s  e Zd Zd@ fdd	Zg Zg Zdddddd	Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Z d>d? Z!  Z"S )A
AutoSchemaNc                    s>   |rt dd |D std|| _|| _|| _t   dS )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                 s       | ]}t |tV  qd S N
isinstancestr).0tagr$   r$   r%   	<genexpr>}       z&AutoSchema.__init__.<locals>.<genexpr>z'tags must be a list or tuple of string.N)all
ValueError_tagsoperation_id_basecomponent_namesuper__init__)r"   tagsr`   ra   	__class__r$   r%   rc   x   s   zAutoSchema.__init__retrievecreater@   partialUpdatedestroy)getpostputpatchdeletec                 C   s   i }|  |||d< | |||d< g }|| ||7 }|| ||7 }|| ||7 }||d< | ||}|r<||d< | |||d< | |||d< |S )Nr'   r!   
parametersrequestBody	responsesrd   )get_operation_idget_descriptionget_path_parametersget_pagination_parametersget_filter_parametersget_request_bodyget_responsesget_tags)r"   rK   r)   rM   rp   request_bodyr$   r$   r%   r=      s   zAutoSchema.get_operationc                 C   sP   | j dur| j S |jj}tdtj}|d|}|dkr&td|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).
        N
serializerr   z"{}" is an invalid class name for schema generation. Serializer's class name should be unique and explicit. e.g. "ItemSerializer")	ra   rf   rP   recompile
IGNORECASEsub	Exceptionr1   )r"   r|   ra   patternr$   r$   r%   get_component_name   s   

zAutoSchema.get_component_namec                 C   s   |  dkri S | ||}| ||}i }t|tjr,| |}| |}||| t|tjrB| |}| |}||| |S )zN
        Return components with their properties from the serializer.
        ro   )	rD   get_request_serializerget_response_serializerrW   r   
Serializerr   map_serializerrC   )r"   rK   r)   request_serializerresponse_serializerr8   ra   contentr$   r$   r%   r>      s   



zAutoSchema.get_componentsc                 C   s.   | d}|d ddd |dd  D  S )NrI   r   r   c                 s   s    | ]}|  V  qd S rU   )r   )rY   xr$   r$   r%   r[      s    z,AutoSchema._to_camel_case.<locals>.<genexpr>r   )splitjoin)r"   	snake_strr8   r$   r$   r%   _to_camel_case   s   
$zAutoSchema._to_camel_casec                 C   s   t t | jdddd}| jdur| j}nP|dur|j}nH| ||dur8| ||jj}|dr7|dd }n,| jjj}|drI|dd }n|drT|dd	 }|| rd|dt|  }|d
krst	snJ dt	
|}|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.)getattrrL   r`   rP   get_serializerrf   endswithr   rE   r   	pluralize)r"   rK   r)   actionr   namer$   r$   r%   get_operation_id_base   s*   





z AutoSchema.get_operation_id_basec                 C   s`   t | jd| }t||| jrd}n|| jvr| |}n| j|  }| |||}|| S )z^
        Compute an operation ID from the view type and get_operation_id_base method.
        r   r   )r   rL   rD   r   method_mappingr   r   )r"   rK   r)   method_namer   r   r$   r$   r%   rs      s   
zAutoSchema.get_operation_idc           	   	   C   s   t sJ dtt| jdddd}g }t |D ]D}d}|durMz|j|}W n ty3   d}Y nw |durA|jrAt|j}n|durM|j	rMt
||}|dd|dd	id
}|| q|S )zL
        Return a list of parameters from templated path variables.
        z;`uritemplate` must be installed for OpenAPI schema support.r   Nr   r   rK   Ttypestring)r   inrequiredr!   r<   )r   r   rL   	variables_meta	get_fieldr   	help_textr   primary_keyr   append)	r"   rK   r)   r   rp   variabler!   model_field	parameterr$   r$   r%   ru     s0   
	zAutoSchema.get_path_parametersc                 C   s8   |  ||sg S g }| jjD ]}|| | j7 }q|S rU   )allows_filtersrL   filter_backendsget_schema_operation_parameters)r"   rK   r)   rp   filter_backendr$   r$   r%   rw   3  s   z AutoSchema.get_filter_parametersc                 C   s:   t | jdddu rdS t| jdr| jjdv S | 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   rg   r@   partial_updaterj   )rk   rm   rn   ro   )r   rL   hasattrr   rD   r"   rK   r)   r$   r$   r%   r   ;  s
   zAutoSchema.allows_filtersc                 C   s0   | j }t|||sg S |  }|sg S ||S rU   )rL   r   get_paginatorr   )r"   rK   r)   rL   	paginatorr$   r$   r%   rv   H  s   
z$AutoSchema.get_pagination_parametersc                 C   s   t t|j}tdd |D rd}n&tdd |D r d}ntdd |D r,d}ntdd |D r8d	}nd }d
|i}|rD||d< |S )Nc                 s   rT   rU   )rW   boolrY   choicer$   r$   r%   r[   V  r\   z-AutoSchema.map_choicefield.<locals>.<genexpr>booleanc                 s   rT   rU   )rW   intr   r$   r$   r%   r[   X  r\   integerc                 s   s     | ]}t |tttfV  qd S rU   )rW   r   floatr   r   r$   r$   r%   r[   Z  s    numberc                 s   rT   rU   rV   r   r$   r$   r%   r[   ]  r\   r   enumr   )r   dictfromkeyschoicesr]   )r"   fieldr   r   mappingr$   r$   r%   map_choicefieldT  s   
zAutoSchema.map_choicefieldc                 C   s  t |tjrd| |jdS t |tjr | |}d|d< |S t |tjr/d| |jdS t |tj	r[t
|ddrB| j|jdS t
|jdd }|d ur[|jj}t |tjr[dd	iS t |tjrid| |dS t |tjrt| |S t |tjrdi d}t |jts| |j|d
< |S t |tjrdddS t |tjrdddS t |tjrdddS t |tjrdddS t |tjrdddS t |tjrddi}|jdkr|j|d< |S t |tjr%t
|dtjrddd}nddi}|j rt!d|j d d  d |d< |j"rt#|j"d d |d< |d  |d< | $|| |S t |tj%r8ddi}| $|| |S t |tj&redd	i}| $|| t#|'ddd ks_t#|'ddd krcd!|d< |S t |tj(rqdd"dS tj)d#tj*dtj+dtj,di}d|'|j-diS )$Narrayr   itemsobjectr   pk_fieldF)r   r   r   r   r   date)r   r1   z	date-timeemailuriuuidbothr1   coerce_to_stringdecimalr   .r   01
multipleOf9maximumminimumr   iint64binaryr   ).rW   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IntegerFieldrk   	FileFieldBooleanField	JSONField	DictFieldHStoreFieldrf   )r"   r   datar   r   r   r   FIELD_CLASS_SCHEMA_TYPEr$   r$   r%   r   p  s   





,zAutoSchema.map_fieldc                 C   s(   |j r|j |d< |jr|j|d< d S d S )Nr   r   )	max_value	min_value)r"   r   r   r$   r$   r%   r      s
   
zAutoSchema._map_min_maxc                 C   s   g }i }|j  D ]\}t|tjrq	|jr |js || | | 	|}|j
r,d|d< |jr3d|d< |jr:d|d< |jd urN|jtkrNt|jsN|j|d< |jrXt|j|d< | || ||| |< q	d|d}|rq||d	< |S )
NTreadOnly	writeOnlynullabledefaultr!   r   )r   
propertiesr   )fieldsvaluesrW   r   HiddenFieldr   partialr   get_field_namer   	read_only
write_only
allow_nullr   r   callabler   rX   map_field_validators)r"   r|   r   r   r   r<   resultr$   r$   r%   r     s4   

zAutoSchema.map_serializerc                 C   s\  |j D ]}t|trd|d< t|trd|d< t|tr'|jjdd|d< qt|tr<d}t|t	j
r6d}|j||< qt|trQd	}t|t	j
rKd
}|j||< qt|tr\|j|d< qt|trg|j|d< qt|trt|dtjs|jrtd|jd d  d |d< |jr|j}|jdur|jdkr||j8 }t|d d |d< |d  |d< qdS )z&
        map field validators
        r   r1   r   z\Zz\zr   	maxLengthmaxItems	minLengthminItemsr   r   r   r   r   r   r   r   Nr   r   )
validatorsrW   r   r   r   regexr   replacer   r   r   limit_valuer	   r   r
   r   r   r   r   r   r   
max_digitsr   )r"   r   r<   v	attr_namedigitsr$   r$   r%   r	  *  sD   









zAutoSchema.map_field_validatorsc                 C   s   |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   r$   r$   r%   r  R  s   zAutoSchema.get_field_namec                 C   s   t | jdd }|r| S d S )Npagination_class)r   rL   )r"   r  r$   r$   r%   r   Y  s   zAutoSchema.get_paginatorc                 C   s   t ttd| jjS )N
media_type)r   mapr   rL   parser_classesr   r$   r$   r%   map_parsers_  s   zAutoSchema.map_parsersc                 C   s0   g }| j jD ]}t|tjrq||j q|S rU   )rL   renderer_classes
issubclassr   BrowsableAPIRendererr   r  )r"   rK   r)   media_typesrendererr$   r$   r%   map_renderersb  s   zAutoSchema.map_renderersc              
   C   sN   | j }t|ds
d S z| W S  tjy&   td|jj	|| Y d S w )Nr   zt{}.get_serializer() raised an exception during schema generation. Serializer fields will not be generated for {} {}.)
rL   r   r   r   APIExceptionr/   r0   r1   rf   rP   )r"   rK   r)   rL   r$   r$   r%   r   k  s   

zAutoSchema.get_serializerc                 C      |  ||S )zr
        Override this method if your view uses a different serializer for
        handling request body.
        r   r   r$   r$   r%   r   z     z!AutoSchema.get_request_serializerc                 C   r$  )zu
        Override this method if your view uses a different serializer for
        populating response data.
        r%  r   r$   r$   r%   r     r&  z"AutoSchema.get_response_serializerc                 C   s   dd | |iS )Nz$refz#/components/schemas/{})r1   r   r"   r|   r$   r$   r%   get_reference  s   zAutoSchema.get_referencec                    sZ   |dvri S |  ||| _| ||}t|tjsi  n| | d fdd| jD iS )N)PUTPATCHPOSTr   c                       i | ]}|d  iqS r<   r$   rY   ctitem_schemar$   r%   
<dictcomp>      z/AutoSchema.get_request_body.<locals>.<dictcomp>)r  request_media_typesr   rW   r   r   r(  )r"   rK   r)   r|   r$   r0  r%   rx     s   
zAutoSchema.get_request_bodyc                    s   |dkr
dddiiS |  ||| _| ||}t|tjs i }n| |}t||| jr=d|d | 	 }|r<|
  n| |dkrEdnd	}| fd
d| jD ddiS )NDELETE204r!   r   r   r   r+  201200c                    r,  r-  r$   r.  response_schemar$   r%   r2    r3  z,AutoSchema.get_responses.<locals>.<dictcomp>)r   r!   )r"  response_media_typesr   rW   r   r   r(  r   rL   r   get_paginated_response_schema)r"   rK   r)   r|   r1  r   status_coder$   r9  r%   ry     s6   


zAutoSchema.get_responsesc                 C   s:   | j r| j S |dr|dd  }|dd ddgS )Nr5   r   r   rI   -)r_   rA   r   r  r   r$   r$   r%   rz     s
   
zAutoSchema.get_tagsc                 C   s   t jdtdd | |S )NzkMethod `_get_reference()` has been renamed to `get_reference()`. The old name will be removed in DRF v3.16.   )
stacklevel)r/   r0   r   r(  r'  r$   r$   r%   _get_reference  s
   
zAutoSchema._get_reference)NNN)#rP   rQ   rR   rc   r4  r;  r   r=   r   r>   r   r   rs   ru   rw   r   rv   r   r   r   r   r	  r  r   r  r"  r   r   r   r(  rx   ry   rz   rA  __classcell__r$   r$   re   r%   rS   v   sL    &$ $(	)rS   )+r}   r/   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   rS   r$   r$   r$   r%   <module>   s"    (\