o
    [d|                     @   s  d Z ddlZddlZddlZddlZzddlZW n ey%   ddlZY nw 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mZ ddlmZ ddlmZ zddlmZ W n ey   ddlmZ Y nw zddlmZ W n ey   dZY nw ddlZzddl m!Z! W n ey   ddlm!Z! Y nw 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- ddl'm.Z. ddl'm/Z/ ddl'm0Z0 ddl'm1Z1 ddl'm2Z2 ddl3m4Z4 d d! Z5d"d# Z6d$d% Z7G d&d' d'eZ8G d(d) d)eZ9G d*d+ d+eZ:G d,d- d-e;Z<G d.d/ d/e;Z=e=Z>G d0d1 d1eZ?dS )2z
What's the big idea?

An endpoint that traverses all restful endpoints producing a swagger 2.0 schema
If a swagger yaml description is found in the docstrings for an endpoint
we add the endpoint to swagger specification output

    N)wrapspartial)defaultdict)	Blueprint)current_app)jsonifyResponse)redirectrender_template)requesturl_for)abort)
MethodView)DefaultJSONProvider)JSONEncoder)RequestParser)Markup)markdown   )OPTIONAL_FIELDSOPTIONAL_OAS3_FIELDS)
LazyString)extract_definitions)get_schema_specs)	get_specs)get_vendor_extension_fields)is_openapi3)parse_definition_docstring)parse_imports)swag_annotation)validate)extract_schema)__version__c                 C   s   | S N textr%   r%   R/var/www/html/crm_dreinet/venv_linux/lib/python3.10/site-packages/flasgger/base.pyNO_SANITIZER8   s   r)   c                 C   s   | r|  ddS | S )N
z<br/>)replacer&   r%   r%   r(   BR_SANITIZER<      r,   c                 C   s   | rt t| S | S r$   )r   r   r&   r%   r%   r(   MK_SANITIZER@   r-   r.   c                       (   e Zd ZdZ fddZdd Z  ZS )APIDocsViewz
    The /apidocs
    c                    s2   | di }|d| _tt| j|i | d S )N	view_argsconfig)popgetr2   superr0   __init__)selfargskwargsr1   	__class__r%   r(   r6   I   s   zAPIDocsView.__init__c                    s  | j dd  fdd| j dg D }dd |D }||| j ddd	}tjd
r1t|S | j |d< t|d
< t|d< | j dtddd|d< | j dtddd|d< | j dtddd|d< | j dtddd|d< | j dtddd|d< t	di |S )zD
        The data under /apidocs
        json or Swagger UI
        endpointflasggerc              	      sL   g | ]"}t d  |d f|dd|dd|dd|ddqS )	.r<   titlez
API Spec 1nameNversion0.0.1)urlr?   r@   rA   r<   )r   joinr4   .0specbase_endpointr%   r(   
<listcomp>T   s    


z#APIDocsView.get.<locals>.<listcomp>specsc                 S   s&   g | ]}|d  r|d  |d dqS )r@   rC   )r@   rC   r%   rE   r%   r%   r(   rJ   ^   s    r?   Flasgger)rK   urlsr?   jsonflasgger_configflasgger_versionfaviconzflasgger.staticzfavicon-32x32.pngfilenameswagger_ui_bundle_jszswagger-ui-bundle.jsswagger_ui_standalone_preset_jszswagger-ui-standalone-preset.js	jquery_jszlib/jquery.min.jsswagger_ui_csszswagger-ui.cssflasgger/index.htmlN)rX   )	r2   r4   r   r8   r   rN   r#   r   r   )r7   rK   rM   datar%   rH   r(   r4   N   sV   






zAPIDocsView.get__name__
__module____qualname____doc__r6   r4   __classcell__r%   r%   r:   r(   r0   D   s    r0   c                   @   s   e Zd ZdZdd ZdS )OAuthRedirectzH
    The OAuth2 redirect HTML for Swagger UI standard/implicit flow
    c                 C   s   t ddgS )Nzflasgger/oauth2-redirect.htmlzflasgger/o2c.htmlr
   r7   r%   r%   r(   r4      s   zOAuthRedirect.getN)r[   r\   r]   r^   r4   r%   r%   r%   r(   r`      s    r`   c                       r/   )APISpecsViewz-
    The /apispec_1.json and other specs
    c                    s&   | d| _tt| j|i | d S )Nloader)r3   rc   r5   rb   r6   )r7   r8   r9   r:   r%   r(   r6      s   zAPISpecsView.__init__c                 C   sF   zt |  W S    ddl}|d t|  }t|dd Y S )zI
        The Swagger view get method outputs to /apispecs_1.json
        r   Nz)jsonify failure; defaulting to json.dumpsapplication/json)mimetype)r   rc   logging	exceptionrN   dumpsr   )r7   rf   rK   r%   r%   r(   r4      s   
zAPISpecsView.getrZ   r%   r%   r:   r(   rb      s    rb   c                   @   s   e Zd ZdZdddZdS )SwaggerDefinitionz 
    Class based definition
    Nc                 C   s   || _ || _|p	g | _d S r$   )r@   objtags)r7   r@   rj   rk   r%   r%   r(   r6      s   zSwaggerDefinition.__init__r$   )r[   r\   r]   r^   r6   r%   r%   r%   r(   ri      s    ri   c                   @   s  e Zd ZdZg ededd dd dgddd	d
Zeeee	dZ
ddddddZdd Z				d;ddZd<ddZdd Zedd Zd<ddZd<d d!Zd=d"d#Zd<d$d%Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0ed1ed2efd3d4Z		d>d5d6Zd7d8 Zd9d: ZdS )?Swagger	apispec_1z/{}.jsonc                 C      dS NTr%   ruler%   r%   r(   <lambda>       zSwagger.<lambda>c                 C   rn   ro   r%   tagr%   r%   r(   rr      rs   )r<   routerule_filtermodel_filterz/flasgger_staticT	/apidocs/)headersrK   static_url_path
swagger_uispecs_route)stringintegernumberbooleanr8   rz   formrN   path)queryheaderformDatabodyr   c                 C   sN   |r|rt | j fi || _dS |r|s|| _dS |s%| j | _dS t)z Initializes self.config. If merge is set to true, then
        self.config will be set to with config + DEFAULT_CONFIG.
        N)dictDEFAULT_CONFIGcopyr2   
ValueError)r7   r2   merger%   r%   r(   _init_config   s   
zSwagger._init_configNFc                    s   d _ g  _g  _|pt _ || | _| _| _|
p"t	
  _ fdd}dd }|p1| _|p6| _i  _|	 _|rG | d S d S )NFc                    s   t j| | jdS )N)format_checker)
jsonschemar!   r   )rY   schemara   r%   r(   default_validation_function   s   z5Swagger.__init__.<locals>.default_validation_functionc                 S   s   t d| jS )Ni  )r   message)e___r%   r%   r(   default_error_handler   s   z/Swagger.__init__.<locals>.default_error_handler)_configured	endpointsdefinition_modelsr,   	sanitizerr   templatetemplate_file
decoratorsr   FormatCheckerr   validation_functionvalidation_error_handlerapispecsparseinit_app)r7   appr2   r   r   r   r   r   r   r   r   r   r   r   r%   ra   r(   r6      s,   
zSwagger.__init__c                 C   s   |p| j | _ || _t| jj| j_| | | jdur"| | j| _| | | 	| | j
rBtdu r7tdi | _i | _| | d| _| |_dS )z8
        Initialize the app with Swagger plugin
        NzPlease install flask_restfulT)r   r   r    add_url_ruleload_configr   load_swagger_filer   register_viewsadd_headersr   r   RuntimeErrorparsersschemasparse_requestr   swag)r7   r   r   r%   r%   r(   r     s    





zSwagger.init_appc                    s     dstj| jj   drtj}n@ ds! dr( fdd}n/t	
 dd }| }| }|d	 d
v rBtj}n fdd}W d    n1 sRw   Y  t	
 dd}||W  d    S 1 smw   Y  d S )N/z.jsonz.ymlz.yamlc                       t t|   S r$   yaml	safe_loadr   readstreamrR   r%   r(   rc   $  r-   z)Swagger.load_swagger_file.<locals>.loaderrzutf-8r   ){[c                    r   r$   r   r   rR   r%   r(   rc   -  s   )
startswithosr   rD   r   	root_pathendswithrN   loadcodecsopenr   strip)r7   rS   rc   fcontentsr%   rR   r(   r     s(   

	$zSwagger.load_swagger_filec                 C   s   | j S )z4
        Return if `init_app` is configured
        )r   ra   r%   r%   r(   
configured3  s   zSwagger.configuredc                    s(    pdd   fddt j D }|S )z,
        Returns all werkzeug rules
        c                 S   rn   ro   r%   rp   r%   r%   r(   rr   >  rs   z*Swagger.get_url_mappings.<locals>.<lambda>c                    s   g | ]} |r|qS r%   r%   )rF   rq   rw   r%   r(   rJ   ?  s    z,Swagger.get_url_mappings.<locals>.<listcomp>)r   url_map
iter_rules)r7   rw   	app_rulesr%   r   r(   get_url_mappings:  s
   
zSwagger.get_url_mappingsc                    s    |pdd   fdd| j D S )z2
        Used for class based definitions
        c                 S   rn   ro   r%   rt   r%   r%   r(   rr   I  rs   z(Swagger.get_def_models.<locals>.<lambda>c                    s   i | ]} |r|j |jqS r%   )r@   rj   )rF   
definitionrx   r%   r(   
<dictcomp>J  s    z*Swagger.get_def_models.<locals>.<dictcomp>)r   )r7   definition_filterr%   r   r(   get_def_modelsE  s   
zSwagger.get_def_modelsc           )   
   C   s  | j js|| jv r| j| S d }| jd D ]}|d |kr!|} nq|s+td|| jdp[|d| jdd|d| jdd|d	| jd	d
|d| jddd| jdpdtt| jdpmttd}| jd}t	|r|d |
di d< |r||d< n| jdp| jdd|d< t| j}|r|| | jd}| jdr| jd|d< | jdr| jd|d< | jdr| jd|d< | jdr| jd|d< t	|r| jdpt}|D ]}	| j|	r| j|	||	< q| jd ur|| j |d }
t|}t| jdd}| jdp*t}| |d  D ]$\}}t|| j\}}|rX|rX|rQ|d	|i || | q5t| |d!||| j|| jd"d#}g d$}|D ]\}}t }|D ]_\}}t	|r|di di }n|di }t|tkrt|d% tkr|\}|| g }|t||j|||d&7 }|d'g }|| v r||}t|d%kr| |v r|d'g }|t||j|||d&7 }|d(}|r|d)i }tt| |j|||d& |d*i }|r.d+d, | D }tt| |j|||d& d }d-|v rz|d-i }d.d, | D }|d urW|t| |j|||d& }|D ] } d/| vrg||  qY|  d/}!|!d urx||! |  qYi }"|d0r|d0|"d0< |d	r|d	|"d	< |r||"d(< |r||"d*< |r||"d-< t|d%kr||"d'< |D ]!}	|	|v r||	}#|	d1v rt!|#tt"fs|#g}#|#|"|	< q|"||< qt|rvz| jd2 }$W n t#t$fy   d3}$Y nw d4|$|}%z'| jd }&|&r'|&%d5r|&d d6 }&|&r'|%&|&r'|%t|&d  }%W n t#t$fy4   Y nw t'(d7|%D ]}'|%)|'d% d8|'d9  }%q;| D ]&\}	}(|%|
vr\i |
|%< |	|
|% v rn|
|% |	 |( qO|(|
|% |	< qOqu|| j|< t	|r|d= |S ):NrK   r<   z<Can`t find specs by endpoint {}, check your flasger`s configinforA   rB   r?   zA swagger APIdescriptionzpowered by FlasggertermsOfServicez/tos)rA   r?   r   r   pathsdefinitions)r   r   r   openapi
componentsr   swaggerswagger_versionz2.0
prefix_idshostbasePathschemessecurityDefinitionsoptional_oas3_fieldsignore_verbs)HEADOPTIONSoptional_fieldsr   rw   doc_dir)openapi_versionr   )r4   postputdeleter   )r<   verbr   r   
parametersrequestBodycontent	callbacksc                 S      i | ]	\}}t ||qS r%   strrF   keyvaluer%   r%   r(   r         z(Swagger.get_apispecs.<locals>.<dictcomp>	responsesc                 S   r   r%   r   r   r%   r%   r(   r     r   idsummary)producesconsumesswaggerUiPrefix z{0}{1}r   z(<([^<>]*:)?([^<>]*)>)z{%s}   )*r   debugr   r2   r   formatr4   r   r   r   
setdefaultr   updater   r   r"   setr   r   itemsr   r   r   r   typelistr   r<   keyslenlowervaluesr3   
isinstancetupleKeyError	TypeErrorr   r   refindallr+   ))r7   r<   rG   _specrY   r   top_level_extension_optionsr   r   r   r   r   r   r   r@   	def_modelr   r   rK   http_methodsrq   verbs
operationsr   update_dictdefsparams	verb_swagrequest_bodyr   r   r   r   def_id	operationr   prefixsrule	base_pathargvalr%   r%   r(   get_apispecsP  s  
	








 


















zSwagger.get_apispecsc                    s    fdd}|S )z:
        Decorator to add class based definitions
        c                    s   j t | d | S )N)rk   )r   appendri   )rj   r@   r7   rk   r%   r(   wrapperS  s   z#Swagger.definition.<locals>.wrapperr%   )r7   r@   rk   r#  r%   r"  r(   r   O  s   zSwagger.definitionc                 C   s   | j |j di  dS )z&
        Copy config from app
        SWAGGERN)r2   r   r4   )r7   r   r%   r%   r(   r   Y  s   zSwagger.load_configc                    s   fdd} j ddr j dd}t j ddt j d	d
 j dd
 j dd| j dd| j dd
d} j dd}|j|d|t jdt j ddd |dk rg|d }nd}|j j d|d|t	 dd |jddd d n
t j ddt} j d D ]&} j
|d  |j|d |d |tj|d t j|d d d!d q|| d
S )"z)
        Register Flasgger views
        c                    s    j r j D ]}|| } q| S r$   )r   )view	decoratorra   r%   r(   	wrap_viewe  s   

z)Swagger.register_views.<locals>.wrap_viewr|   T	uiversion   r<   r=   
url_prefixN	subdomaintemplate_folderzui{0}/templatesstatic_folderzui{0}/staticr{   )r*  r+  r,  r-  r{   r}   ry   apidocs)r2   )r1   )	view_funcz	/o2c.htmlz/oauth2-redirect.htmloauth_redirectz/apidocs/index.htmlc                   S   s   t tdS )Nzflasgger.apidocs)r	   r   r%   r%   r%   r(   rr     s    z(Swagger.register_views.<locals>.<lambda>rK   rv   r<   )rc   )r2   r4   r   r[   r   r   r0   as_viewr   r`   r   r!  rb   r   r   register_blueprint)r7   r   r'  r(  	blueprintr}   redirect_defaultrG   r%   ra   r(   r   _  sp   


	
	
	zSwagger.register_viewsc                    s   |j  fdd}dS )z.
        Inject headers after request
        c                    s$    j dD ]	\}}|| j|< q| S )Nrz   )r2   r4   rz   )responser   r   ra   r%   r(   after_request  s   z*Swagger.add_headers.<locals>.after_requestN)r7  )r7   r   r7  r%   ra   r(   r     s   zSwagger.add_headersc                    s   |j  fdd}d S )Nc                     s  g } t tjdD ]&}d|v r+d|v r|dd }nd}| d||d  q
| | q
d| }|tj	  } j
jsQ| jv rQ j| } j| }nVd}d} jd D ],}	 j|	d	 d
}
||
d v rtj	 |
d | v r|
d | tj	  }t|
} nqZ|sdS tt}tdd } |||| | j|< | j|< dtji}| D ]
}||  ||< qd|v rtjpi |d< | D ].\}}z ||| }t| W q tjy } z ||||  W Y d}~qd}~ww ttd| dS )z
            Parse and validate request data(query, form, header and body),
            set data to `request.parsed_data`
            r   <:r   z{{{:s}}}r   NrK   r<   r1  r   c                   S   s   dt tdS )Nobject)r  
properties)r   r   r%   r%   r%   r(   rr     s    z?Swagger.parse_request.<locals>.before_request.<locals>.<lambda>r   rN   parsed_data)r   r   url_rulesplitindexr!  r   rD   methodr  r   r   r   r   r2   r   r"   r   r   update_schemas_parsersr1   r  
parse_argsrN   r  r   printr   ValidationErrorr   setattr)subssubstartr   path_keyr   r   docr   rG   apispecr<  locationrY   retr   ra   r%   r(   before_request  s`   





z-Swagger.parse_request.<locals>.before_request)rN  )r7   r   rN  r%   ra   r(   r     s   zSwagger.parse_requestc                 C   s  |   red}d}|di di  D ]5\}}d|v r#|di }q|| j|| jd|v r6|d ddn|dd |dd	| jd
 d	d q|durat|tkrc|||< | ||| dS dS dS |dg D ]`}	| j|	d  }|dkr|	d ||< | ||| qk|	d }|dkr|| j|| jd|	v r|	d ddn|	dd |	dd	| j|	d  d	d |	D ]}
|
dkr|	|
 || d | |
< qqkdS )zD
        Schemas and parsers would be updated here from doc
        rN   Nr   r   rd   r   r  requiredFr   )r  rO  rL  store_missingr   inr@   r   r;  )	r   r4   r  add_argumentSCHEMA_TYPESSCHEMA_LOCATIONSr  r   set_schemas)r7   rJ  r   r   r   rL  json_schemar@   r   paramkr%   r%   r(   rA    st   




zSwagger.update_schemas_parsersr   rL  r   c                 C   s<   t | jdrdt|i|| d< d S t||| d< d S )Nr   r   r   r   )r   r2   r4   r   )r7   r   rL  r   r%   r%   r(   rU  -  s   zSwagger.set_schemasc                    s2   du rj du rj fdd}|S )a  
        A decorator that is used to validate incoming requests data
        against a schema

            swagger = Swagger(app)

            @app.route('/pets', methods=['POST'])
            @swagger.validate('Pet')
            @swag_from("pet_post_endpoint.yml")
            def post():
                return db.insert(request.data)

        This annotation only works if the endpoint is already swagged,
        i.e. placing @swag_from above @validate or not declaring the
        swagger specifications in the method's docstring *won't work*

        Naturally, if you use @app.route annotation it still needs to
        be the outermost annotation

        :param schema_id: the id of the schema with which the data will
            be validated

        :param validation_function: custom validation function which
            takes the positional arguments: data to be validated at
            first and schema to validate against at second

        :param validation_error_handler: custom function to handle
            exceptions thrown when validating which takes the exception
            thrown as the first, the data being validated as the second
            and the schema being used to validate as the third argument
        Nc                    s    t   fdd}|S )Nc                     s2   t }t|jdd  | i |S )Nr   )	schema_idrK   r   r   r   )r   r!   r2   r4   )r8   r9   rK   )funcrY  r7   r   r   r%   r(   r#  ^  s   

z4Swagger.validate.<locals>.decorator.<locals>.wrapper)r   )rZ  r#  rY  r7   r   r   )rZ  r(   r&  ]  s   
z#Swagger.validate.<locals>.decorator)r   r   )r7   rY  r   r   r&  r%   r[  r(   r!   4  s   #zSwagger.validatec                 C   s^   t || }|du rtd|dd |d D D ]}|dur,|d |kr,|  S qdS )z
        This method finds a schema known to Flasgger and returns it.

        :raise KeyError: when the specified :param schema_id: is not
        found by Flasgger

        :param schema_id: the id of the desired schema
        Nz#Specified schema_id '{0}' not foundc                 s   s    | ]}| d V  qdS )r   N)r4   )rF   	parameterr%   r%   r(   	<genexpr>|  s    

z%Swagger.get_schema.<locals>.<genexpr>r   r   )r   r
  r   r4   r  )r7   rY  schema_specsr   r%   r%   r(   
get_schemam  s   
	
zSwagger.get_schemac                 C   s   t | jdS )Nr   )r   r2   r4   ra   r%   r%   r(   r     s   zSwagger.is_openapi3)NNNNNNNNFNFr$   )rm   )NN) r[   r\   r]   DEFAULT_ENDPOINTr   r   r   intfloatboolrS  rT  r   r6   r   r   propertyr   r   r   r   r   r   r   r   r   rA  r   rU  r!   r_  r   r%   r%   r%   r(   rl      s`    

$



  

K
<
=

9rl   c                       s   e Zd Z fddZ  ZS )LazyJSONEncoderc                    s"   t |tr	t|S tt| |S r$   )r  r   r   r5   re  default)r7   rj   r:   r%   r(   rf    s   
zLazyJSONEncoder.default)r[   r\   r]   rf  r_   r%   r%   r:   r(   re    s    re  )@r^   r  r   r   r   
simplejsonrN   ImportError	functoolsr   r   collectionsr   flaskr   r   r   r   r	   r   r   r   r   flask.viewsr   flask.json.providerr   
flask.jsonr   flask_restful.reqparser   r   
markupsafer   mistuner   	constantsr   r   utilsr   r   r   r   r   r   r   r   r    r!   r"   r   r#   r)   r,   r.   r0   r`   rb   r:  ri   rl   rL   re  r%   r%   r%   r(   <module>   s    H
     U