prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Edit user config file programatically
  It would be great to be able to modify the user config file from Qiskit. Something like `user_config['default']['option'] = True`.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `qiskit/user_config.py`
  Content:
  ```
  1 # This code is part of Qiskit.
  2 #
  3 # (C) Copyright IBM 2017, 2019.
  4 #
  5 # This code is licensed under the Apache License, Version 2.0. You may
  6 # obtain a copy of this license in the LICENSE.txt file in the root directory
  7 # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
  8 #
  9 # Any modifications or derivative works of this code must retain this
  10 # copyright notice, and modified files need to carry a notice indicating
  11 # that they have been altered from the originals.
  12 
  13 """Utils for reading a user preference config files."""
  14 
  15 import configparser
  16 import os
  17 from warnings import warn
  18 
  19 from qiskit import exceptions
  20 
  21 DEFAULT_FILENAME = os.path.join(os.path.expanduser("~"), ".qiskit", "settings.conf")
  22 
  23 
  24 class UserConfig:
  25     """Class representing a user config file
  26 
  27     The config file format should look like:
  28 
  29     [default]
  30     circuit_drawer = mpl
  31     circuit_mpl_style = default
  32     circuit_mpl_style_path = ~/.qiskit:<default location>
  33     transpile_optimization_level = 1
  34     parallel = False
  35     num_processes = 4
  36 
  37     """
  38 
  39     def __init__(self, filename=None):
  40         """Create a UserConfig
  41 
  42         Args:
  43             filename (str): The path to the user config file. If one isn't
  44                 specified, ~/.qiskit/settings.conf is used.
  45         """
  46         if filename is None:
  47             self.filename = DEFAULT_FILENAME
  48         else:
  49             self.filename = filename
  50         self.settings = {}
  51         self.config_parser = configparser.ConfigParser()
  52 
  53     def read_config_file(self):
  54         """Read config file and parse the contents into the settings attr."""
  55         if not os.path.isfile(self.filename):
  56             return
  57         self.config_parser.read(self.filename)
  58         if "default" in self.config_parser.sections():
  59             # Parse circuit_drawer
  60             circuit_drawer = self.config_parser.get("default", "circuit_drawer", fallback=None)
  61             if circuit_drawer:
  62                 if circuit_drawer not in ["text", "mpl", "latex", "latex_source", "auto"]:
  63                     raise exceptions.QiskitUserConfigError(
  64                         "%s is not a valid circuit drawer backend. Must be "
  65                         "either 'text', 'mpl', 'latex', 'latex_source', or "
  66                         "'auto'." % circuit_drawer
  67                     )
  68                 self.settings["circuit_drawer"] = circuit_drawer
  69 
  70             # Parse state_drawer
  71             state_drawer = self.config_parser.get("default", "state_drawer", fallback=None)
  72             if state_drawer:
  73                 valid_state_drawers = [
  74                     "repr",
  75                     "text",
  76                     "latex",
  77                     "latex_source",
  78                     "qsphere",
  79                     "hinton",
  80                     "bloch",
  81                 ]
  82                 if state_drawer not in valid_state_drawers:
  83                     valid_choices_string = "', '".join(c for c in valid_state_drawers)
  84                     raise exceptions.QiskitUserConfigError(
  85                         f"'{state_drawer}' is not a valid state drawer backend. "
  86                         f"Choose from: '{valid_choices_string}'"
  87                     )
  88                 self.settings["state_drawer"] = state_drawer
  89 
  90             # Parse circuit_mpl_style
  91             circuit_mpl_style = self.config_parser.get(
  92                 "default", "circuit_mpl_style", fallback=None
  93             )
  94             if circuit_mpl_style:
  95                 if not isinstance(circuit_mpl_style, str):
  96                     warn(
  97                         "%s is not a valid mpl circuit style. Must be "
  98                         "a text string. Will not load style." % circuit_mpl_style,
  99                         UserWarning,
  100                         2,
  101                     )
  102                 self.settings["circuit_mpl_style"] = circuit_mpl_style
  103 
  104             # Parse circuit_mpl_style_path
  105             circuit_mpl_style_path = self.config_parser.get(
  106                 "default", "circuit_mpl_style_path", fallback=None
  107             )
  108             if circuit_mpl_style_path:
  109                 cpath_list = circuit_mpl_style_path.split(":")
  110                 for path in cpath_list:
  111                     if not os.path.exists(os.path.expanduser(path)):
  112                         warn(
  113                             "%s is not a valid circuit mpl style path."
  114                             " Correct the path in ~/.qiskit/settings.conf." % path,
  115                             UserWarning,
  116                             2,
  117                         )
  118                 self.settings["circuit_mpl_style_path"] = cpath_list
  119 
  120             # Parse transpile_optimization_level
  121             transpile_optimization_level = self.config_parser.getint(
  122                 "default", "transpile_optimization_level", fallback=-1
  123             )
  124             if transpile_optimization_level != -1:
  125                 if transpile_optimization_level < 0 or transpile_optimization_level > 3:
  126                     raise exceptions.QiskitUserConfigError(
  127                         "%s is not a valid optimization level. Must be " "0, 1, 2, or 3."
  128                     )
  129                 self.settings["transpile_optimization_level"] = transpile_optimization_level
  130 
  131             # Parse parallel
  132             parallel_enabled = self.config_parser.getboolean("default", "parallel", fallback=None)
  133             if parallel_enabled is not None:
  134                 self.settings["parallel_enabled"] = parallel_enabled
  135 
  136             # Parse num_processes
  137             num_processes = self.config_parser.getint("default", "num_processes", fallback=-1)
  138             if num_processes != -1:
  139                 if num_processes <= 0:
  140                     raise exceptions.QiskitUserConfigError(
  141                         "%s is not a valid number of processes. Must be " "greater than 0"
  142                     )
  143                 self.settings["num_processes"] = num_processes
  144 
  145 
  146 def get_config():
  147     """Read the config file from the default location or env var
  148 
  149     It will read a config file at either the default location
  150     ~/.qiskit/settings.conf or if set the value of the QISKIT_SETTINGS env var.
  151 
  152     It will return the parsed settings dict from the parsed config file.
  153     Returns:
  154         dict: The settings dict from the parsed config file.
  155     """
  156     filename = os.getenv("QISKIT_SETTINGS", DEFAULT_FILENAME)
  157     if not os.path.isfile(filename):
  158         return {}
  159     user_config = UserConfig(filename)
  160     user_config.read_config_file()
  161     return user_config.settings
  162
  ```
  --- 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/qiskit/user_config.py b/qiskit/user_config.py
  --- a/qiskit/user_config.py
  +++ b/qiskit/user_config.py
  @@ -143,6 +143,70 @@
                   self.settings["num_processes"] = num_processes
   
   
  +def set_config(key, value, section=None, file_path=None):
  +    """Adds or modifies a user configuration
  +
  +    It will add configuration to the currently configured location
  +    or the value of file argument.
  +
  +    Only valid user config can be set in 'default' section. Custom
  +    user config can be added in any other sections.
  +
  +    Changes to the existing config file will not be reflected in
  +    the current session since the config file is parsed at import time.
  +
  +    Args:
  +        key (str): name of the config
  +        value (obj): value of the config
  +        section (str, optional): if not specified, adds it to the
  +            `default` section of the config file.
  +        file_path (str, optional): the file to which config is added.
  +            If not specified, adds it to the default config file or
  +            if set, the value of `QISKIT_SETTINGS` env variable.
  +
  +    Raises:
  +        QiskitUserConfigError: if the config is invalid
  +    """
  +    filename = file_path or os.getenv("QISKIT_SETTINGS", DEFAULT_FILENAME)
  +    section = "default" if section is None else section
  +
  +    if not isinstance(key, str):
  +        raise exceptions.QiskitUserConfigError("Key must be string type")
  +
  +    valid_config = {
  +        "circuit_drawer",
  +        "circuit_mpl_style",
  +        "circuit_mpl_style_path",
  +        "transpile_optimization_level",
  +        "parallel",
  +        "num_processes",
  +    }
  +
  +    if section in [None, "default"]:
  +        if key not in valid_config:
  +            raise exceptions.QiskitUserConfigError("{} is not a valid user config.".format(key))
  +
  +    config = configparser.ConfigParser()
  +    config.read(filename)
  +
  +    if section not in config.sections():
  +        config.add_section(section)
  +
  +    config.set(section, key, str(value))
  +
  +    try:
  +        with open(filename, "w") as cfgfile:
  +            config.write(cfgfile)
  +    except OSError as ex:
  +        raise exceptions.QiskitUserConfigError(
  +            "Unable to load the config file {}. Error: '{}'".format(filename, str(ex))
  +        )
  +
  +    # validates config
  +    user_config = UserConfig(filename)
  +    user_config.read_config_file()
  +
  +
   def get_config():
       """Read the config file from the default location or env var
  
verification_info: {"golden_diff": "diff --git a/qiskit/user_config.py b/qiskit/user_config.py\n--- a/qiskit/user_config.py\n+++ b/qiskit/user_config.py\n@@ -143,6 +143,70 @@\n                 self.settings[\"num_processes\"] = num_processes\n \n \n+def set_config(key, value, section=None, file_path=None):\n+    \"\"\"Adds or modifies a user configuration\n+\n+    It will add configuration to the currently configured location\n+    or the value of file argument.\n+\n+    Only valid user config can be set in 'default' section. Custom\n+    user config can be added in any other sections.\n+\n+    Changes to the existing config file will not be reflected in\n+    the current session since the config file is parsed at import time.\n+\n+    Args:\n+        key (str): name of the config\n+        value (obj): value of the config\n+        section (str, optional): if not specified, adds it to the\n+            `default` section of the config file.\n+        file_path (str, optional): the file to which config is added.\n+            If not specified, adds it to the default config file or\n+            if set, the value of `QISKIT_SETTINGS` env variable.\n+\n+    Raises:\n+        QiskitUserConfigError: if the config is invalid\n+    \"\"\"\n+    filename = file_path or os.getenv(\"QISKIT_SETTINGS\", DEFAULT_FILENAME)\n+    section = \"default\" if section is None else section\n+\n+    if not isinstance(key, str):\n+        raise exceptions.QiskitUserConfigError(\"Key must be string type\")\n+\n+    valid_config = {\n+        \"circuit_drawer\",\n+        \"circuit_mpl_style\",\n+        \"circuit_mpl_style_path\",\n+        \"transpile_optimization_level\",\n+        \"parallel\",\n+        \"num_processes\",\n+    }\n+\n+    if section in [None, \"default\"]:\n+        if key not in valid_config:\n+            raise exceptions.QiskitUserConfigError(\"{} is not a valid user config.\".format(key))\n+\n+    config = configparser.ConfigParser()\n+    config.read(filename)\n+\n+    if section not in config.sections():\n+        config.add_section(section)\n+\n+    config.set(section, key, str(value))\n+\n+    try:\n+        with open(filename, \"w\") as cfgfile:\n+            config.write(cfgfile)\n+    except OSError as ex:\n+        raise exceptions.QiskitUserConfigError(\n+            \"Unable to load the config file {}. Error: '{}'\".format(filename, str(ex))\n+        )\n+\n+    # validates config\n+    user_config = UserConfig(filename)\n+    user_config.read_config_file()\n+\n+\n def get_config():\n     \"\"\"Read the config file from the default location or env var\n", "issue": "Edit user config file programatically\nIt would be great to be able to modify the user config file from Qiskit. Something like `user_config['default']['option'] = True`.\n", "before_files": [{"content": "# This code is part of Qiskit.\n#\n# (C) Copyright IBM 2017, 2019.\n#\n# This code is licensed under the Apache License, Version 2.0. You may\n# obtain a copy of this license in the LICENSE.txt file in the root directory\n# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.\n#\n# Any modifications or derivative works of this code must retain this\n# copyright notice, and modified files need to carry a notice indicating\n# that they have been altered from the originals.\n\n\"\"\"Utils for reading a user preference config files.\"\"\"\n\nimport configparser\nimport os\nfrom warnings import warn\n\nfrom qiskit import exceptions\n\nDEFAULT_FILENAME = os.path.join(os.path.expanduser(\"~\"), \".qiskit\", \"settings.conf\")\n\n\nclass UserConfig:\n    \"\"\"Class representing a user config file\n\n    The config file format should look like:\n\n    [default]\n    circuit_drawer = mpl\n    circuit_mpl_style = default\n    circuit_mpl_style_path = ~/.qiskit:<default location>\n    transpile_optimization_level = 1\n    parallel = False\n    num_processes = 4\n\n    \"\"\"\n\n    def __init__(self, filename=None):\n        \"\"\"Create a UserConfig\n\n        Args:\n            filename (str): The path to the user config file. If one isn't\n                specified, ~/.qiskit/settings.conf is used.\n        \"\"\"\n        if filename is None:\n            self.filename = DEFAULT_FILENAME\n        else:\n            self.filename = filename\n        self.settings = {}\n        self.config_parser = configparser.ConfigParser()\n\n    def read_config_file(self):\n        \"\"\"Read config file and parse the contents into the settings attr.\"\"\"\n        if not os.path.isfile(self.filename):\n            return\n        self.config_parser.read(self.filename)\n        if \"default\" in self.config_parser.sections():\n            # Parse circuit_drawer\n            circuit_drawer = self.config_parser.get(\"default\", \"circuit_drawer\", fallback=None)\n            if circuit_drawer:\n                if circuit_drawer not in [\"text\", \"mpl\", \"latex\", \"latex_source\", \"auto\"]:\n                    raise exceptions.QiskitUserConfigError(\n                        \"%s is not a valid circuit drawer backend. Must be \"\n                        \"either 'text', 'mpl', 'latex', 'latex_source', or \"\n                        \"'auto'.\" % circuit_drawer\n                    )\n                self.settings[\"circuit_drawer\"] = circuit_drawer\n\n            # Parse state_drawer\n            state_drawer = self.config_parser.get(\"default\", \"state_drawer\", fallback=None)\n            if state_drawer:\n                valid_state_drawers = [\n                    \"repr\",\n                    \"text\",\n                    \"latex\",\n                    \"latex_source\",\n                    \"qsphere\",\n                    \"hinton\",\n                    \"bloch\",\n                ]\n                if state_drawer not in valid_state_drawers:\n                    valid_choices_string = \"', '\".join(c for c in valid_state_drawers)\n                    raise exceptions.QiskitUserConfigError(\n                        f\"'{state_drawer}' is not a valid state drawer backend. \"\n                        f\"Choose from: '{valid_choices_string}'\"\n                    )\n                self.settings[\"state_drawer\"] = state_drawer\n\n            # Parse circuit_mpl_style\n            circuit_mpl_style = self.config_parser.get(\n                \"default\", \"circuit_mpl_style\", fallback=None\n            )\n            if circuit_mpl_style:\n                if not isinstance(circuit_mpl_style, str):\n                    warn(\n                        \"%s is not a valid mpl circuit style. Must be \"\n                        \"a text string. Will not load style.\" % circuit_mpl_style,\n                        UserWarning,\n                        2,\n                    )\n                self.settings[\"circuit_mpl_style\"] = circuit_mpl_style\n\n            # Parse circuit_mpl_style_path\n            circuit_mpl_style_path = self.config_parser.get(\n                \"default\", \"circuit_mpl_style_path\", fallback=None\n            )\n            if circuit_mpl_style_path:\n                cpath_list = circuit_mpl_style_path.split(\":\")\n                for path in cpath_list:\n                    if not os.path.exists(os.path.expanduser(path)):\n                        warn(\n                            \"%s is not a valid circuit mpl style path.\"\n                            \" Correct the path in ~/.qiskit/settings.conf.\" % path,\n                            UserWarning,\n                            2,\n                        )\n                self.settings[\"circuit_mpl_style_path\"] = cpath_list\n\n            # Parse transpile_optimization_level\n            transpile_optimization_level = self.config_parser.getint(\n                \"default\", \"transpile_optimization_level\", fallback=-1\n            )\n            if transpile_optimization_level != -1:\n                if transpile_optimization_level < 0 or transpile_optimization_level > 3:\n                    raise exceptions.QiskitUserConfigError(\n                        \"%s is not a valid optimization level. Must be \" \"0, 1, 2, or 3.\"\n                    )\n                self.settings[\"transpile_optimization_level\"] = transpile_optimization_level\n\n            # Parse parallel\n            parallel_enabled = self.config_parser.getboolean(\"default\", \"parallel\", fallback=None)\n            if parallel_enabled is not None:\n                self.settings[\"parallel_enabled\"] = parallel_enabled\n\n            # Parse num_processes\n            num_processes = self.config_parser.getint(\"default\", \"num_processes\", fallback=-1)\n            if num_processes != -1:\n                if num_processes <= 0:\n                    raise exceptions.QiskitUserConfigError(\n                        \"%s is not a valid number of processes. Must be \" \"greater than 0\"\n                    )\n                self.settings[\"num_processes\"] = num_processes\n\n\ndef get_config():\n    \"\"\"Read the config file from the default location or env var\n\n    It will read a config file at either the default location\n    ~/.qiskit/settings.conf or if set the value of the QISKIT_SETTINGS env var.\n\n    It will return the parsed settings dict from the parsed config file.\n    Returns:\n        dict: The settings dict from the parsed config file.\n    \"\"\"\n    filename = os.getenv(\"QISKIT_SETTINGS\", DEFAULT_FILENAME)\n    if not os.path.isfile(filename):\n        return {}\n    user_config = UserConfig(filename)\n    user_config.read_config_file()\n    return user_config.settings\n", "path": "qiskit/user_config.py"}], "after_files": [{"content": "# This code is part of Qiskit.\n#\n# (C) Copyright IBM 2017, 2019.\n#\n# This code is licensed under the Apache License, Version 2.0. You may\n# obtain a copy of this license in the LICENSE.txt file in the root directory\n# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.\n#\n# Any modifications or derivative works of this code must retain this\n# copyright notice, and modified files need to carry a notice indicating\n# that they have been altered from the originals.\n\n\"\"\"Utils for reading a user preference config files.\"\"\"\n\nimport configparser\nimport os\nfrom warnings import warn\n\nfrom qiskit import exceptions\n\nDEFAULT_FILENAME = os.path.join(os.path.expanduser(\"~\"), \".qiskit\", \"settings.conf\")\n\n\nclass UserConfig:\n    \"\"\"Class representing a user config file\n\n    The config file format should look like:\n\n    [default]\n    circuit_drawer = mpl\n    circuit_mpl_style = default\n    circuit_mpl_style_path = ~/.qiskit:<default location>\n    transpile_optimization_level = 1\n    parallel = False\n    num_processes = 4\n\n    \"\"\"\n\n    def __init__(self, filename=None):\n        \"\"\"Create a UserConfig\n\n        Args:\n            filename (str): The path to the user config file. If one isn't\n                specified, ~/.qiskit/settings.conf is used.\n        \"\"\"\n        if filename is None:\n            self.filename = DEFAULT_FILENAME\n        else:\n            self.filename = filename\n        self.settings = {}\n        self.config_parser = configparser.ConfigParser()\n\n    def read_config_file(self):\n        \"\"\"Read config file and parse the contents into the settings attr.\"\"\"\n        if not os.path.isfile(self.filename):\n            return\n        self.config_parser.read(self.filename)\n        if \"default\" in self.config_parser.sections():\n            # Parse circuit_drawer\n            circuit_drawer = self.config_parser.get(\"default\", \"circuit_drawer\", fallback=None)\n            if circuit_drawer:\n                if circuit_drawer not in [\"text\", \"mpl\", \"latex\", \"latex_source\", \"auto\"]:\n                    raise exceptions.QiskitUserConfigError(\n                        \"%s is not a valid circuit drawer backend. Must be \"\n                        \"either 'text', 'mpl', 'latex', 'latex_source', or \"\n                        \"'auto'.\" % circuit_drawer\n                    )\n                self.settings[\"circuit_drawer\"] = circuit_drawer\n\n            # Parse state_drawer\n            state_drawer = self.config_parser.get(\"default\", \"state_drawer\", fallback=None)\n            if state_drawer:\n                valid_state_drawers = [\n                    \"repr\",\n                    \"text\",\n                    \"latex\",\n                    \"latex_source\",\n                    \"qsphere\",\n                    \"hinton\",\n                    \"bloch\",\n                ]\n                if state_drawer not in valid_state_drawers:\n                    valid_choices_string = \"', '\".join(c for c in valid_state_drawers)\n                    raise exceptions.QiskitUserConfigError(\n                        f\"'{state_drawer}' is not a valid state drawer backend. \"\n                        f\"Choose from: '{valid_choices_string}'\"\n                    )\n                self.settings[\"state_drawer\"] = state_drawer\n\n            # Parse circuit_mpl_style\n            circuit_mpl_style = self.config_parser.get(\n                \"default\", \"circuit_mpl_style\", fallback=None\n            )\n            if circuit_mpl_style:\n                if not isinstance(circuit_mpl_style, str):\n                    warn(\n                        \"%s is not a valid mpl circuit style. Must be \"\n                        \"a text string. Will not load style.\" % circuit_mpl_style,\n                        UserWarning,\n                        2,\n                    )\n                self.settings[\"circuit_mpl_style\"] = circuit_mpl_style\n\n            # Parse circuit_mpl_style_path\n            circuit_mpl_style_path = self.config_parser.get(\n                \"default\", \"circuit_mpl_style_path\", fallback=None\n            )\n            if circuit_mpl_style_path:\n                cpath_list = circuit_mpl_style_path.split(\":\")\n                for path in cpath_list:\n                    if not os.path.exists(os.path.expanduser(path)):\n                        warn(\n                            \"%s is not a valid circuit mpl style path.\"\n                            \" Correct the path in ~/.qiskit/settings.conf.\" % path,\n                            UserWarning,\n                            2,\n                        )\n                self.settings[\"circuit_mpl_style_path\"] = cpath_list\n\n            # Parse transpile_optimization_level\n            transpile_optimization_level = self.config_parser.getint(\n                \"default\", \"transpile_optimization_level\", fallback=-1\n            )\n            if transpile_optimization_level != -1:\n                if transpile_optimization_level < 0 or transpile_optimization_level > 3:\n                    raise exceptions.QiskitUserConfigError(\n                        \"%s is not a valid optimization level. Must be \" \"0, 1, 2, or 3.\"\n                    )\n                self.settings[\"transpile_optimization_level\"] = transpile_optimization_level\n\n            # Parse parallel\n            parallel_enabled = self.config_parser.getboolean(\"default\", \"parallel\", fallback=None)\n            if parallel_enabled is not None:\n                self.settings[\"parallel_enabled\"] = parallel_enabled\n\n            # Parse num_processes\n            num_processes = self.config_parser.getint(\"default\", \"num_processes\", fallback=-1)\n            if num_processes != -1:\n                if num_processes <= 0:\n                    raise exceptions.QiskitUserConfigError(\n                        \"%s is not a valid number of processes. Must be \" \"greater than 0\"\n                    )\n                self.settings[\"num_processes\"] = num_processes\n\n\ndef set_config(key, value, section=None, file_path=None):\n    \"\"\"Adds or modifies a user configuration\n\n    It will add configuration to the currently configured location\n    or the value of file argument.\n\n    Only valid user config can be set in 'default' section. Custom\n    user config can be added in any other sections.\n\n    Changes to the existing config file will not be reflected in\n    the current session since the config file is parsed at import time.\n\n    Args:\n        key (str): name of the config\n        value (obj): value of the config\n        section (str, optional): if not specified, adds it to the\n            `default` section of the config file.\n        file_path (str, optional): the file to which config is added.\n            If not specified, adds it to the default config file or\n            if set, the value of `QISKIT_SETTINGS` env variable.\n\n    Raises:\n        QiskitUserConfigError: if the config is invalid\n    \"\"\"\n    filename = file_path or os.getenv(\"QISKIT_SETTINGS\", DEFAULT_FILENAME)\n    section = \"default\" if section is None else section\n\n    if not isinstance(key, str):\n        raise exceptions.QiskitUserConfigError(\"Key must be string type\")\n\n    valid_config = {\n        \"circuit_drawer\",\n        \"circuit_mpl_style\",\n        \"circuit_mpl_style_path\",\n        \"transpile_optimization_level\",\n        \"parallel\",\n        \"num_processes\",\n    }\n\n    if section in [None, \"default\"]:\n        if key not in valid_config:\n            raise exceptions.QiskitUserConfigError(\"{} is not a valid user config.\".format(key))\n\n    config = configparser.ConfigParser()\n    config.read(filename)\n\n    if section not in config.sections():\n        config.add_section(section)\n\n    config.set(section, key, str(value))\n\n    try:\n        with open(filename, \"w\") as cfgfile:\n            config.write(cfgfile)\n    except OSError as ex:\n        raise exceptions.QiskitUserConfigError(\n            \"Unable to load the config file {}. Error: '{}'\".format(filename, str(ex))\n        )\n\n    # validates config\n    user_config = UserConfig(filename)\n    user_config.read_config_file()\n\n\ndef get_config():\n    \"\"\"Read the config file from the default location or env var\n\n    It will read a config file at either the default location\n    ~/.qiskit/settings.conf or if set the value of the QISKIT_SETTINGS env var.\n\n    It will return the parsed settings dict from the parsed config file.\n    Returns:\n        dict: The settings dict from the parsed config file.\n    \"\"\"\n    filename = os.getenv(\"QISKIT_SETTINGS\", DEFAULT_FILENAME)\n    if not os.path.isfile(filename):\n        return {}\n    user_config = UserConfig(filename)\n    user_config.read_config_file()\n    return user_config.settings\n", "path": "qiskit/user_config.py"}]}