prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Support for pdb and debuggers
  ### Proposed fixes:
  
  It is now possible to debug ckan with pdb/ipdb/PyCharm debugger and others, both outside Docker and inside Docker.
  I just exposed a `werkzeug` option to the CKAN CLI, called `passthrough_errors`. Enabling that, together with `--disable-reloader` (which should be the default in my opinion, like it was in the past), allow to run pdb without making other changes to the source code.
  `threads` should not be enabled and `processes` should be set to 1. These are the defaults already.
  
  > passthrough_errors (bool) – set this to True to disable the error catching. This means that the server will die on errors but it can be useful to hook debuggers in (pdb etc.)
  -- https://werkzeug.palletsprojects.com/en/2.0.x/serving/
  
  Example:
  ```
  $ cd contrib/docker
  $ docker-compose up --build -d
  $ # wait...
  $ docker-compose exec ckan bash
  root@f6a71d0b7686:/# python3 -m pdb /usr/lib/ckan/venv/bin/ckan -c /etc/ckan/production.ini run --host 0.0.0.0 -E --disable-reloader
  > /usr/lib/ckan/venv/bin/ckan(3)<module>()
  -> import re
  (Pdb) b ckan/views/api.py:215
  Breakpoint 1 at /usr/lib/ckan/venv/src/ckan/ckan/views/api.py:215
  (Pdb) c
  2021-11-01 17:00:50,832 INFO  [ckan.cli] Using configuration file /etc/ckan/production.ini
  2021-11-01 17:00:50,832 INFO  [ckan.config.environment] Loading static files from public
  2021-11-01 17:00:50,954 INFO  [ckan.config.environment] Loading templates from /usr/lib/ckan/venv/src/ckan/ckan/templates
  2021-11-01 17:00:51,552 INFO  [ckan.config.environment] Loading templates from /usr/lib/ckan/venv/src/ckan/ckan/templates
  2021-11-01 17:00:52,173 INFO  [ckan.cli.server] Running CKAN on http://0.0.0.0:5000
  2021-11-01 17:00:52,174 WARNI [werkzeug]  * Running on all addresses.
     WARNING: This is a development server. Do not use it in a production deployment.
  ```
  
  ...then `http://localhost:5000/api/3/action/package_search` can be opened in the web browser to trigger the breakpoint:
  
  ```
  > /usr/lib/ckan/venv/src/ckan/ckan/views/api.py(215)action()
  -> try:
  (Pdb)
  ```
  
  ### Features:
  
  - [ ] includes tests covering changes
  - [x] includes updated documentation
  - [X] includes user-visible changes
  - [ ] includes API changes
  - [ ] includes bugfix for possible backport
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `ckan/cli/server.py`
  Content:
  ```
  1 # encoding: utf-8
  2 
  3 import logging
  4 
  5 import click
  6 from werkzeug.serving import run_simple
  7 
  8 import ckan.plugins.toolkit as tk
  9 from ckan.common import config
  10 
  11 log = logging.getLogger(__name__)
  12 
  13 DEFAULT_HOST = u"localhost"
  14 DEFAULT_PORT = 5000
  15 
  16 
  17 @click.command(u"run", short_help=u"Start development server")
  18 @click.option(u"-H", u"--host", help=u"Host name")
  19 @click.option(u"-p", u"--port", help=u"Port number")
  20 @click.option(u"-r", u"--disable-reloader", is_flag=True,
  21               help=u"Disable reloader")
  22 @click.option(
  23     u"-t", u"--threaded", is_flag=True,
  24     help=u"Handle each request in a separate thread"
  25 )
  26 @click.option(
  27     u"--processes", type=int, default=0,
  28     help=u"Maximum number of concurrent processes"
  29 )
  30 @click.option(
  31     u"-e", u"--extra-files", multiple=True,
  32     help=u"Additional files that should be watched for server reloading"
  33     " (you can provide multiple values)")
  34 @click.option(
  35     u"-C", u"--ssl-cert", default=None,
  36     help=u"Certificate file to use to enable SSL. Passing 'adhoc' will "
  37     " automatically generate a new one (on each server reload).")
  38 @click.option(
  39     u"-K", u"--ssl-key", default=None,
  40     help=u"Key file to use to enable SSL. Passing 'adhoc' will "
  41     " automatically generate a new one (on each server reload).")
  42 @click.pass_context
  43 def run(ctx, host, port, disable_reloader, threaded, extra_files, processes,
  44         ssl_cert, ssl_key):
  45     u"""Runs the Werkzeug development server"""
  46 
  47     # Reloading
  48     use_reloader = not disable_reloader
  49     config_extra_files = tk.aslist(
  50         config.get(u"ckan.devserver.watch_patterns")
  51     )
  52     extra_files = list(extra_files) + [
  53         config[u"__file__"]
  54     ] + config_extra_files
  55 
  56     # Threads and processes
  57     threaded = threaded or tk.asbool(config.get(u"ckan.devserver.threaded"))
  58     processes = processes or tk.asint(
  59         config.get(u"ckan.devserver.multiprocess", 1)
  60     )
  61     if threaded and processes > 1:
  62         tk.error_shout(u"Cannot have a multithreaded and multi process server")
  63         raise click.Abort()
  64 
  65     # SSL
  66     cert_file = ssl_cert or config.get(u"ckan.devserver.ssl_cert")
  67     key_file = ssl_key or config.get(u"ckan.devserver.ssl_key")
  68 
  69     if cert_file and key_file:
  70         if cert_file == key_file == u"adhoc":
  71             ssl_context = u"adhoc"
  72         else:
  73             ssl_context = (ssl_cert, ssl_key)
  74     else:
  75         ssl_context = None
  76 
  77     host = host or config.get(u'ckan.devserver.host', DEFAULT_HOST)
  78     port = port or config.get(u'ckan.devserver.port', DEFAULT_PORT)
  79     try:
  80         port = int(port)
  81     except ValueError:
  82         tk.error_shout(u"Server port must be an integer, not {}".format(port))
  83         raise click.Abort()
  84 
  85     log.info(u"Running CKAN on {scheme}://{host}:{port}".format(
  86         scheme=u"https" if ssl_context else u"http", host=host, port=port))
  87 
  88     run_simple(
  89         host,
  90         port,
  91         ctx.obj.app,
  92         use_reloader=use_reloader,
  93         use_evalex=True,
  94         threaded=threaded,
  95         processes=processes,
  96         extra_files=extra_files,
  97         ssl_context=ssl_context,
  98     )
  99
  ```
  --- 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/ckan/cli/server.py b/ckan/cli/server.py
  --- a/ckan/cli/server.py
  +++ b/ckan/cli/server.py
  @@ -19,6 +19,8 @@
   @click.option(u"-p", u"--port", help=u"Port number")
   @click.option(u"-r", u"--disable-reloader", is_flag=True,
                 help=u"Disable reloader")
  +@click.option(u"-E", u"--passthrough-errors", is_flag=True,
  +              help=u"Disable error caching (useful to hook debuggers)")
   @click.option(
       u"-t", u"--threaded", is_flag=True,
       help=u"Handle each request in a separate thread"
  @@ -40,10 +42,16 @@
       help=u"Key file to use to enable SSL. Passing 'adhoc' will "
       " automatically generate a new one (on each server reload).")
   @click.pass_context
  -def run(ctx, host, port, disable_reloader, threaded, extra_files, processes,
  -        ssl_cert, ssl_key):
  +def run(ctx, host, port, disable_reloader, passthrough_errors, threaded,
  +        extra_files, processes, ssl_cert, ssl_key):
       u"""Runs the Werkzeug development server"""
   
  +    # passthrough_errors overrides conflicting options
  +    if passthrough_errors:
  +        disable_reloader = True
  +        threaded = False
  +        processes = 1
  +
       # Reloading
       use_reloader = not disable_reloader
       config_extra_files = tk.aslist(
  @@ -95,4 +103,5 @@
           processes=processes,
           extra_files=extra_files,
           ssl_context=ssl_context,
  +        passthrough_errors=passthrough_errors,
       )
  
verification_info: {"golden_diff": "diff --git a/ckan/cli/server.py b/ckan/cli/server.py\n--- a/ckan/cli/server.py\n+++ b/ckan/cli/server.py\n@@ -19,6 +19,8 @@\n @click.option(u\"-p\", u\"--port\", help=u\"Port number\")\n @click.option(u\"-r\", u\"--disable-reloader\", is_flag=True,\n               help=u\"Disable reloader\")\n+@click.option(u\"-E\", u\"--passthrough-errors\", is_flag=True,\n+              help=u\"Disable error caching (useful to hook debuggers)\")\n @click.option(\n     u\"-t\", u\"--threaded\", is_flag=True,\n     help=u\"Handle each request in a separate thread\"\n@@ -40,10 +42,16 @@\n     help=u\"Key file to use to enable SSL. Passing 'adhoc' will \"\n     \" automatically generate a new one (on each server reload).\")\n @click.pass_context\n-def run(ctx, host, port, disable_reloader, threaded, extra_files, processes,\n-        ssl_cert, ssl_key):\n+def run(ctx, host, port, disable_reloader, passthrough_errors, threaded,\n+        extra_files, processes, ssl_cert, ssl_key):\n     u\"\"\"Runs the Werkzeug development server\"\"\"\n \n+    # passthrough_errors overrides conflicting options\n+    if passthrough_errors:\n+        disable_reloader = True\n+        threaded = False\n+        processes = 1\n+\n     # Reloading\n     use_reloader = not disable_reloader\n     config_extra_files = tk.aslist(\n@@ -95,4 +103,5 @@\n         processes=processes,\n         extra_files=extra_files,\n         ssl_context=ssl_context,\n+        passthrough_errors=passthrough_errors,\n     )\n", "issue": "Support for pdb and debuggers\n### Proposed fixes:\r\n\r\nIt is now possible to debug ckan with pdb/ipdb/PyCharm debugger and others, both outside Docker and inside Docker.\r\nI just exposed a `werkzeug` option to the CKAN CLI, called `passthrough_errors`. Enabling that, together with `--disable-reloader` (which should be the default in my opinion, like it was in the past), allow to run pdb without making other changes to the source code.\r\n`threads` should not be enabled and `processes` should be set to 1. These are the defaults already.\r\n\r\n> passthrough_errors (bool) \u2013 set this to True to disable the error catching. This means that the server will die on errors but it can be useful to hook debuggers in (pdb etc.)\r\n-- https://werkzeug.palletsprojects.com/en/2.0.x/serving/\r\n\r\nExample:\r\n```\r\n$ cd contrib/docker\r\n$ docker-compose up --build -d\r\n$ # wait...\r\n$ docker-compose exec ckan bash\r\nroot@f6a71d0b7686:/# python3 -m pdb /usr/lib/ckan/venv/bin/ckan -c /etc/ckan/production.ini run --host 0.0.0.0 -E --disable-reloader\r\n> /usr/lib/ckan/venv/bin/ckan(3)<module>()\r\n-> import re\r\n(Pdb) b ckan/views/api.py:215\r\nBreakpoint 1 at /usr/lib/ckan/venv/src/ckan/ckan/views/api.py:215\r\n(Pdb) c\r\n2021-11-01 17:00:50,832 INFO  [ckan.cli] Using configuration file /etc/ckan/production.ini\r\n2021-11-01 17:00:50,832 INFO  [ckan.config.environment] Loading static files from public\r\n2021-11-01 17:00:50,954 INFO  [ckan.config.environment] Loading templates from /usr/lib/ckan/venv/src/ckan/ckan/templates\r\n2021-11-01 17:00:51,552 INFO  [ckan.config.environment] Loading templates from /usr/lib/ckan/venv/src/ckan/ckan/templates\r\n2021-11-01 17:00:52,173 INFO  [ckan.cli.server] Running CKAN on http://0.0.0.0:5000\r\n2021-11-01 17:00:52,174 WARNI [werkzeug]  * Running on all addresses.\r\n   WARNING: This is a development server. Do not use it in a production deployment.\r\n```\r\n\r\n...then `http://localhost:5000/api/3/action/package_search` can be opened in the web browser to trigger the breakpoint:\r\n\r\n```\r\n> /usr/lib/ckan/venv/src/ckan/ckan/views/api.py(215)action()\r\n-> try:\r\n(Pdb)\r\n```\r\n\r\n### Features:\r\n\r\n- [ ] includes tests covering changes\r\n- [x] includes updated documentation\r\n- [X] includes user-visible changes\r\n- [ ] includes API changes\r\n- [ ] includes bugfix for possible backport\n", "before_files": [{"content": "# encoding: utf-8\n\nimport logging\n\nimport click\nfrom werkzeug.serving import run_simple\n\nimport ckan.plugins.toolkit as tk\nfrom ckan.common import config\n\nlog = logging.getLogger(__name__)\n\nDEFAULT_HOST = u\"localhost\"\nDEFAULT_PORT = 5000\n\n\n@click.command(u\"run\", short_help=u\"Start development server\")\n@click.option(u\"-H\", u\"--host\", help=u\"Host name\")\n@click.option(u\"-p\", u\"--port\", help=u\"Port number\")\n@click.option(u\"-r\", u\"--disable-reloader\", is_flag=True,\n              help=u\"Disable reloader\")\n@click.option(\n    u\"-t\", u\"--threaded\", is_flag=True,\n    help=u\"Handle each request in a separate thread\"\n)\n@click.option(\n    u\"--processes\", type=int, default=0,\n    help=u\"Maximum number of concurrent processes\"\n)\n@click.option(\n    u\"-e\", u\"--extra-files\", multiple=True,\n    help=u\"Additional files that should be watched for server reloading\"\n    \" (you can provide multiple values)\")\n@click.option(\n    u\"-C\", u\"--ssl-cert\", default=None,\n    help=u\"Certificate file to use to enable SSL. Passing 'adhoc' will \"\n    \" automatically generate a new one (on each server reload).\")\n@click.option(\n    u\"-K\", u\"--ssl-key\", default=None,\n    help=u\"Key file to use to enable SSL. Passing 'adhoc' will \"\n    \" automatically generate a new one (on each server reload).\")\n@click.pass_context\ndef run(ctx, host, port, disable_reloader, threaded, extra_files, processes,\n        ssl_cert, ssl_key):\n    u\"\"\"Runs the Werkzeug development server\"\"\"\n\n    # Reloading\n    use_reloader = not disable_reloader\n    config_extra_files = tk.aslist(\n        config.get(u\"ckan.devserver.watch_patterns\")\n    )\n    extra_files = list(extra_files) + [\n        config[u\"__file__\"]\n    ] + config_extra_files\n\n    # Threads and processes\n    threaded = threaded or tk.asbool(config.get(u\"ckan.devserver.threaded\"))\n    processes = processes or tk.asint(\n        config.get(u\"ckan.devserver.multiprocess\", 1)\n    )\n    if threaded and processes > 1:\n        tk.error_shout(u\"Cannot have a multithreaded and multi process server\")\n        raise click.Abort()\n\n    # SSL\n    cert_file = ssl_cert or config.get(u\"ckan.devserver.ssl_cert\")\n    key_file = ssl_key or config.get(u\"ckan.devserver.ssl_key\")\n\n    if cert_file and key_file:\n        if cert_file == key_file == u\"adhoc\":\n            ssl_context = u\"adhoc\"\n        else:\n            ssl_context = (ssl_cert, ssl_key)\n    else:\n        ssl_context = None\n\n    host = host or config.get(u'ckan.devserver.host', DEFAULT_HOST)\n    port = port or config.get(u'ckan.devserver.port', DEFAULT_PORT)\n    try:\n        port = int(port)\n    except ValueError:\n        tk.error_shout(u\"Server port must be an integer, not {}\".format(port))\n        raise click.Abort()\n\n    log.info(u\"Running CKAN on {scheme}://{host}:{port}\".format(\n        scheme=u\"https\" if ssl_context else u\"http\", host=host, port=port))\n\n    run_simple(\n        host,\n        port,\n        ctx.obj.app,\n        use_reloader=use_reloader,\n        use_evalex=True,\n        threaded=threaded,\n        processes=processes,\n        extra_files=extra_files,\n        ssl_context=ssl_context,\n    )\n", "path": "ckan/cli/server.py"}], "after_files": [{"content": "# encoding: utf-8\n\nimport logging\n\nimport click\nfrom werkzeug.serving import run_simple\n\nimport ckan.plugins.toolkit as tk\nfrom ckan.common import config\n\nlog = logging.getLogger(__name__)\n\nDEFAULT_HOST = u\"localhost\"\nDEFAULT_PORT = 5000\n\n\n@click.command(u\"run\", short_help=u\"Start development server\")\n@click.option(u\"-H\", u\"--host\", help=u\"Host name\")\n@click.option(u\"-p\", u\"--port\", help=u\"Port number\")\n@click.option(u\"-r\", u\"--disable-reloader\", is_flag=True,\n              help=u\"Disable reloader\")\n@click.option(u\"-E\", u\"--passthrough-errors\", is_flag=True,\n              help=u\"Disable error caching (useful to hook debuggers)\")\n@click.option(\n    u\"-t\", u\"--threaded\", is_flag=True,\n    help=u\"Handle each request in a separate thread\"\n)\n@click.option(\n    u\"--processes\", type=int, default=0,\n    help=u\"Maximum number of concurrent processes\"\n)\n@click.option(\n    u\"-e\", u\"--extra-files\", multiple=True,\n    help=u\"Additional files that should be watched for server reloading\"\n    \" (you can provide multiple values)\")\n@click.option(\n    u\"-C\", u\"--ssl-cert\", default=None,\n    help=u\"Certificate file to use to enable SSL. Passing 'adhoc' will \"\n    \" automatically generate a new one (on each server reload).\")\n@click.option(\n    u\"-K\", u\"--ssl-key\", default=None,\n    help=u\"Key file to use to enable SSL. Passing 'adhoc' will \"\n    \" automatically generate a new one (on each server reload).\")\n@click.pass_context\ndef run(ctx, host, port, disable_reloader, passthrough_errors, threaded,\n        extra_files, processes, ssl_cert, ssl_key):\n    u\"\"\"Runs the Werkzeug development server\"\"\"\n\n    # passthrough_errors overrides conflicting options\n    if passthrough_errors:\n        disable_reloader = True\n        threaded = False\n        processes = 1\n\n    # Reloading\n    use_reloader = not disable_reloader\n    config_extra_files = tk.aslist(\n        config.get(u\"ckan.devserver.watch_patterns\")\n    )\n    extra_files = list(extra_files) + [\n        config[u\"__file__\"]\n    ] + config_extra_files\n\n    # Threads and processes\n    threaded = threaded or tk.asbool(config.get(u\"ckan.devserver.threaded\"))\n    processes = processes or tk.asint(\n        config.get(u\"ckan.devserver.multiprocess\", 1)\n    )\n    if threaded and processes > 1:\n        tk.error_shout(u\"Cannot have a multithreaded and multi process server\")\n        raise click.Abort()\n\n    # SSL\n    cert_file = ssl_cert or config.get(u\"ckan.devserver.ssl_cert\")\n    key_file = ssl_key or config.get(u\"ckan.devserver.ssl_key\")\n\n    if cert_file and key_file:\n        if cert_file == key_file == u\"adhoc\":\n            ssl_context = u\"adhoc\"\n        else:\n            ssl_context = (ssl_cert, ssl_key)\n    else:\n        ssl_context = None\n\n    host = host or config.get(u'ckan.devserver.host', DEFAULT_HOST)\n    port = port or config.get(u'ckan.devserver.port', DEFAULT_PORT)\n    try:\n        port = int(port)\n    except ValueError:\n        tk.error_shout(u\"Server port must be an integer, not {}\".format(port))\n        raise click.Abort()\n\n    log.info(u\"Running CKAN on {scheme}://{host}:{port}\".format(\n        scheme=u\"https\" if ssl_context else u\"http\", host=host, port=port))\n\n    run_simple(\n        host,\n        port,\n        ctx.obj.app,\n        use_reloader=use_reloader,\n        use_evalex=True,\n        threaded=threaded,\n        processes=processes,\n        extra_files=extra_files,\n        ssl_context=ssl_context,\n        passthrough_errors=passthrough_errors,\n    )\n", "path": "ckan/cli/server.py"}]}