3
¥Yði#  ã               @   sž   d Z ddlZddlZddlZddlZddlmZ yddl	m
Z
 W n  ek
r`   ddlm
Z
 Y nX ejrŒddlmZ ddlmZ ddlmZ G dd	„ d	ƒZdS )
a9  
Application Profiler
====================

This module provides a middleware that profiles each request with the
:mod:`cProfile` module. This can help identify bottlenecks in your code
that may be slowing down your application.

.. autoclass:: ProfilerMiddleware

:copyright: 2007 Pallets
:license: BSD-3-Clause
é    N)ÚStats)ÚProfile)ÚStartResponse)ÚWSGIApplication)ÚWSGIEnvironmentc            	   @   st   e Zd ZdZejdf ddfdeje ej	e ej	ej
eeef  eje eddœdd	„Zd
dej	e dœdd„ZdS )ÚProfilerMiddlewarea  Wrap a WSGI application and profile the execution of each
    request. Responses are buffered so that timings are more exact.

    If ``stream`` is given, :class:`pstats.Stats` are written to it
    after each request. If ``profile_dir`` is given, :mod:`cProfile`
    data files are saved to that directory, one file per request.

    The filename can be customized by passing ``filename_format``. If
    it is a string, it will be formatted using :meth:`str.format` with
    the following fields available:

    -   ``{method}`` - The request method; GET, POST, etc.
    -   ``{path}`` - The request path or 'root' should one not exist.
    -   ``{elapsed}`` - The elapsed time of the request.
    -   ``{time}`` - The time of the request.

    If it is a callable, it will be called with the WSGI ``environ``
    dict and should return a filename.

    :param app: The WSGI application to wrap.
    :param stream: Write stats to this stream. Disable with ``None``.
    :param sort_by: A tuple of columns to sort stats by. See
        :meth:`pstats.Stats.sort_stats`.
    :param restrictions: A tuple of restrictions to filter stats by. See
        :meth:`pstats.Stats.print_stats`.
    :param profile_dir: Save profile data files to this directory.
    :param filename_format: Format string for profile data file names,
        or a callable returning a name. See explanation above.

    .. code-block:: python

        from werkzeug.middleware.profiler import ProfilerMiddleware
        app = ProfilerMiddleware(app)

    .. versionchanged:: 0.15
        Stats are written even if ``profile_dir`` is given, and can be
        disable by passing ``stream=None``.

    .. versionadded:: 0.15
        Added ``filename_format``.

    .. versionadded:: 0.9
        Added ``restrictions`` and ``profile_dir``.
    ÚtimeÚcallsNz/{method}.{path}.{elapsed:.0f}ms.{time:.0f}.profr   )ÚappÚstreamÚsort_byÚrestrictionsÚprofile_dirÚfilename_formatÚreturnc             C   s(   || _ || _|| _|| _|| _|| _d S )N)Ú_appÚ_streamÚ_sort_byÚ_restrictionsÚ_profile_dirÚ_filename_format)Úselfr
   r   r   r   r   r   © r   ú@/tmp/pip-build-8om4l6ph/Werkzeug/werkzeug/middleware/profiler.pyÚ__init__M   s    	zProfilerMiddleware.__init__r   r   )ÚenvironÚstart_responser   c                sL  g ‰d‡‡fdd„	‰ d dœ‡ ‡‡‡fdd„}t ƒ }tjƒ }|j|ƒ djˆƒ}tjƒ | }ˆjd k	rÊtˆjƒrzˆjˆƒ}n6ˆjjˆd ˆd jd	ƒj	d	d
ƒpžd|d tjƒ d�}t
jjˆj|ƒ}|j|ƒ ˆjd k	�rFt|ˆjd�}	|	jˆjŽ  tdd ˆjd� ˆjddƒ}
td|
›�ˆjd� |	jˆjŽ  tdd › d�ˆjd� |gS )Nc                s   ˆ| ||ƒ ˆ j S )N)Úappend)ÚstatusÚheadersÚexc_info)Úresponse_bodyr   r   r   Úcatching_start_responseb   s    z<ProfilerMiddleware.__call__.<locals>.catching_start_response)r   c                 s4   ˆj ˆtjdˆ ƒƒ} ˆj| ƒ t| dƒr0| jƒ  d S )Nr   Úclose)r   ÚtÚcastÚextendÚhasattrr#   )Zapp_iter)r"   r   r!   r   r   r   Úrunappf   s
    

z+ProfilerMiddleware.__call__.<locals>.runappó    ÚREQUEST_METHODZ	PATH_INFOú/Ú.Úrootg     @�@)ÚmethodÚpathÚelapsedr   )r   ú-éP   )ÚfileÚ zPATH: Ú
)N)r   r   ZruncallÚjoinr   Úcallabler   ÚformatÚstripÚreplaceÚosr/   Z
dump_statsr   r   Z
sort_statsr   ÚprintÚgetZprint_statsr   )r   r   r   r(   ÚprofileÚstartÚbodyr0   ÚfilenameÚstatsZ	path_infor   )r"   r   r!   r   r   r   Ú__call__]   s6    	




zProfilerMiddleware.__call__)r   r	   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚsysÚstdoutr$   ZIOÚstrÚIterableÚUnionÚintÚfloatÚOptionalr   ÚbytesrC   r   r   r   r   r      s   ,4	r   )rG   Úos.pathr;   rH   r   Útypingr$   Zpstatsr   ZcProfiler   ÚImportErrorr>   ZTYPE_CHECKINGZ_typeshed.wsgir   r   r   r   r   r   r   r   Ú<module>   s   