prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  [feature request] werkzeug.contrib.profiler.ProfilerMiddleware custom file name formatting
  It would be nice to allow users to customize the output file name format when using the ProfilerMiddleware.
  
  Currently, the file name format is `'%(method)s.%(path)s.%(elapsed)06dms.%(time)d'`, which when multiple invocations have occurred leads to the profile files being ordered by their respective elapsed times. Having the ability to customize this format allows profiling users to make use of the resultant profile files in additional ways.
  
  I propose the `profiler.ProfilerMiddleware` is changed to allow users to customize the format of the profile filenames for their specific needs.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `werkzeug/contrib/profiler.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 """
  3     werkzeug.contrib.profiler
  4     ~~~~~~~~~~~~~~~~~~~~~~~~~
  5 
  6     This module provides a simple WSGI profiler middleware for finding
  7     bottlenecks in web application.  It uses the :mod:`profile` or
  8     :mod:`cProfile` module to do the profiling and writes the stats to the
  9     stream provided (defaults to stderr).
  10 
  11     Example usage::
  12 
  13         from werkzeug.contrib.profiler import ProfilerMiddleware
  14         app = ProfilerMiddleware(app)
  15 
  16     :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details.
  17     :license: BSD, see LICENSE for more details.
  18 """
  19 import sys
  20 import time
  21 import os.path
  22 try:
  23     try:
  24         from cProfile import Profile
  25     except ImportError:
  26         from profile import Profile
  27     from pstats import Stats
  28     available = True
  29 except ImportError:
  30     available = False
  31 
  32 
  33 class MergeStream(object):
  34 
  35     """An object that redirects `write` calls to multiple streams.
  36     Use this to log to both `sys.stdout` and a file::
  37 
  38         f = open('profiler.log', 'w')
  39         stream = MergeStream(sys.stdout, f)
  40         profiler = ProfilerMiddleware(app, stream)
  41     """
  42 
  43     def __init__(self, *streams):
  44         if not streams:
  45             raise TypeError('at least one stream must be given')
  46         self.streams = streams
  47 
  48     def write(self, data):
  49         for stream in self.streams:
  50             stream.write(data)
  51 
  52 
  53 class ProfilerMiddleware(object):
  54 
  55     """Simple profiler middleware.  Wraps a WSGI application and profiles
  56     a request.  This intentionally buffers the response so that timings are
  57     more exact.
  58 
  59     By giving the `profile_dir` argument, pstat.Stats files are saved to that
  60     directory, one file per request. Without it, a summary is printed to
  61     `stream` instead.
  62 
  63     For the exact meaning of `sort_by` and `restrictions` consult the
  64     :mod:`profile` documentation.
  65 
  66     .. versionadded:: 0.9
  67        Added support for `restrictions` and `profile_dir`.
  68 
  69     :param app: the WSGI application to profile.
  70     :param stream: the stream for the profiled stats.  defaults to stderr.
  71     :param sort_by: a tuple of columns to sort the result by.
  72     :param restrictions: a tuple of profiling strictions, not used if dumping
  73                          to `profile_dir`.
  74     :param profile_dir: directory name to save pstat files
  75     """
  76 
  77     def __init__(self, app, stream=None,
  78                  sort_by=('time', 'calls'), restrictions=(), profile_dir=None):
  79         if not available:
  80             raise RuntimeError('the profiler is not available because '
  81                                'profile or pstat is not installed.')
  82         self._app = app
  83         self._stream = stream or sys.stdout
  84         self._sort_by = sort_by
  85         self._restrictions = restrictions
  86         self._profile_dir = profile_dir
  87 
  88     def __call__(self, environ, start_response):
  89         response_body = []
  90 
  91         def catching_start_response(status, headers, exc_info=None):
  92             start_response(status, headers, exc_info)
  93             return response_body.append
  94 
  95         def runapp():
  96             appiter = self._app(environ, catching_start_response)
  97             response_body.extend(appiter)
  98             if hasattr(appiter, 'close'):
  99                 appiter.close()
  100 
  101         p = Profile()
  102         start = time.time()
  103         p.runcall(runapp)
  104         body = b''.join(response_body)
  105         elapsed = time.time() - start
  106 
  107         if self._profile_dir is not None:
  108             prof_filename = os.path.join(self._profile_dir,
  109                                          '%s.%s.%06dms.%d.prof' % (
  110                                              environ['REQUEST_METHOD'],
  111                                              environ.get('PATH_INFO').strip(
  112                                                  '/').replace('/', '.') or 'root',
  113                                              elapsed * 1000.0,
  114                                              time.time()
  115                                          ))
  116             p.dump_stats(prof_filename)
  117 
  118         else:
  119             stats = Stats(p, stream=self._stream)
  120             stats.sort_stats(*self._sort_by)
  121 
  122             self._stream.write('-' * 80)
  123             self._stream.write('\nPATH: %r\n' % environ.get('PATH_INFO'))
  124             stats.print_stats(*self._restrictions)
  125             self._stream.write('-' * 80 + '\n\n')
  126 
  127         return [body]
  128 
  129 
  130 def make_action(app_factory, hostname='localhost', port=5000,
  131                 threaded=False, processes=1, stream=None,
  132                 sort_by=('time', 'calls'), restrictions=()):
  133     """Return a new callback for :mod:`werkzeug.script` that starts a local
  134     server with the profiler enabled.
  135 
  136     ::
  137 
  138         from werkzeug.contrib import profiler
  139         action_profile = profiler.make_action(make_app)
  140     """
  141     def action(hostname=('h', hostname), port=('p', port),
  142                threaded=threaded, processes=processes):
  143         """Start a new development server."""
  144         from werkzeug.serving import run_simple
  145         app = ProfilerMiddleware(app_factory(), stream, sort_by, restrictions)
  146         run_simple(hostname, port, app, False, None, threaded, processes)
  147     return action
  148
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/werkzeug/contrib/profiler.py b/werkzeug/contrib/profiler.py
  --- a/werkzeug/contrib/profiler.py
  +++ b/werkzeug/contrib/profiler.py
  @@ -9,7 +9,6 @@
       stream provided (defaults to stderr).
   
       Example usage::
  -
           from werkzeug.contrib.profiler import ProfilerMiddleware
           app = ProfilerMiddleware(app)
   
  @@ -60,22 +59,43 @@
       directory, one file per request. Without it, a summary is printed to
       `stream` instead.
   
  +    The file name format 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. Either way, the ``'.prof'``
  +    extension will be appended to the name. The default format is
  +    ``'{method}.{path}.{elapsed:06d}ms.{time:d}'``.
  +
       For the exact meaning of `sort_by` and `restrictions` consult the
       :mod:`profile` documentation.
   
       .. versionadded:: 0.9
          Added support for `restrictions` and `profile_dir`.
   
  +    .. versionadded:: 0.15
  +       Added ``profile_file_name_format``.
  +
       :param app: the WSGI application to profile.
       :param stream: the stream for the profiled stats.  defaults to stderr.
       :param sort_by: a tuple of columns to sort the result by.
  -    :param restrictions: a tuple of profiling strictions, not used if dumping
  +    :param restrictions: a tuple of profiling restrictions, not used if dumping
                            to `profile_dir`.
       :param profile_dir: directory name to save pstat files
  +    :param filename_format: format of the filename excluding the extension.
       """
   
  -    def __init__(self, app, stream=None,
  -                 sort_by=('time', 'calls'), restrictions=(), profile_dir=None):
  +    def __init__(
  +        self, app, stream=None,
  +        sort_by=('time', 'calls'), restrictions=(), profile_dir=None,
  +        filename_format='%(method)s.%(path)s.%(elapsed)06dms.%(time)d'
  +    ):
           if not available:
               raise RuntimeError('the profiler is not available because '
                                  'profile or pstat is not installed.')
  @@ -84,6 +104,7 @@
           self._sort_by = sort_by
           self._restrictions = restrictions
           self._profile_dir = profile_dir
  +        self._filename_format = filename_format
   
       def __call__(self, environ, start_response):
           response_body = []
  @@ -105,14 +126,18 @@
           elapsed = time.time() - start
   
           if self._profile_dir is not None:
  -            prof_filename = os.path.join(self._profile_dir,
  -                                         '%s.%s.%06dms.%d.prof' % (
  -                                             environ['REQUEST_METHOD'],
  -                                             environ.get('PATH_INFO').strip(
  -                                                 '/').replace('/', '.') or 'root',
  -                                             elapsed * 1000.0,
  -                                             time.time()
  -                                         ))
  +            if callable(self._filename_format):
  +                filename = self._filename_format(environ)
  +            else:
  +                filename = self._filename_format.format(
  +                    method=environ['REQUEST_METHOD'],
  +                    path=(
  +                        environ.get('PATH_INFO').strip('/').replace('/', '.')
  +                        or 'root'),
  +                    elapsed=elapsed * 1000.0,
  +                    time=time.time(),
  +                )
  +            prof_filename = os.path.join(self._profile_dir, filename + '.prof')
               p.dump_stats(prof_filename)
   
           else:
  
verification_info: {"golden_diff": "diff --git a/werkzeug/contrib/profiler.py b/werkzeug/contrib/profiler.py\n--- a/werkzeug/contrib/profiler.py\n+++ b/werkzeug/contrib/profiler.py\n@@ -9,7 +9,6 @@\n     stream provided (defaults to stderr).\n \n     Example usage::\n-\n         from werkzeug.contrib.profiler import ProfilerMiddleware\n         app = ProfilerMiddleware(app)\n \n@@ -60,22 +59,43 @@\n     directory, one file per request. Without it, a summary is printed to\n     `stream` instead.\n \n+    The file name format can be customized by passing\n+    ``filename_format``. If it is a string, it will be formatted using\n+    :meth:`str.format` with the following fields available:\n+\n+    -   ``{method}`` - the request method; GET, POST, etc\n+    -   ``{path}`` - the request path or 'root' should one not exist\n+    -   ``{elapsed}`` - the elapsed time of the request\n+    -   ``{time}`` - the time of the request\n+\n+    If it is a callable, it will be called with the WSGI ``environ``\n+    dict and should return a filename. Either way, the ``'.prof'``\n+    extension will be appended to the name. The default format is\n+    ``'{method}.{path}.{elapsed:06d}ms.{time:d}'``.\n+\n     For the exact meaning of `sort_by` and `restrictions` consult the\n     :mod:`profile` documentation.\n \n     .. versionadded:: 0.9\n        Added support for `restrictions` and `profile_dir`.\n \n+    .. versionadded:: 0.15\n+       Added ``profile_file_name_format``.\n+\n     :param app: the WSGI application to profile.\n     :param stream: the stream for the profiled stats.  defaults to stderr.\n     :param sort_by: a tuple of columns to sort the result by.\n-    :param restrictions: a tuple of profiling strictions, not used if dumping\n+    :param restrictions: a tuple of profiling restrictions, not used if dumping\n                          to `profile_dir`.\n     :param profile_dir: directory name to save pstat files\n+    :param filename_format: format of the filename excluding the extension.\n     \"\"\"\n \n-    def __init__(self, app, stream=None,\n-                 sort_by=('time', 'calls'), restrictions=(), profile_dir=None):\n+    def __init__(\n+        self, app, stream=None,\n+        sort_by=('time', 'calls'), restrictions=(), profile_dir=None,\n+        filename_format='%(method)s.%(path)s.%(elapsed)06dms.%(time)d'\n+    ):\n         if not available:\n             raise RuntimeError('the profiler is not available because '\n                                'profile or pstat is not installed.')\n@@ -84,6 +104,7 @@\n         self._sort_by = sort_by\n         self._restrictions = restrictions\n         self._profile_dir = profile_dir\n+        self._filename_format = filename_format\n \n     def __call__(self, environ, start_response):\n         response_body = []\n@@ -105,14 +126,18 @@\n         elapsed = time.time() - start\n \n         if self._profile_dir is not None:\n-            prof_filename = os.path.join(self._profile_dir,\n-                                         '%s.%s.%06dms.%d.prof' % (\n-                                             environ['REQUEST_METHOD'],\n-                                             environ.get('PATH_INFO').strip(\n-                                                 '/').replace('/', '.') or 'root',\n-                                             elapsed * 1000.0,\n-                                             time.time()\n-                                         ))\n+            if callable(self._filename_format):\n+                filename = self._filename_format(environ)\n+            else:\n+                filename = self._filename_format.format(\n+                    method=environ['REQUEST_METHOD'],\n+                    path=(\n+                        environ.get('PATH_INFO').strip('/').replace('/', '.')\n+                        or 'root'),\n+                    elapsed=elapsed * 1000.0,\n+                    time=time.time(),\n+                )\n+            prof_filename = os.path.join(self._profile_dir, filename + '.prof')\n             p.dump_stats(prof_filename)\n \n         else:\n", "issue": "[feature request] werkzeug.contrib.profiler.ProfilerMiddleware custom file name formatting\nIt would be nice to allow users to customize the output file name format when using the ProfilerMiddleware.\r\n\r\nCurrently, the file name format is `'%(method)s.%(path)s.%(elapsed)06dms.%(time)d'`, which when multiple invocations have occurred leads to the profile files being ordered by their respective elapsed times. Having the ability to customize this format allows profiling users to make use of the resultant profile files in additional ways.\r\n\r\nI propose the `profiler.ProfilerMiddleware` is changed to allow users to customize the format of the profile filenames for their specific needs.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\n    werkzeug.contrib.profiler\n    ~~~~~~~~~~~~~~~~~~~~~~~~~\n\n    This module provides a simple WSGI profiler middleware for finding\n    bottlenecks in web application.  It uses the :mod:`profile` or\n    :mod:`cProfile` module to do the profiling and writes the stats to the\n    stream provided (defaults to stderr).\n\n    Example usage::\n\n        from werkzeug.contrib.profiler import ProfilerMiddleware\n        app = ProfilerMiddleware(app)\n\n    :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details.\n    :license: BSD, see LICENSE for more details.\n\"\"\"\nimport sys\nimport time\nimport os.path\ntry:\n    try:\n        from cProfile import Profile\n    except ImportError:\n        from profile import Profile\n    from pstats import Stats\n    available = True\nexcept ImportError:\n    available = False\n\n\nclass MergeStream(object):\n\n    \"\"\"An object that redirects `write` calls to multiple streams.\n    Use this to log to both `sys.stdout` and a file::\n\n        f = open('profiler.log', 'w')\n        stream = MergeStream(sys.stdout, f)\n        profiler = ProfilerMiddleware(app, stream)\n    \"\"\"\n\n    def __init__(self, *streams):\n        if not streams:\n            raise TypeError('at least one stream must be given')\n        self.streams = streams\n\n    def write(self, data):\n        for stream in self.streams:\n            stream.write(data)\n\n\nclass ProfilerMiddleware(object):\n\n    \"\"\"Simple profiler middleware.  Wraps a WSGI application and profiles\n    a request.  This intentionally buffers the response so that timings are\n    more exact.\n\n    By giving the `profile_dir` argument, pstat.Stats files are saved to that\n    directory, one file per request. Without it, a summary is printed to\n    `stream` instead.\n\n    For the exact meaning of `sort_by` and `restrictions` consult the\n    :mod:`profile` documentation.\n\n    .. versionadded:: 0.9\n       Added support for `restrictions` and `profile_dir`.\n\n    :param app: the WSGI application to profile.\n    :param stream: the stream for the profiled stats.  defaults to stderr.\n    :param sort_by: a tuple of columns to sort the result by.\n    :param restrictions: a tuple of profiling strictions, not used if dumping\n                         to `profile_dir`.\n    :param profile_dir: directory name to save pstat files\n    \"\"\"\n\n    def __init__(self, app, stream=None,\n                 sort_by=('time', 'calls'), restrictions=(), profile_dir=None):\n        if not available:\n            raise RuntimeError('the profiler is not available because '\n                               'profile or pstat is not installed.')\n        self._app = app\n        self._stream = stream or sys.stdout\n        self._sort_by = sort_by\n        self._restrictions = restrictions\n        self._profile_dir = profile_dir\n\n    def __call__(self, environ, start_response):\n        response_body = []\n\n        def catching_start_response(status, headers, exc_info=None):\n            start_response(status, headers, exc_info)\n            return response_body.append\n\n        def runapp():\n            appiter = self._app(environ, catching_start_response)\n            response_body.extend(appiter)\n            if hasattr(appiter, 'close'):\n                appiter.close()\n\n        p = Profile()\n        start = time.time()\n        p.runcall(runapp)\n        body = b''.join(response_body)\n        elapsed = time.time() - start\n\n        if self._profile_dir is not None:\n            prof_filename = os.path.join(self._profile_dir,\n                                         '%s.%s.%06dms.%d.prof' % (\n                                             environ['REQUEST_METHOD'],\n                                             environ.get('PATH_INFO').strip(\n                                                 '/').replace('/', '.') or 'root',\n                                             elapsed * 1000.0,\n                                             time.time()\n                                         ))\n            p.dump_stats(prof_filename)\n\n        else:\n            stats = Stats(p, stream=self._stream)\n            stats.sort_stats(*self._sort_by)\n\n            self._stream.write('-' * 80)\n            self._stream.write('\\nPATH: %r\\n' % environ.get('PATH_INFO'))\n            stats.print_stats(*self._restrictions)\n            self._stream.write('-' * 80 + '\\n\\n')\n\n        return [body]\n\n\ndef make_action(app_factory, hostname='localhost', port=5000,\n                threaded=False, processes=1, stream=None,\n                sort_by=('time', 'calls'), restrictions=()):\n    \"\"\"Return a new callback for :mod:`werkzeug.script` that starts a local\n    server with the profiler enabled.\n\n    ::\n\n        from werkzeug.contrib import profiler\n        action_profile = profiler.make_action(make_app)\n    \"\"\"\n    def action(hostname=('h', hostname), port=('p', port),\n               threaded=threaded, processes=processes):\n        \"\"\"Start a new development server.\"\"\"\n        from werkzeug.serving import run_simple\n        app = ProfilerMiddleware(app_factory(), stream, sort_by, restrictions)\n        run_simple(hostname, port, app, False, None, threaded, processes)\n    return action\n", "path": "werkzeug/contrib/profiler.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\n    werkzeug.contrib.profiler\n    ~~~~~~~~~~~~~~~~~~~~~~~~~\n\n    This module provides a simple WSGI profiler middleware for finding\n    bottlenecks in web application.  It uses the :mod:`profile` or\n    :mod:`cProfile` module to do the profiling and writes the stats to the\n    stream provided (defaults to stderr).\n\n    Example usage::\n        from werkzeug.contrib.profiler import ProfilerMiddleware\n        app = ProfilerMiddleware(app)\n\n    :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details.\n    :license: BSD, see LICENSE for more details.\n\"\"\"\nimport sys\nimport time\nimport os.path\ntry:\n    try:\n        from cProfile import Profile\n    except ImportError:\n        from profile import Profile\n    from pstats import Stats\n    available = True\nexcept ImportError:\n    available = False\n\n\nclass MergeStream(object):\n\n    \"\"\"An object that redirects `write` calls to multiple streams.\n    Use this to log to both `sys.stdout` and a file::\n\n        f = open('profiler.log', 'w')\n        stream = MergeStream(sys.stdout, f)\n        profiler = ProfilerMiddleware(app, stream)\n    \"\"\"\n\n    def __init__(self, *streams):\n        if not streams:\n            raise TypeError('at least one stream must be given')\n        self.streams = streams\n\n    def write(self, data):\n        for stream in self.streams:\n            stream.write(data)\n\n\nclass ProfilerMiddleware(object):\n\n    \"\"\"Simple profiler middleware.  Wraps a WSGI application and profiles\n    a request.  This intentionally buffers the response so that timings are\n    more exact.\n\n    By giving the `profile_dir` argument, pstat.Stats files are saved to that\n    directory, one file per request. Without it, a summary is printed to\n    `stream` instead.\n\n    The file name format can be customized by passing\n    ``filename_format``. If it is a string, it will be formatted using\n    :meth:`str.format` with the following fields available:\n\n    -   ``{method}`` - the request method; GET, POST, etc\n    -   ``{path}`` - the request path or 'root' should one not exist\n    -   ``{elapsed}`` - the elapsed time of the request\n    -   ``{time}`` - the time of the request\n\n    If it is a callable, it will be called with the WSGI ``environ``\n    dict and should return a filename. Either way, the ``'.prof'``\n    extension will be appended to the name. The default format is\n    ``'{method}.{path}.{elapsed:06d}ms.{time:d}'``.\n\n    For the exact meaning of `sort_by` and `restrictions` consult the\n    :mod:`profile` documentation.\n\n    .. versionadded:: 0.9\n       Added support for `restrictions` and `profile_dir`.\n\n    .. versionadded:: 0.15\n       Added ``profile_file_name_format``.\n\n    :param app: the WSGI application to profile.\n    :param stream: the stream for the profiled stats.  defaults to stderr.\n    :param sort_by: a tuple of columns to sort the result by.\n    :param restrictions: a tuple of profiling restrictions, not used if dumping\n                         to `profile_dir`.\n    :param profile_dir: directory name to save pstat files\n    :param filename_format: format of the filename excluding the extension.\n    \"\"\"\n\n    def __init__(\n        self, app, stream=None,\n        sort_by=('time', 'calls'), restrictions=(), profile_dir=None,\n        filename_format='%(method)s.%(path)s.%(elapsed)06dms.%(time)d'\n    ):\n        if not available:\n            raise RuntimeError('the profiler is not available because '\n                               'profile or pstat is not installed.')\n        self._app = app\n        self._stream = stream or sys.stdout\n        self._sort_by = sort_by\n        self._restrictions = restrictions\n        self._profile_dir = profile_dir\n        self._filename_format = filename_format\n\n    def __call__(self, environ, start_response):\n        response_body = []\n\n        def catching_start_response(status, headers, exc_info=None):\n            start_response(status, headers, exc_info)\n            return response_body.append\n\n        def runapp():\n            appiter = self._app(environ, catching_start_response)\n            response_body.extend(appiter)\n            if hasattr(appiter, 'close'):\n                appiter.close()\n\n        p = Profile()\n        start = time.time()\n        p.runcall(runapp)\n        body = b''.join(response_body)\n        elapsed = time.time() - start\n\n        if self._profile_dir is not None:\n            if callable(self._filename_format):\n                filename = self._filename_format(environ)\n            else:\n                filename = self._filename_format.format(\n                    method=environ['REQUEST_METHOD'],\n                    path=(\n                        environ.get('PATH_INFO').strip('/').replace('/', '.')\n                        or 'root'),\n                    elapsed=elapsed * 1000.0,\n                    time=time.time(),\n                )\n            prof_filename = os.path.join(self._profile_dir, filename + '.prof')\n            p.dump_stats(prof_filename)\n\n        else:\n            stats = Stats(p, stream=self._stream)\n            stats.sort_stats(*self._sort_by)\n\n            self._stream.write('-' * 80)\n            self._stream.write('\\nPATH: %r\\n' % environ.get('PATH_INFO'))\n            stats.print_stats(*self._restrictions)\n            self._stream.write('-' * 80 + '\\n\\n')\n\n        return [body]\n\n\ndef make_action(app_factory, hostname='localhost', port=5000,\n                threaded=False, processes=1, stream=None,\n                sort_by=('time', 'calls'), restrictions=()):\n    \"\"\"Return a new callback for :mod:`werkzeug.script` that starts a local\n    server with the profiler enabled.\n\n    ::\n\n        from werkzeug.contrib import profiler\n        action_profile = profiler.make_action(make_app)\n    \"\"\"\n    def action(hostname=('h', hostname), port=('p', port),\n               threaded=threaded, processes=processes):\n        \"\"\"Start a new development server.\"\"\"\n        from werkzeug.serving import run_simple\n        app = ProfilerMiddleware(app_factory(), stream, sort_by, restrictions)\n        run_simple(hostname, port, app, False, None, threaded, processes)\n    return action\n", "path": "werkzeug/contrib/profiler.py"}]}