
     h\                     r   d dl Z d dlZd dlZd dlmZ d dlmZmZ d dl	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 d dlmZ d d	lmZ d
dlmZ d
dlmZ d
dlmZ d
dl m!Z!m"Z"m#Z# d
dlm$Z$m%Z% d
dl&m'Z'm(Z(m)Z)  ej*        e+          Z, ej-        d          Z. G d de          Z G d de/          Z0dS )    N)OrderedDictdefaultdict)
URLPatternURLResolver)
versioning)SchemaGenerator)EndpointEnumerator)endpoint_orderingget_pk_name)get_pk_description)api_settings   )openapi)swagger_settings)SwaggerGenerationError)get_basic_type_infoget_queryset_fieldget_queryset_from_view)ReferenceResolverSwaggerDict)force_real_strget_consumesget_producesz{(?P<parameter>\w+)}c                   P     e Zd Zd
 fd	Z fdZd fd	Zd ZddZd Zd	 Z	 xZ
S )r	   Nc                 h    t          t          |                               ||           || _        d S N)superr	   __init__request)selfpatternsurlconfr   	__class__s       O/var/www/html/Sam_Eipo/venv/lib/python3.11/site-packages/drf_yasg/generators.pyr   zEndpointEnumerator.__init__   s/     $''007CCC    c                     |                     d          rt                              d|           |                     t	          t
          |                               |                    S )N)zEurl pattern does not end in $ ('%s') - unexpected things might happen)endswithloggerwarningunescape_pathr   r	   get_path_from_regex)r    
path_regexr#   s     r$   r,   z&EndpointEnumerator.get_path_from_regex!   s^    s## 	pNNbdnooo!!%(:D"A"A"U"UV`"a"abbbr%    c                 l   t          t          |                               ||          sdS t          | j        dd           }t          |j        dd           }|5t          |t          j                  r|r||	                    d          vrdS t          |j        dt                                dS dS )NFversionversioning_class:swagger_schemaT)r   r	   should_include_endpointgetattrr   cls
issubclassr   NamespaceVersioningsplitobject)	r    pathcallbackapp_name	namespaceurl_namer0   r1   r#   s	           r$   r4   z*EndpointEnumerator.should_include_endpoint&   s    '..FFtXVV 	5$,	488"8<1CTJJ'J7GIg,h,h' 7)//#*>*>>>u8<!1688<<D5tr%   c                 J   t          |j        dd          }|t          |t          j                  rpt          | j        dd          }|rXt          |dd          }d|z  }||vr(t                              d|j        d|d|           |                    ||          }|S )	a"  If ``request.version`` is not ``None`` and `callback` uses ``URLPathVersioning``, this function replaces
        the ``version`` parameter in `path` with the actual version.

        :param str path: the templated path
        :param callback: the view callback
        :rtype: str
        r1   Nr0   version_param{%s}zview z  uses URLPathVersioning but URL z has no param )	r5   r6   r7   r   URLPathVersioningr   r)   inforeplace)r    r;   r<   r1   r0   rA   s         r$   replace_versionz"EndpointEnumerator.replace_version5   s     #8<1CTJJ'J7GIe,f,f'dlIt<<G < '(8/9 U U & 6 ,,KKK#+<<<}}!F G G G||M7;;r%   c           	         || j         }g }|t                      }|D ]}|t          |j                  z   }t	          |t
                    r	 |                     |          }	|j        }
|j        }| 	                    |	|
|pd|pd|          rb| 
                    |	|
          }	|	|v r|                    |	           |                     |
          D ]}|	||
f}|                    |           # t          $ r t                              dd           Y w xY wt	          |t"                    r\|                     |j        ||r|d|j        n|j        |r|d|j        n|j        |          }|                    |           pt                              d                    t1          |                               t3          |t4          	          }|S )
z
        Return a list of all available API endpoints by inspecting the URL conf.

        Copied entirely from super.
        Nr.   zfailed to enumerate viewT)exc_infor2   )r!   prefixr=   r>   ignored_endpointszunknown pattern type {}key)r!   setstrpattern
isinstancer   r,   r<   namer4   rF   addget_allowed_methodsappend	Exceptionr)   r*   r   get_api_endpointsurl_patternsr=   r>   extendformattypesortedr
   )r    r!   rI   r=   r>   rJ   api_endpointsrO   r-   r;   r<   r?   methodendpointnested_endpointss                  r$   rV   z$EndpointEnumerator.get_api_endpointsJ   sA    }H$ #  	P  	PG#go"6"66J':.. PN33J??D&/H&|H33D(HNPRT]Tcacemnn ;#33D(CC  #444$)--d333&*&>&>x&H&H ; ;F(,fh'?H)00::::  N N NNN#=NMMMMMN G[11 
P#'#9#9$1%GOe'2B2BCCU\UeJSjG4E4EFFY`Yj&7 $: $ $  $$%566668??WNNOOOO}2CDDDs   AC1)AC11&DDc                 .    t          j        dd|          S )zzUnescape all backslash escapes from `s`.

        :param str s: string with backslash escapes
        :rtype: str
        z\\(.)z\1)resub)r    ss     r$   unescapezEndpointEnumerator.unescape}   s     vhq)))r%   c                 F   d}|rt                               |          }|s||                     |          z  }ng||                     |d|                                                   z  }||                                z  }||                                d         }||S )a  Remove backslashes escapes from all path components outside {parameters}. This is needed because
        ``simplify_regex`` does not handle this correctly.

        **NOTE:** this might destructively affect some url regex patterns that contain metacharacters (e.g. \w, \d)
        outside path parameter groups; if you are in this category, God help you

        :param str path: path possibly containing
        :return: the unescaped path
        :rtype: str
        r.   N)PATH_PARAMETER_REsearchrd   startgroupend)r    r;   
clean_pathmatchs       r$   r+   z EndpointEnumerator.unescape_path   s     
 	&%,,T22E dmmD111
$--^ekkmm^(<===J%++--'J		%D  	& r%   )NNN)r.   r.   N)Nr.   NNN)__name__
__module____qualname__r   r,   r4   rF   rV   rd   r+   __classcell__)r#   s   @r$   r	   r	      s             c c c c c
       *1 1 1 1f* * *      r%   r	   c                       e Zd ZdZeZeZddZe	d             Z
d Zd Zdd	Z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S )OpenAPISchemaGeneratorz
    This class iterates over all registered API endpoints and returns an appropriate OpenAPI 2.0 compliant schema.
    Method implementations shamelessly stolen and adapted from rest-framework ``SchemaGenerator``.
    r.   Nc                    t          |j        ||                    dd          ||          | _        || _        || _        g | _        g | _        |t          j	        t          j	        }|rgt          j
        |          }|j        dvs|j        st          d          |j        rt                              d|z             dS || j        _        dS dS )a  

        :param openapi.Info info: information about the API
        :param str version: API version string; if omitted, `info.default_version` will be used
        :param str url: API scheme, host and port; if ``None`` is passed and ``DEFAULT_API_URL`` is not set, the url
            will be inferred from the request made against the schema view, so you should generally not need to set
            this parameter explicitly; if the empty string is passed, no host and scheme will be emitted

            If `url` is not ``None`` or the empty string, it must be a scheme-absolute uri (i.e. starting with http://
            or https://), and any path component is ignored;

            See also: :ref:`documentation on base URL construction <custom-spec-base-url>`
        :param patterns: if given, only these patterns will be enumerated for inclusion in the API spec
        :param urlconf: if patterns is not given, use this urlconf to enumerate patterns;
            if not given, the default urlconf is used
        descriptionr.   N)httphttpsz%`url` must be an absolute HTTP(S) urlzKpath component of api base URL %s is ignored; use FORCE_SCRIPT_NAME instead)r   titleget_genrD   r0   consumesproducesr   DEFAULT_API_URLurlparseschemenetlocr   r;   r)   r*   url)r    rD   r0   r   r!   r"   
parsed_urls          r$   r   zOpenAPISchemaGenerator.__init__   s    " $DJTXXmR5P5PRZ\cdd		;+;G"2C 	$!*3//J (999AR9,-TUUU $lorrsssss #		$ 	$r%   c                     | j         j        S r   )ry   r   )r    s    r$   r   zOpenAPISchemaGenerator.url   s    y}r%   c                 L    t           j        }|t          j        |i           }|S )a  Get the security schemes for this API. This determines what is usable in security requirements,
        and helps clients configure their authorization credentials.

        :return: the security schemes usable with this API
        :rtype: dict[str,dict] or None
        )r   SECURITY_DEFINITIONSr   	_as_odict)r    security_definitionss     r$   get_security_definitionsz/OpenAPISchemaGenerator.get_security_definitions   s-      0D+#.#89Mr#R#R ##r%   c                 ~    t           j        }|d |D             }d |D             }t          |t                    }|S )aj  Get the base (global) security requirements of the API. This is never called if
        :meth:`.get_security_definitions` returns `None`.

        :param security_definitions: security definitions as returned by :meth:`.get_security_definitions`
        :return: the security schemes accepted by default
        :rtype: list[dict[str,list[str]]] or None
        Nc                     g | ]}|g iS  r   ).0security_schemes     r$   
<listcomp>zDOpenAPISchemaGenerator.get_security_requirements.<locals>.<listcomp>   s    $g$g$gor%:$g$g$gr%   c                 8    g | ]}t          j        |i           S r   )r   r   )r   srs     r$   r   zDOpenAPISchemaGenerator.get_security_requirements.<locals>.<listcomp>   s%     _ _ _2!6r2!>!> _ _ _r%   rK   )r   SECURITY_REQUIREMENTSr[   list)r    r   security_requirementss      r$   get_security_requirementsz0OpenAPISchemaGenerator.get_security_requirements   sW     !1 F ($g$gRf$g$g$g! _ _I^ _ _ _ &'<$ G G G$$r%   Fc                 6   |                      |          }|                     t          j        d          }t	          t
          j                  | _        t          t
          j	                  | _
        |                     ||||          \  }}|                                 }|r|                     |          }nd}| j        }	|	||                                }	t          j        d| j        || j        pd| j
        pd|||	|| j        d	t'          |          S )a  Generate a :class:`.Swagger` object representing the API schema.

        :param request: the request used for filtering accessible endpoints and finding the spec URI
        :type request: rest_framework.request.Request or None
        :param bool public: if True, all endpoints are included regardless of access through `request`

        :return: the generated Swagger specification
        :rtype: openapi.Swagger
        T)
force_initN)	rD   pathsrz   r{   r   security_url_prefix_versionr   )get_endpointsreference_resolver_classr   SCHEMA_DEFINITIONSr   r   DEFAULT_PARSER_CLASSESrz   r   DEFAULT_RENDERER_CLASSESr{   	get_pathsr   r   r   build_absolute_uriSwaggerrD   r0   dict)
r    r   public	endpoints
componentsr   rI   r   r   r   s
             r$   
get_schemaz!OpenAPISchemaGenerator.get_schema   s)    &&w//	2273MZ^2__
$\%HII$\%JKKy*gvNNv#<<>> 	)$($B$BCW$X$X!!$(!h;7.,,..C 
%$-2G4RVR_Rgcg!5@Uft|
 
 @DJ?O?O
 
 	
r%   c                    | j                             |||          }t          |dd          }|C|                                D ].\  }}t          ||d          }|t	          |j        d|           /t	          |dd           |S )aP  Create a view instance from a view callback as registered in urlpatterns.

        :param callback: view callback registered in urlpatterns
        :param str method: HTTP method
        :param request: request to bind to the view
        :type request: rest_framework.request.Request or None
        :return: the view instance
        _swagger_auto_schemaNswagger_fake_viewT)ry   create_viewr5   itemssetattr__func__)r    r<   r]   r   view	overrides_view_methods           r$   r   z"OpenAPISchemaGenerator.create_view
  s     y$$Xvw??H&<dCC	 &__.. U U	%dFD99*K02H)TTT)4000r%   c                     d|vr|S t          t          |          dd          }|rt          |          }nd}|                    dd|z            S )aK  Coerce {pk} path arguments into the name of the model field, where possible. This is cleaner for an
        external representation (i.e. "this is an identifier", not "this is a database primary key").

        :param str path: the path
        :param rest_framework.views.APIView view: associated view
        :rtype: str
        z{pk}modelNidrB   )r5   r   r   rE   )r    r;   r   r   
field_names        r$   coerce_pathz"OpenAPISchemaGenerator.coerce_path  sc     K.t44gtDD 	$U++JJJ||FFZ$7888r%   c                   	 |                      | j        j        | j        j        |          }|                                }t          t                    }i 	|D ]Z\  }}}|                     |||          }|                     ||          }||         	                    ||f           |j
        	|<   [	fd|                                D             S )a  Iterate over all the registered endpoints in the API and return a fake view with the right parameters.

        :param request: request to bind to the endpoint views
        :type request: rest_framework.request.Request or None
        :return: {path: (view_class, list[(http_method, view_instance)])
        :rtype: dict[str,(type,list[(str,rest_framework.views.APIView)])]
        )r   c                 ,    i | ]\  }}||         |fS r   r   )r   r;   methodsview_clss      r$   
<dictcomp>z8OpenAPISchemaGenerator.get_endpoints.<locals>.<dictcomp>C  s(    XXXMD'x~w/XXXr%   )endpoint_enumerator_classry   r!   r"   rV   r   r   r   r   rT   r6   r   )
r    r   
enumeratorr   
view_pathsr;   r]   r<   r   r   s
            @r$   r   z$OpenAPISchemaGenerator.get_endpoints1  s     33DI4F	HYcj3kk
0022	 &&
&/ 	* 	*"D&(##Hfg>>D##D$//Dt##VTN333%\HTNNXXXXZEUEUEWEWXXXXr%   c                 :    | j                             |||          S )aX  Return a list of keys that should be used to group an operation within the specification. ::

          /users/                   ("users", "list"), ("users", "create")
          /users/{pk}/              ("users", "read"), ("users", "update"), ("users", "delete")
          /users/enabled/           ("users", "enabled")  # custom viewset list action
          /users/{pk}/star/         ("users", "star")     # custom viewset detail action
          /users/{pk}/groups/       ("users", "groups", "list"), ("users", "groups", "create")
          /users/{pk}/groups/{pk}/  ("users", "groups", "read"), ("users", "groups", "update")

        :param str subpath: path to the operation with any common prefix/base path removed
        :param str method: HTTP method
        :param view: the view associated with the operation
        :rtype: list[str]
        )ry   get_keys)r    subpathr]   r   s       r$   get_operation_keysz)OpenAPISchemaGenerator.get_operation_keysE  s     y!!'64888r%   c                 6    | j                             |          S )a  
        Given a list of all paths, return the common prefix which should be
        discounted when generating a schema structure.

        This will be the longest common string that does not include that last
        component of the URL, or the last component before a path parameter.

        For example: ::

            /api/v1/users/
            /api/v1/users/{pk}/

        The path prefix is ``/api/v1/``.

        :param list[str] paths: list of paths
        :rtype: str
        )ry   determine_path_prefixr    r   s     r$   r   z,OpenAPISchemaGenerator.determine_path_prefixV  s    $ y..u555r%   c                 >    |p| j                             |||          S )a  Check if a given endpoint should be included in the resulting schema.

        :param str path: request path
        :param str method: http request method
        :param view: instantiated view callback
        :param bool public: if True, all endpoints are included regardless of access through `request`
        :returns: true if the view should be excluded
        :rtype: bool
        )ry   has_view_permissions)r    r;   r]   r   r   s        r$   r4   z.OpenAPISchemaGenerator.should_include_endpointj  s#     K77fdKKKr%   c                 ,    t          j        |          S )zConstruct the Swagger Paths object.

        :param OrderedDict[str,openapi.PathItem] paths: mapping of paths to :class:`.PathItem` objects
        :returns: the :class:`.Paths` object
        :rtype: openapi.Paths
        r   )r   Pathsr   s     r$   get_paths_objectz'OpenAPISchemaGenerator.get_paths_objectv  s     }5))))r%   c           
         |st          j        i           dfS |                     t          |                                                    pd}d|vs
J d            t                      }t          |                                          D ]\  }\  }}	i }
|	D ]Q\  }}|                     ||||          s| 	                    ||||||          }|||
|
                                <   R|
rK|t          |          d         }|                    d          sd|z   }|                     |||
          ||<   |                     |          |fS )a+  Generate the Swagger Paths for the API from the given endpoints.

        :param dict endpoints: endpoints as returned by get_endpoints
        :param ReferenceResolver components: resolver/container for Swagger References
        :param Request request: the request made against the schema view; can be None
        :param bool public: if True, all endpoints are included regardless of access through `request`
        :returns: the :class:`.Paths` object and the longest common path prefix, as a 2-tuple
        :rtype: tuple[openapi.Paths,str]
        r   r.   {z,base path cannot be templated in swagger 2.0N/)r   r   r   r   keysr   r[   r   r4   get_operationlowerlen
startswithget_path_itemr   )r    r   r   r   r   rI   r   r;   r   r   
operationsr]   r   	operationpath_suffixs                  r$   r   z OpenAPISchemaGenerator.get_paths  s     	/=r***B..++D1A1A,B,BCCIr&   "P   )/	0A0A)B)B 	T 	T%D%8WJ ' ; ;33D&$OO  ..tT66:W^__	(1:Jv||~~. T #3v;;<<0"--c22 4"%"3K%)%7%7h
%S%Sk"$$U++V33r%   c           	         |                      |t          |          d         ||          }|                     ||          }t          j        }	t          |d|	          }	|                    d|	          }	|	dS  |	|||||||          }
|
                    |          }|dS d|v r,t          |j	                  t          | j	                  k    r|`	d|v r,t          |j
                  t          | j
                  k    r|`
|S )a  Get an :class:`.Operation` for the given API endpoint (path, method). This method delegates to
        :meth:`~.inspectors.ViewInspector.get_operation` of a :class:`~.inspectors.ViewInspector` determined
        according to settings and :func:`@swagger_auto_schema <.swagger_auto_schema>` overrides.

        :param view: the view associated with this endpoint
        :param str path: the path component of the operation URL
        :param str prefix: common path prefix among all endpoints
        :param str method: the http method of the operation
        :param openapi.ReferenceResolver components: referenceable components
        :param Request request: the request made against the schema view; can be None
        :rtype: openapi.Operation
        Nr3   auto_schemarz   r{   )r   r   get_overridesr   DEFAULT_AUTO_SCHEMA_CLASSr5   rx   r   rM   rz   r{   )r    r   r;   rI   r]   r   r   operation_keysr   view_inspector_clsview_inspectorr   s               r$   r   z$OpenAPISchemaGenerator.get_operation  s     00c&kkll1CVTRR&&tV44	 .G$T+;=OPP&]]=:LMM%4++D$
GU^`noo"00@@	4""s9+='>'>#dmBTBT'T'T"""s9+='>'>#dmBTBT'T'T"r%   c                 T    |                      ||          }t          j        dd|i|S )a  Get a :class:`.PathItem` object that describes the parameters and operations related to a single path in the
        API.

        :param str path: the path
        :param type view_cls: the view that was bound to this path in urlpatterns
        :param dict[str,openapi.Operation] operations: operations defined on this path, keyed by lowercase HTTP method
        :rtype: openapi.PathItem
        
parametersr   )get_path_parametersr   PathItem)r    r;   r   r   path_parameterss        r$   r   z$OpenAPISchemaGenerator.get_path_item  s5     224BBII?IjIIIr%   c                     |                                 }t          |d|          }t          ||d          }t          |di           }||v r||         }t          j        |          S )a"  Get overrides specified for a given operation.

        :param view: the view associated with the operation
        :param str method: HTTP method
        :return: a dictionary containing any overrides set by :func:`@swagger_auto_schema <.swagger_auto_schema>`
        :rtype: dict
        actionNr   )r   r5   copydeepcopy)r    r   r]   r   action_methodr   s         r$   r   z$OpenAPISchemaGenerator.get_overrides  sj     x00fd33M+A2FF	Y!&)I}Y'''r%   c           	         g }t          |          }t          t          j        |                    D ]	}t	          ||          \  }}t          |          pdt          j        i}t          |dd          |k    r>|d         t          j        k    r(t          |d|	                    dd                    |d<   |rt          |dd          r|j
        }	n&|r"t          |dd          rt          ||          }	nd}	t          j        d|t          |	          d	t          j        d
|}
|                    |
           |S )a  Return a list of Parameter instances corresponding to any templated path variables.

        :param str path: templated request path
        :param type view_cls: the view class associated with the path
        :return: path parameters
        :rtype: list[openapi.Parameter]
        rZ   lookup_fieldNlookup_value_regexrO   	help_textFprimary_keyT)rQ   rt   requiredin_r   )r   r[   uritemplate	variablesr   r   r   TYPE_STRINGr5   rx   r   r   	Parameterr   IN_PATHrT   )r    r;   r   r   querysetvariabler   model_fieldattrsrt   fields              r$   r   z*OpenAPISchemaGenerator.get_path_parameters  sg    
)(33{4T::;; 	% 	%H!3Hh!G!GE;'44UAT8UEx66(BBuV}X_XkGkGk#*85I599U^`dKeKe#f#fi  #w{KGG #)3 #mU!K!K #0DD"% *;77O	 
  E e$$$$r%   )r.   NNN)NFr   )rm   rn   ro   __doc__r	   r   r   r   r   propertyr   r   r   r   r   r   r   r   r   r4   r   r   r   r   r   r   r   r%   r$   rr   rr      sS         !30!$ !$ !$ !$F   X$ $ $% % % 
 
 
 
@   *9 9 9$Y Y Y(9 9 9"6 6 6(
L 
L 
L* * *#4 #4 #4J$ $ $L
J 
J 
J( ( ("! ! ! ! !r%   rr   )1r   loggingra   urllib.parseparser}   collectionsr   r   r   django.urlsr   r   rest_frameworkr   rest_framework.schemasr   !rest_framework.schemas.generatorsr	   _EndpointEnumeratorr
   r   rest_framework.schemas.utilsr   rest_framework.settingsr   r.   r   app_settingsr   errorsr   inspectors.fieldr   r   r   r   r   utilsr   r   r   	getLoggerrm   r)   compilerf   r:   rr   r   r%   r$   <module>r     s     				       0 0 0 0 0 0 0 0     / / / / / / / / % % % % % % 2 2 2 2 2 2 W W W W W W L L L L L L L L ; ; ; ; ; ; 0 0 0 0 0 0       * * * * * * * * * * * * ] ] ] ] ] ] ] ] ] ] 3 3 3 3 3 3 3 3 = = = = = = = = = =		8	$	$BJ677     ,   Dj j j j jV j j j j jr%   