o
    PDi                      @   s   d dl Z d dlZd dlZ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
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	Zd
ZdZedZdd ZG dd dedZdedefddZdS )    N)StringIO)local)models)SilkyConfig)SilkInternalInconsistencySilkNotConfigured_time_taken)	Singletonsilk_queriesprofilesquerieszsilk.collectorc                   C   s   t d)Na  Silk middleware has not been installed correctly. Ordering must ensure that Silk middleware can execute process_request and process_response. If an earlier middleware returns from either of these methods, Silk will not have the chance to inspect the request/response objects.)RuntimeError r   r   G/var/www/Datamplify/venv/lib/python3.10/site-packages/silk/collector.pyraise_middleware_error   s   r   c                       s   e Zd ZdZ fddZdd Zedd Zdd	 Zej	d
d Zdd Z
edd Zedd Zedd Zdd Zedd Zd0d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-efd.d/Z  ZS )1DataCollectorz
    Provides the ability to save all models at the end of the request. We
    cannot save during the request due to the possibility of atomic blocks
    and hence must collect data and perform the save at the end.
    c                    s   t    t | _|   d S N)super__init__r   
_configureself	__class__r   r   r   %   s   
zDataCollector.__init__c                 C   s   t | jdst  d S d S )Ntemp_identifier)hasattrr   r   r   r   r   r   ensure_middleware_installed*   s   
z)DataCollector.ensure_middleware_installedc                 C      t | jdd S )Nrequestgetattrr   r   r   r   r   r   .      zDataCollector.requestc                 C   s    |    | j jd7  _| jjS )N   )r   r   r   r   r   r   r   get_identifier2   s   zDataCollector.get_identifierc                 C   s   || j _d S r   )r   r   )r   valuer   r   r   r   7   s   c                 C   s$   i | j _d| j _|   d | j _d S )Nr   )r   objectsr   stop_python_profilerpythonprofilerr   r   r   r   r   ;   s   zDataCollector._configurec                 C   r   )Nr&   r    r   r   r   r   r&   A   r"   zDataCollector.objectsc                 C   
   |  tS r   )_get_objectsTYP_QUERIESr   r   r   r   r   E      
zDataCollector.queriesc                 C   r)   r   )r*   TYP_SILK_QUERIESr   r   r   r   r   I   r,   zDataCollector.silk_queriesc                 C   s4   | j }|d u r| d|  ||vri ||< || S )Nz,Attempt to access %s without initialisation.)r&   _raise_not_configured)r   typr&   r   r   r   r*   M   s   zDataCollector._get_objectsc                 C   r)   r   )r*   TYP_PROFILESr   r   r   r   r   W   r,   zDataCollector.profilesNTc              
   C   sz   || _ |   |r;t | j_z	| jj  W d S  ty: } ztj	dt
| dd d | j_W Y d }~d S d }~ww d S )Nz$Could not enable python profiler, %sT)exc_info)r   r   cProfileProfiler   r(   enable
ValueErrorLoggererrorstr)r   r   should_profileer   r   r   	configure[   s   zDataCollector.configurec                 C   s   d | _ |   d S r   )r   r   r   r   r   r   clearh   s   zDataCollector.clearc                 C   s   t |d )Nz' Is the middleware installed correctly?)r   )r   errr   r   r   r.   l   s   z#DataCollector._raise_not_configuredc                 G   sV   |    |D ]"}|  }| j}|d u r| d ||vr!i | j|< || j| |< qd S )Nz>Attempt to register object of type %s without initialisation. )r   r$   r&   r.   )r   r/   argsargidentr&   r   r   r   register_objectso   s   
zDataCollector.register_objectsc                 G      | j tg|R   d S r   )rA   r+   r   r>   r   r   r   register_query      zDataCollector.register_queryc                 G   rB   r   )rA   r0   rC   r   r   r   register_profile   rE   zDataCollector.register_profilec                 C   sB   t  jrt| j}tdd | j D }|| j_|| j_d S d S )Nc                 s   s&    | ]\}}t |d  |d V  qdS )
start_timeend_timeNr   ).0_xr   r   r   	<genexpr>   s   $ z7DataCollector._record_meta_profiling.<locals>.<genexpr>)	r   
SILKY_METAlenr   sumitemsr   meta_num_queriesmeta_time_spent_queries)r   num_queries
query_timer   r   r   _record_meta_profiling   s   
z$DataCollector._record_meta_profilingc                 C   s"   t | jdd r| jj  d S d S )Nr(   )r!   r   r(   disabler   r   r   r   r'      s   z"DataCollector.stop_python_profilerc              
   C   s  t | jdd rct }tj| jj|dd}|  | }d	|
ddd }|| j_t jrc|  }| jjj|}| jjj|d}t|j| W d    n1 sYw   Y  |j| j_g }| j D ]\}}	||	d< tjdi |	}
||
g7 }qjtjj| tjjj| jd	}| D ]}
| j |
j!}	|	r|
|	d
< q| j"# D ]M}g }t$|v r|t$ }|t$= |D ])}z| j| }	z	|%|	d
  W n t&y   t'dw W q t&y   t'dw tj(jj)di |}|r|j*| q| +  d S )Nr(   )stream
cumulative
r      zw+b
identifier)r   modelzProfile references a query dictionary that has not been converted into a Django model. This should never happen, please file a bug reportzjProfile references a query temp_id that does not exist. This should never happen, please file a bug reportr   ),r!   r   r   pstatsStatsr(   
sort_statsprint_statsgetvaluejoinsplitr   	pyprofiler   SILKY_PYTHON_PROFILER_BINARY_get_proposed_file_name	prof_filestorageget_available_nameopenmarshaldumpstatsnamer   rP   r   SQLQueryr&   bulk_createfilterallgetr[   r   valuesr+   appendKeyErrorr   r3   createsetrU   )r   spsprofile_textproposed_file_name	file_namefsql_queriesr[   query	sql_queryprofileprofile_query_modelsprofile_queriesquery_temp_idr   r   r   finalise   sl   

zDataCollector.finalisec                 G   rB   r   )rA   r-   rC   r   r   r   register_silk_query   rE   z!DataCollector.register_silk_queryreturnc                 C   s>   t  jrt| jj}| dt| jj dS t| jj dS )z<Retrieve the profile file name to be proposed to the storagerJ   z.prof)r   (SILKY_PYTHON_PROFILER_EXTENDED_FILE_NAMEslugify_pathr   pathr8   id)r   slugified_pathr   r   r   rf      s   z%DataCollector._get_proposed_file_name)NT)__name__
__module____qualname____doc__r   r   propertyr   r$   setterr   r&   r   r   r*   r   r;   r<   r.   rA   rD   rF   rU   r'   r   r   r8   rf   __classcell__r   r   r   r   r      s<    







8r   )	metaclassrequest_pathr   c                 C   sF   t | } td| ddd} |  dd } tdd| dS )z
    Convert any characters not included in [a-zA-Z0-9_]) with a single underscore.
    Convert to lowercase. Also strip any leading and trailing char that are not in the
    accepted list

    Inspired from django slugify
    NFKDasciiignoreN2   z\W+rJ   )	r8   unicodedata	normalizeencodedecodelowerresubstrip)r   r   r   r   r      s   
r   )r2   loggingrk   r]   r   r   ior   	threadingr   silkr   silk.configr   silk.errorsr   r   silk.modelsr	   silk.singletonr
   r-   r0   r+   	getLoggerr6   r   r   r8   r   r   r   r   r   <module>   s*    
 7