prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  dev server hot reload has stopped working
  ## Description
  
  In #5532 the `env` attribute was dropped from `SDConfig` in `sdconfig.py`. That value is checked in [`source.py`](https://github.com/freedomofpress/securedrop/blob/6246482157e31d0655a91c5e7284cc8550f2c289/securedrop/source.py#L11) and [`journalist.py`](https://github.com/freedomofpress/securedrop/blob/6246482157e31d0655a91c5e7284cc8550f2c289/securedrop/journalist.py#L26) to determine whether the Flask app will run in [debug](https://flask.palletsprojects.com/en/1.1.x/config/#DEBUG) mode. By default it will not, so the dev server has stopped responding to code changes.
  
  Given the Flask documentation warnings about setting debug mode via code and not the `FLASK_DEBUG` environment variable, we may want to reevaluate all of this, but right now let's just get back to a properly functioning dev server.
  
  ## Steps to Reproduce
  
  - Check out `develop` at a commit before the `sdconfig.py` change (eff931fa8a0e74d5c3be87e46c5d0f004f02e289).
  - Run `make dev`.
  - Change `securedrop/journalist_app/main.py` to trigger a reload, and confirm that the change is detected.
  - Stop the dev server.
  - Check out `develop` and run `make dev`.
  - Change `securedrop/journalist_app/main.py` again, and observe that the change is not detected.
  
  ## Expected Behavior
  
  That the dev server would notice code changes and reload to pick them up.
  
  ## Actual Behavior
  
  It does not care one whit about your useless flailings. We are all `prod` now.
  
  ## Comments
  
  Just need to restore `SDConfig.env`.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `securedrop/sdconfig.py`
  Content:
  ```
  1 from typing import Dict
  2 from typing import Optional
  3 
  4 from typing import Type
  5 
  6 import config as _config
  7 from typing import List
  8 
  9 
  10 class SDConfig:
  11     def __init__(self) -> None:
  12         self.JOURNALIST_APP_FLASK_CONFIG_CLS = \
  13             _config.JournalistInterfaceFlaskConfig  # type: Type
  14 
  15         self.SOURCE_APP_FLASK_CONFIG_CLS = \
  16             _config.SourceInterfaceFlaskConfig  # type: Type
  17 
  18         self.DATABASE_ENGINE = _config.DATABASE_ENGINE  # type: str
  19         self.DATABASE_FILE = _config.DATABASE_FILE  # type: str
  20 
  21         self.DATABASE_USERNAME = getattr(_config, "DATABASE_USERNAME", None)  # type: Optional[str]
  22         self.DATABASE_PASSWORD = getattr(_config, "DATABASE_PASSWORD", None)  # type: Optional[str]
  23         self.DATABASE_HOST = getattr(_config, "DATABASE_HOST", None)  # type: Optional[str]
  24         self.DATABASE_NAME = getattr(_config, "DATABASE_NAME", None)  # type: Optional[str]
  25 
  26         self.ADJECTIVES = _config.ADJECTIVES  # type: str
  27         self.NOUNS = _config.NOUNS  # type: str
  28         self.WORD_LIST = _config.WORD_LIST  # type: str
  29 
  30         self.DEFAULT_LOCALE = _config.DEFAULT_LOCALE  # type: str
  31         self.SUPPORTED_LOCALES = getattr(
  32             _config, "SUPPORTED_LOCALES", [self.DEFAULT_LOCALE]
  33         )  # type: List[str]
  34 
  35         self.GPG_KEY_DIR = _config.GPG_KEY_DIR  # type: str
  36 
  37         self.JOURNALIST_KEY = _config.JOURNALIST_KEY  # type: str
  38         self.JOURNALIST_TEMPLATES_DIR = _config.JOURNALIST_TEMPLATES_DIR  # type: str
  39 
  40         self.SCRYPT_GPG_PEPPER = _config.SCRYPT_GPG_PEPPER  # type: str
  41         self.SCRYPT_ID_PEPPER = _config.SCRYPT_ID_PEPPER  # type: str
  42         self.SCRYPT_PARAMS = _config.SCRYPT_PARAMS  # type: Dict[str, int]
  43 
  44         self.SECUREDROP_DATA_ROOT = _config.SECUREDROP_DATA_ROOT  # type: str
  45         self.SECUREDROP_ROOT = _config.SECUREDROP_ROOT  # type: str
  46 
  47         self.SESSION_EXPIRATION_MINUTES = _config.SESSION_EXPIRATION_MINUTES  # type: int
  48 
  49         self.SOURCE_TEMPLATES_DIR = _config.SOURCE_TEMPLATES_DIR  # type: str
  50         self.TEMP_DIR = _config.TEMP_DIR  # type: str
  51         self.STORE_DIR = _config.STORE_DIR  # type: str
  52         self.TRANSLATION_DIRS = getattr(_config, "TRANSLATION_DIRS", None)  # type: Optional[str]
  53 
  54         self.WORKER_PIDFILE = _config.WORKER_PIDFILE  # type: str
  55 
  56         if _config.env == 'test':
  57             self.RQ_WORKER_NAME = 'test'  # type: str
  58         else:
  59             self.RQ_WORKER_NAME = 'default'
  60 
  61     @property
  62     def DATABASE_URI(self) -> str:
  63         if self.DATABASE_ENGINE == "sqlite":
  64             db_uri = (self.DATABASE_ENGINE + ":///" +
  65                       self.DATABASE_FILE)
  66         else:
  67             if self.DATABASE_USERNAME is None:
  68                 raise RuntimeError("Missing DATABASE_USERNAME entry from config.py")
  69             if self.DATABASE_PASSWORD is None:
  70                 raise RuntimeError("Missing DATABASE_PASSWORD entry from config.py")
  71             if self.DATABASE_HOST is None:
  72                 raise RuntimeError("Missing DATABASE_HOST entry from config.py")
  73             if self.DATABASE_NAME is None:
  74                 raise RuntimeError("Missing DATABASE_NAME entry from config.py")
  75 
  76             db_uri = (
  77                 self.DATABASE_ENGINE + '://' +
  78                 self.DATABASE_USERNAME + ':' +
  79                 self.DATABASE_PASSWORD + '@' +
  80                 self.DATABASE_HOST + '/' +
  81                 self.DATABASE_NAME
  82             )
  83         return db_uri
  84 
  85 
  86 config = SDConfig()  # type: SDConfig
  87
  ```
  --- 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/securedrop/sdconfig.py b/securedrop/sdconfig.py
  --- a/securedrop/sdconfig.py
  +++ b/securedrop/sdconfig.py
  @@ -53,7 +53,8 @@
   
           self.WORKER_PIDFILE = _config.WORKER_PIDFILE  # type: str
   
  -        if _config.env == 'test':
  +        self.env = getattr(_config, 'env', 'prod')  # type: str
  +        if self.env == 'test':
               self.RQ_WORKER_NAME = 'test'  # type: str
           else:
               self.RQ_WORKER_NAME = 'default'
  
verification_info: {"golden_diff": "diff --git a/securedrop/sdconfig.py b/securedrop/sdconfig.py\n--- a/securedrop/sdconfig.py\n+++ b/securedrop/sdconfig.py\n@@ -53,7 +53,8 @@\n \n         self.WORKER_PIDFILE = _config.WORKER_PIDFILE  # type: str\n \n-        if _config.env == 'test':\n+        self.env = getattr(_config, 'env', 'prod')  # type: str\n+        if self.env == 'test':\n             self.RQ_WORKER_NAME = 'test'  # type: str\n         else:\n             self.RQ_WORKER_NAME = 'default'\n", "issue": "dev server hot reload has stopped working\n## Description\r\n\r\nIn #5532 the `env` attribute was dropped from `SDConfig` in `sdconfig.py`. That value is checked in [`source.py`](https://github.com/freedomofpress/securedrop/blob/6246482157e31d0655a91c5e7284cc8550f2c289/securedrop/source.py#L11) and [`journalist.py`](https://github.com/freedomofpress/securedrop/blob/6246482157e31d0655a91c5e7284cc8550f2c289/securedrop/journalist.py#L26) to determine whether the Flask app will run in [debug](https://flask.palletsprojects.com/en/1.1.x/config/#DEBUG) mode. By default it will not, so the dev server has stopped responding to code changes.\r\n\r\nGiven the Flask documentation warnings about setting debug mode via code and not the `FLASK_DEBUG` environment variable, we may want to reevaluate all of this, but right now let's just get back to a properly functioning dev server.\r\n\r\n## Steps to Reproduce\r\n\r\n- Check out `develop` at a commit before the `sdconfig.py` change (eff931fa8a0e74d5c3be87e46c5d0f004f02e289).\r\n- Run `make dev`.\r\n- Change `securedrop/journalist_app/main.py` to trigger a reload, and confirm that the change is detected.\r\n- Stop the dev server.\r\n- Check out `develop` and run `make dev`.\r\n- Change `securedrop/journalist_app/main.py` again, and observe that the change is not detected.\r\n\r\n## Expected Behavior\r\n\r\nThat the dev server would notice code changes and reload to pick them up.\r\n\r\n## Actual Behavior\r\n\r\nIt does not care one whit about your useless flailings. We are all `prod` now.\r\n\r\n## Comments\r\n\r\nJust need to restore `SDConfig.env`.\r\n\n", "before_files": [{"content": "from typing import Dict\nfrom typing import Optional\n\nfrom typing import Type\n\nimport config as _config\nfrom typing import List\n\n\nclass SDConfig:\n    def __init__(self) -> None:\n        self.JOURNALIST_APP_FLASK_CONFIG_CLS = \\\n            _config.JournalistInterfaceFlaskConfig  # type: Type\n\n        self.SOURCE_APP_FLASK_CONFIG_CLS = \\\n            _config.SourceInterfaceFlaskConfig  # type: Type\n\n        self.DATABASE_ENGINE = _config.DATABASE_ENGINE  # type: str\n        self.DATABASE_FILE = _config.DATABASE_FILE  # type: str\n\n        self.DATABASE_USERNAME = getattr(_config, \"DATABASE_USERNAME\", None)  # type: Optional[str]\n        self.DATABASE_PASSWORD = getattr(_config, \"DATABASE_PASSWORD\", None)  # type: Optional[str]\n        self.DATABASE_HOST = getattr(_config, \"DATABASE_HOST\", None)  # type: Optional[str]\n        self.DATABASE_NAME = getattr(_config, \"DATABASE_NAME\", None)  # type: Optional[str]\n\n        self.ADJECTIVES = _config.ADJECTIVES  # type: str\n        self.NOUNS = _config.NOUNS  # type: str\n        self.WORD_LIST = _config.WORD_LIST  # type: str\n\n        self.DEFAULT_LOCALE = _config.DEFAULT_LOCALE  # type: str\n        self.SUPPORTED_LOCALES = getattr(\n            _config, \"SUPPORTED_LOCALES\", [self.DEFAULT_LOCALE]\n        )  # type: List[str]\n\n        self.GPG_KEY_DIR = _config.GPG_KEY_DIR  # type: str\n\n        self.JOURNALIST_KEY = _config.JOURNALIST_KEY  # type: str\n        self.JOURNALIST_TEMPLATES_DIR = _config.JOURNALIST_TEMPLATES_DIR  # type: str\n\n        self.SCRYPT_GPG_PEPPER = _config.SCRYPT_GPG_PEPPER  # type: str\n        self.SCRYPT_ID_PEPPER = _config.SCRYPT_ID_PEPPER  # type: str\n        self.SCRYPT_PARAMS = _config.SCRYPT_PARAMS  # type: Dict[str, int]\n\n        self.SECUREDROP_DATA_ROOT = _config.SECUREDROP_DATA_ROOT  # type: str\n        self.SECUREDROP_ROOT = _config.SECUREDROP_ROOT  # type: str\n\n        self.SESSION_EXPIRATION_MINUTES = _config.SESSION_EXPIRATION_MINUTES  # type: int\n\n        self.SOURCE_TEMPLATES_DIR = _config.SOURCE_TEMPLATES_DIR  # type: str\n        self.TEMP_DIR = _config.TEMP_DIR  # type: str\n        self.STORE_DIR = _config.STORE_DIR  # type: str\n        self.TRANSLATION_DIRS = getattr(_config, \"TRANSLATION_DIRS\", None)  # type: Optional[str]\n\n        self.WORKER_PIDFILE = _config.WORKER_PIDFILE  # type: str\n\n        if _config.env == 'test':\n            self.RQ_WORKER_NAME = 'test'  # type: str\n        else:\n            self.RQ_WORKER_NAME = 'default'\n\n    @property\n    def DATABASE_URI(self) -> str:\n        if self.DATABASE_ENGINE == \"sqlite\":\n            db_uri = (self.DATABASE_ENGINE + \":///\" +\n                      self.DATABASE_FILE)\n        else:\n            if self.DATABASE_USERNAME is None:\n                raise RuntimeError(\"Missing DATABASE_USERNAME entry from config.py\")\n            if self.DATABASE_PASSWORD is None:\n                raise RuntimeError(\"Missing DATABASE_PASSWORD entry from config.py\")\n            if self.DATABASE_HOST is None:\n                raise RuntimeError(\"Missing DATABASE_HOST entry from config.py\")\n            if self.DATABASE_NAME is None:\n                raise RuntimeError(\"Missing DATABASE_NAME entry from config.py\")\n\n            db_uri = (\n                self.DATABASE_ENGINE + '://' +\n                self.DATABASE_USERNAME + ':' +\n                self.DATABASE_PASSWORD + '@' +\n                self.DATABASE_HOST + '/' +\n                self.DATABASE_NAME\n            )\n        return db_uri\n\n\nconfig = SDConfig()  # type: SDConfig\n", "path": "securedrop/sdconfig.py"}], "after_files": [{"content": "from typing import Dict\nfrom typing import Optional\n\nfrom typing import Type\n\nimport config as _config\nfrom typing import List\n\n\nclass SDConfig:\n    def __init__(self) -> None:\n        self.JOURNALIST_APP_FLASK_CONFIG_CLS = \\\n            _config.JournalistInterfaceFlaskConfig  # type: Type\n\n        self.SOURCE_APP_FLASK_CONFIG_CLS = \\\n            _config.SourceInterfaceFlaskConfig  # type: Type\n\n        self.DATABASE_ENGINE = _config.DATABASE_ENGINE  # type: str\n        self.DATABASE_FILE = _config.DATABASE_FILE  # type: str\n\n        self.DATABASE_USERNAME = getattr(_config, \"DATABASE_USERNAME\", None)  # type: Optional[str]\n        self.DATABASE_PASSWORD = getattr(_config, \"DATABASE_PASSWORD\", None)  # type: Optional[str]\n        self.DATABASE_HOST = getattr(_config, \"DATABASE_HOST\", None)  # type: Optional[str]\n        self.DATABASE_NAME = getattr(_config, \"DATABASE_NAME\", None)  # type: Optional[str]\n\n        self.ADJECTIVES = _config.ADJECTIVES  # type: str\n        self.NOUNS = _config.NOUNS  # type: str\n        self.WORD_LIST = _config.WORD_LIST  # type: str\n\n        self.DEFAULT_LOCALE = _config.DEFAULT_LOCALE  # type: str\n        self.SUPPORTED_LOCALES = getattr(\n            _config, \"SUPPORTED_LOCALES\", [self.DEFAULT_LOCALE]\n        )  # type: List[str]\n\n        self.GPG_KEY_DIR = _config.GPG_KEY_DIR  # type: str\n\n        self.JOURNALIST_KEY = _config.JOURNALIST_KEY  # type: str\n        self.JOURNALIST_TEMPLATES_DIR = _config.JOURNALIST_TEMPLATES_DIR  # type: str\n\n        self.SCRYPT_GPG_PEPPER = _config.SCRYPT_GPG_PEPPER  # type: str\n        self.SCRYPT_ID_PEPPER = _config.SCRYPT_ID_PEPPER  # type: str\n        self.SCRYPT_PARAMS = _config.SCRYPT_PARAMS  # type: Dict[str, int]\n\n        self.SECUREDROP_DATA_ROOT = _config.SECUREDROP_DATA_ROOT  # type: str\n        self.SECUREDROP_ROOT = _config.SECUREDROP_ROOT  # type: str\n\n        self.SESSION_EXPIRATION_MINUTES = _config.SESSION_EXPIRATION_MINUTES  # type: int\n\n        self.SOURCE_TEMPLATES_DIR = _config.SOURCE_TEMPLATES_DIR  # type: str\n        self.TEMP_DIR = _config.TEMP_DIR  # type: str\n        self.STORE_DIR = _config.STORE_DIR  # type: str\n        self.TRANSLATION_DIRS = getattr(_config, \"TRANSLATION_DIRS\", None)  # type: Optional[str]\n\n        self.WORKER_PIDFILE = _config.WORKER_PIDFILE  # type: str\n\n        self.env = getattr(_config, 'env', 'prod')  # type: str\n        if self.env == 'test':\n            self.RQ_WORKER_NAME = 'test'  # type: str\n        else:\n            self.RQ_WORKER_NAME = 'default'\n\n    @property\n    def DATABASE_URI(self) -> str:\n        if self.DATABASE_ENGINE == \"sqlite\":\n            db_uri = (self.DATABASE_ENGINE + \":///\" +\n                      self.DATABASE_FILE)\n        else:\n            if self.DATABASE_USERNAME is None:\n                raise RuntimeError(\"Missing DATABASE_USERNAME entry from config.py\")\n            if self.DATABASE_PASSWORD is None:\n                raise RuntimeError(\"Missing DATABASE_PASSWORD entry from config.py\")\n            if self.DATABASE_HOST is None:\n                raise RuntimeError(\"Missing DATABASE_HOST entry from config.py\")\n            if self.DATABASE_NAME is None:\n                raise RuntimeError(\"Missing DATABASE_NAME entry from config.py\")\n\n            db_uri = (\n                self.DATABASE_ENGINE + '://' +\n                self.DATABASE_USERNAME + ':' +\n                self.DATABASE_PASSWORD + '@' +\n                self.DATABASE_HOST + '/' +\n                self.DATABASE_NAME\n            )\n        return db_uri\n\n\nconfig = SDConfig()  # type: SDConfig\n", "path": "securedrop/sdconfig.py"}]}