We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Using exclude paths for all instances of a Flask app
This is less a feature request than a question about how to use `OPENTELEMETRY_PYTHON_FLASK_EXCLUDED_HOSTS` to exclude routes from being traced for all instances of a flask application (i.e. regardless of host being deployed to). I initially thought something like below would work -

```python
from os import environ
environ["OPENTELEMETRY_PYTHON_FLASK_EXCLUDED_HOSTS"] = "/route1,/route2"
```

But it appears that this would be executed after the `Configuration` singleton gets initialized, and won't get picked up. Calling `configuration.Configuration._reset()` after setting `environ` seems like a hack to make this work but the docs state it's not for production code and it feels hacky as well.

Of course setting the environment on the deployed to host would solve this. The issue is that in some instances we may have a flask application that has e.g. a ping route that should never be traced, and we may not have control over the environment variables of the host being deployed to (so the app has to somehow set the exclude paths). So I suppose my question is, can the application programmatically set it's own exclude paths? Thanks in advance for the help.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `opentelemetry-api/src/opentelemetry/configuration/__init__.py`
Content:
```
1 # Copyright The OpenTelemetry Authors
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 """
16 Simple configuration manager
17 
18 This is a configuration manager for OpenTelemetry. It reads configuration
19 values from environment variables prefixed with ``OPENTELEMETRY_PYTHON_`` whose
20 characters are only alphanumeric characters and unserscores, except for the
21 first character after ``OPENTELEMETRY_PYTHON_`` which must not be a number.
22 
23 For example, these environment variables will be read:
24 
25 1. ``OPENTELEMETRY_PYTHON_SOMETHING``
26 2. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_``
27 3. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND__ELSE``
28 4. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND_else``
29 5. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND_else2``
30 
31 These won't:
32 
33 1. ``OPENTELEMETRY_PYTH_SOMETHING``
34 2. ``OPENTELEMETRY_PYTHON_2_SOMETHING_AND__ELSE``
35 3. ``OPENTELEMETRY_PYTHON_SOMETHING_%_ELSE``
36 
37 The values stored in the environment variables can be found in an instance of
38 ``opentelemetry.configuration.Configuration``. This class can be instantiated
39 freely because instantiating it returns always the same object.
40 
41 For example, if the environment variable
42 ``OPENTELEMETRY_PYTHON_METER_PROVIDER`` value is ``my_meter_provider``, then
43 ``Configuration().meter_provider == "my_meter_provider"`` would be ``True``.
44 
45 Non defined attributes will always return ``None``. This is intended to make it
46 easier to use the ``Configuration`` object in actual code, because it won't be
47 necessary to check for the attribute to be defined first.
48 
49 Environment variables used by OpenTelemetry
50 -------------------------------------------
51 
52 1. OPENTELEMETRY_PYTHON_METER_PROVIDER
53 2. OPENTELEMETRY_PYTHON_TRACER_PROVIDER
54 
55 The value of these environment variables should be the name of the entry point
56 that points to the class that implements either provider. This OpenTelemetry
57 API package provides one entry point for each, which can be found in the
58 setup.py file::
59 
60     entry_points={
61         ...
62         "opentelemetry_meter_provider": [
63             "default_meter_provider = "
64             "opentelemetry.metrics:DefaultMeterProvider"
65         ],
66         "opentelemetry_tracer_provider": [
67             "default_tracer_provider = "
68             "opentelemetry.trace:DefaultTracerProvider"
69         ],
70     }
71 
72 To use the meter provider above, then the
73 ``OPENTELEMETRY_PYTHON_METER_PROVIDER`` should be set to
74 ``"default_meter_provider"`` (this is not actually necessary since the
75 OpenTelemetry API provided providers are the default ones used if no
76 configuration is found in the environment variables).
77 
78 Configuration values that are exactly ``"True"`` or ``"False"`` will be
79 converted to its boolean values of ``True`` and ``False`` respectively.
80 
81 Configuration values that can be casted to integers or floats will be casted.
82 
83 This object can be used by any OpenTelemetry component, native or external.
84 For that reason, the ``Configuration`` object is designed to be immutable.
85 If a component would change the value of one of the ``Configuration`` object
86 attributes then another component that relied on that value may break, leading
87 to bugs that are very hard to debug. To avoid this situation, the preferred
88 approach for components that need a different value than the one provided by
89 the ``Configuration`` object is to implement a mechanism that allows the user
90 to override this value instead of changing it.
91 """
92 
93 from os import environ
94 from re import fullmatch
95 from typing import ClassVar, Dict, Optional, TypeVar, Union
96 
97 ConfigValue = Union[str, bool, int, float]
98 _T = TypeVar("_T", ConfigValue, Optional[ConfigValue])
99 
100 
101 class Configuration:
102     _instance = None  # type: ClassVar[Optional[Configuration]]
103     _config_map = {}  # type: ClassVar[Dict[str, ConfigValue]]
104 
105     def __new__(cls) -> "Configuration":
106         if cls._instance is not None:
107             instance = cls._instance
108         else:
109 
110             instance = super().__new__(cls)
111             for key, value_str in environ.items():
112 
113                 match = fullmatch(
114                     r"OPENTELEMETRY_PYTHON_([A-Za-z_][\w_]*)", key
115                 )
116 
117                 if match is not None:
118 
119                     key = match.group(1)
120                     value = value_str  # type: ConfigValue
121 
122                     if value_str == "True":
123                         value = True
124                     elif value_str == "False":
125                         value = False
126                     else:
127                         try:
128                             value = int(value_str)
129                         except ValueError:
130                             pass
131                         try:
132                             value = float(value_str)
133                         except ValueError:
134                             pass
135 
136                     instance._config_map[key] = value
137 
138             cls._instance = instance
139 
140         return instance
141 
142     def __getattr__(self, name: str) -> Optional[ConfigValue]:
143         return self._config_map.get(name)
144 
145     def __setattr__(self, key: str, val: ConfigValue) -> None:
146         if key == "_config_map":
147             super().__setattr__(key, val)
148         else:
149             raise AttributeError(key)
150 
151     def get(self, name: str, default: _T) -> _T:
152         """Use this typed method for dynamic access instead of `getattr`
153 
154         :rtype: str or bool or int or float or None
155         """
156         val = self._config_map.get(name, default)
157         return val
158 
159     @classmethod
160     def _reset(cls) -> None:
161         """
162         This method "resets" the global configuration attributes
163 
164         It is not intended to be used by production code but by testing code
165         only.
166         """
167 
168         if cls._instance:
169             cls._instance._config_map.clear()  # pylint: disable=protected-access
170             cls._instance = None
171
```
--- 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()

```

diff --git a/opentelemetry-api/src/opentelemetry/configuration/__init__.py b/opentelemetry-api/src/opentelemetry/configuration/__init__.py
--- a/opentelemetry-api/src/opentelemetry/configuration/__init__.py
+++ b/opentelemetry-api/src/opentelemetry/configuration/__init__.py
@@ -142,19 +142,18 @@
     def __getattr__(self, name: str) -> Optional[ConfigValue]:
         return self._config_map.get(name)
 
-    def __setattr__(self, key: str, val: ConfigValue) -> None:
-        if key == "_config_map":
-            super().__setattr__(key, val)
+    def __setattr__(self, name: str, value: ConfigValue) -> None:
+        if name not in self._config_map.keys():
+            self._config_map[name] = value
         else:
-            raise AttributeError(key)
+            raise AttributeError(name)
 
     def get(self, name: str, default: _T) -> _T:
         """Use this typed method for dynamic access instead of `getattr`
 
         :rtype: str or bool or int or float or None
         """
-        val = self._config_map.get(name, default)
-        return val
+        return self._config_map.get(name, default)
 
     @classmethod
     def _reset(cls) -> None:

{"golden_diff": "diff --git a/opentelemetry-api/src/opentelemetry/configuration/__init__.py b/opentelemetry-api/src/opentelemetry/configuration/__init__.py\n--- a/opentelemetry-api/src/opentelemetry/configuration/__init__.py\n+++ b/opentelemetry-api/src/opentelemetry/configuration/__init__.py\n@@ -142,19 +142,18 @@\n     def __getattr__(self, name: str) -> Optional[ConfigValue]:\n         return self._config_map.get(name)\n \n-    def __setattr__(self, key: str, val: ConfigValue) -> None:\n-        if key == \"_config_map\":\n-            super().__setattr__(key, val)\n+    def __setattr__(self, name: str, value: ConfigValue) -> None:\n+        if name not in self._config_map.keys():\n+            self._config_map[name] = value\n         else:\n-            raise AttributeError(key)\n+            raise AttributeError(name)\n \n     def get(self, name: str, default: _T) -> _T:\n         \"\"\"Use this typed method for dynamic access instead of `getattr`\n \n         :rtype: str or bool or int or float or None\n         \"\"\"\n-        val = self._config_map.get(name, default)\n-        return val\n+        return self._config_map.get(name, default)\n \n     @classmethod\n     def _reset(cls) -> None:\n", "issue": "Using exclude paths for all instances of a Flask app\nThis is less a feature request than a question about how to use `OPENTELEMETRY_PYTHON_FLASK_EXCLUDED_HOSTS` to exclude routes from being traced for all instances of a flask application (i.e. regardless of host being deployed to). I initially thought something like below would work -\r\n\r\n```python\r\nfrom os import environ\r\nenviron[\"OPENTELEMETRY_PYTHON_FLASK_EXCLUDED_HOSTS\"] = \"/route1,/route2\"\r\n```\r\n\r\nBut it appears that this would be executed after the `Configuration` singleton gets initialized, and won't get picked up. Calling `configuration.Configuration._reset()` after setting `environ` seems like a hack to make this work but the docs state it's not for production code and it feels hacky as well.\r\n\r\nOf course setting the environment on the deployed to host would solve this. The issue is that in some instances we may have a flask application that has e.g. a ping route that should never be traced, and we may not have control over the environment variables of the host being deployed to (so the app has to somehow set the exclude paths). So I suppose my question is, can the application programmatically set it's own exclude paths? Thanks in advance for the help.\r\n\n", "before_files": [{"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"\nSimple configuration manager\n\nThis is a configuration manager for OpenTelemetry. It reads configuration\nvalues from environment variables prefixed with ``OPENTELEMETRY_PYTHON_`` whose\ncharacters are only alphanumeric characters and unserscores, except for the\nfirst character after ``OPENTELEMETRY_PYTHON_`` which must not be a number.\n\nFor example, these environment variables will be read:\n\n1. ``OPENTELEMETRY_PYTHON_SOMETHING``\n2. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_``\n3. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND__ELSE``\n4. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND_else``\n5. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND_else2``\n\nThese won't:\n\n1. ``OPENTELEMETRY_PYTH_SOMETHING``\n2. ``OPENTELEMETRY_PYTHON_2_SOMETHING_AND__ELSE``\n3. ``OPENTELEMETRY_PYTHON_SOMETHING_%_ELSE``\n\nThe values stored in the environment variables can be found in an instance of\n``opentelemetry.configuration.Configuration``. This class can be instantiated\nfreely because instantiating it returns always the same object.\n\nFor example, if the environment variable\n``OPENTELEMETRY_PYTHON_METER_PROVIDER`` value is ``my_meter_provider``, then\n``Configuration().meter_provider == \"my_meter_provider\"`` would be ``True``.\n\nNon defined attributes will always return ``None``. This is intended to make it\neasier to use the ``Configuration`` object in actual code, because it won't be\nnecessary to check for the attribute to be defined first.\n\nEnvironment variables used by OpenTelemetry\n-------------------------------------------\n\n1. OPENTELEMETRY_PYTHON_METER_PROVIDER\n2. OPENTELEMETRY_PYTHON_TRACER_PROVIDER\n\nThe value of these environment variables should be the name of the entry point\nthat points to the class that implements either provider. This OpenTelemetry\nAPI package provides one entry point for each, which can be found in the\nsetup.py file::\n\n    entry_points={\n        ...\n        \"opentelemetry_meter_provider\": [\n            \"default_meter_provider = \"\n            \"opentelemetry.metrics:DefaultMeterProvider\"\n        ],\n        \"opentelemetry_tracer_provider\": [\n            \"default_tracer_provider = \"\n            \"opentelemetry.trace:DefaultTracerProvider\"\n        ],\n    }\n\nTo use the meter provider above, then the\n``OPENTELEMETRY_PYTHON_METER_PROVIDER`` should be set to\n``\"default_meter_provider\"`` (this is not actually necessary since the\nOpenTelemetry API provided providers are the default ones used if no\nconfiguration is found in the environment variables).\n\nConfiguration values that are exactly ``\"True\"`` or ``\"False\"`` will be\nconverted to its boolean values of ``True`` and ``False`` respectively.\n\nConfiguration values that can be casted to integers or floats will be casted.\n\nThis object can be used by any OpenTelemetry component, native or external.\nFor that reason, the ``Configuration`` object is designed to be immutable.\nIf a component would change the value of one of the ``Configuration`` object\nattributes then another component that relied on that value may break, leading\nto bugs that are very hard to debug. To avoid this situation, the preferred\napproach for components that need a different value than the one provided by\nthe ``Configuration`` object is to implement a mechanism that allows the user\nto override this value instead of changing it.\n\"\"\"\n\nfrom os import environ\nfrom re import fullmatch\nfrom typing import ClassVar, Dict, Optional, TypeVar, Union\n\nConfigValue = Union[str, bool, int, float]\n_T = TypeVar(\"_T\", ConfigValue, Optional[ConfigValue])\n\n\nclass Configuration:\n    _instance = None  # type: ClassVar[Optional[Configuration]]\n    _config_map = {}  # type: ClassVar[Dict[str, ConfigValue]]\n\n    def __new__(cls) -> \"Configuration\":\n        if cls._instance is not None:\n            instance = cls._instance\n        else:\n\n            instance = super().__new__(cls)\n            for key, value_str in environ.items():\n\n                match = fullmatch(\n                    r\"OPENTELEMETRY_PYTHON_([A-Za-z_][\\w_]*)\", key\n                )\n\n                if match is not None:\n\n                    key = match.group(1)\n                    value = value_str  # type: ConfigValue\n\n                    if value_str == \"True\":\n                        value = True\n                    elif value_str == \"False\":\n                        value = False\n                    else:\n                        try:\n                            value = int(value_str)\n                        except ValueError:\n                            pass\n                        try:\n                            value = float(value_str)\n                        except ValueError:\n                            pass\n\n                    instance._config_map[key] = value\n\n            cls._instance = instance\n\n        return instance\n\n    def __getattr__(self, name: str) -> Optional[ConfigValue]:\n        return self._config_map.get(name)\n\n    def __setattr__(self, key: str, val: ConfigValue) -> None:\n        if key == \"_config_map\":\n            super().__setattr__(key, val)\n        else:\n            raise AttributeError(key)\n\n    def get(self, name: str, default: _T) -> _T:\n        \"\"\"Use this typed method for dynamic access instead of `getattr`\n\n        :rtype: str or bool or int or float or None\n        \"\"\"\n        val = self._config_map.get(name, default)\n        return val\n\n    @classmethod\n    def _reset(cls) -> None:\n        \"\"\"\n        This method \"resets\" the global configuration attributes\n\n        It is not intended to be used by production code but by testing code\n        only.\n        \"\"\"\n\n        if cls._instance:\n            cls._instance._config_map.clear()  # pylint: disable=protected-access\n            cls._instance = None\n", "path": "opentelemetry-api/src/opentelemetry/configuration/__init__.py"}], "after_files": [{"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"\nSimple configuration manager\n\nThis is a configuration manager for OpenTelemetry. It reads configuration\nvalues from environment variables prefixed with ``OPENTELEMETRY_PYTHON_`` whose\ncharacters are only alphanumeric characters and unserscores, except for the\nfirst character after ``OPENTELEMETRY_PYTHON_`` which must not be a number.\n\nFor example, these environment variables will be read:\n\n1. ``OPENTELEMETRY_PYTHON_SOMETHING``\n2. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_``\n3. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND__ELSE``\n4. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND_else``\n5. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND_else2``\n\nThese won't:\n\n1. ``OPENTELEMETRY_PYTH_SOMETHING``\n2. ``OPENTELEMETRY_PYTHON_2_SOMETHING_AND__ELSE``\n3. ``OPENTELEMETRY_PYTHON_SOMETHING_%_ELSE``\n\nThe values stored in the environment variables can be found in an instance of\n``opentelemetry.configuration.Configuration``. This class can be instantiated\nfreely because instantiating it returns always the same object.\n\nFor example, if the environment variable\n``OPENTELEMETRY_PYTHON_METER_PROVIDER`` value is ``my_meter_provider``, then\n``Configuration().meter_provider == \"my_meter_provider\"`` would be ``True``.\n\nNon defined attributes will always return ``None``. This is intended to make it\neasier to use the ``Configuration`` object in actual code, because it won't be\nnecessary to check for the attribute to be defined first.\n\nEnvironment variables used by OpenTelemetry\n-------------------------------------------\n\n1. OPENTELEMETRY_PYTHON_METER_PROVIDER\n2. OPENTELEMETRY_PYTHON_TRACER_PROVIDER\n\nThe value of these environment variables should be the name of the entry point\nthat points to the class that implements either provider. This OpenTelemetry\nAPI package provides one entry point for each, which can be found in the\nsetup.py file::\n\n    entry_points={\n        ...\n        \"opentelemetry_meter_provider\": [\n            \"default_meter_provider = \"\n            \"opentelemetry.metrics:DefaultMeterProvider\"\n        ],\n        \"opentelemetry_tracer_provider\": [\n            \"default_tracer_provider = \"\n            \"opentelemetry.trace:DefaultTracerProvider\"\n        ],\n    }\n\nTo use the meter provider above, then the\n``OPENTELEMETRY_PYTHON_METER_PROVIDER`` should be set to\n``\"default_meter_provider\"`` (this is not actually necessary since the\nOpenTelemetry API provided providers are the default ones used if no\nconfiguration is found in the environment variables).\n\nConfiguration values that are exactly ``\"True\"`` or ``\"False\"`` will be\nconverted to its boolean values of ``True`` and ``False`` respectively.\n\nConfiguration values that can be casted to integers or floats will be casted.\n\nThis object can be used by any OpenTelemetry component, native or external.\nFor that reason, the ``Configuration`` object is designed to be immutable.\nIf a component would change the value of one of the ``Configuration`` object\nattributes then another component that relied on that value may break, leading\nto bugs that are very hard to debug. To avoid this situation, the preferred\napproach for components that need a different value than the one provided by\nthe ``Configuration`` object is to implement a mechanism that allows the user\nto override this value instead of changing it.\n\"\"\"\n\nfrom os import environ\nfrom re import fullmatch\nfrom typing import ClassVar, Dict, Optional, TypeVar, Union\n\nConfigValue = Union[str, bool, int, float]\n_T = TypeVar(\"_T\", ConfigValue, Optional[ConfigValue])\n\n\nclass Configuration:\n    _instance = None  # type: ClassVar[Optional[Configuration]]\n    _config_map = {}  # type: ClassVar[Dict[str, ConfigValue]]\n\n    def __new__(cls) -> \"Configuration\":\n        if cls._instance is not None:\n            instance = cls._instance\n        else:\n\n            instance = super().__new__(cls)\n            for key, value_str in environ.items():\n\n                match = fullmatch(\n                    r\"OPENTELEMETRY_PYTHON_([A-Za-z_][\\w_]*)\", key\n                )\n\n                if match is not None:\n\n                    key = match.group(1)\n                    value = value_str  # type: ConfigValue\n\n                    if value_str == \"True\":\n                        value = True\n                    elif value_str == \"False\":\n                        value = False\n                    else:\n                        try:\n                            value = int(value_str)\n                        except ValueError:\n                            pass\n                        try:\n                            value = float(value_str)\n                        except ValueError:\n                            pass\n\n                    instance._config_map[key] = value\n\n            cls._instance = instance\n\n        return instance\n\n    def __getattr__(self, name: str) -> Optional[ConfigValue]:\n        return self._config_map.get(name)\n\n    def __setattr__(self, name: str, value: ConfigValue) -> None:\n        if name not in self._config_map.keys():\n            self._config_map[name] = value\n        else:\n            raise AttributeError(name)\n\n    def get(self, name: str, default: _T) -> _T:\n        \"\"\"Use this typed method for dynamic access instead of `getattr`\n\n        :rtype: str or bool or int or float or None\n        \"\"\"\n        return self._config_map.get(name, default)\n\n    @classmethod\n    def _reset(cls) -> None:\n        \"\"\"\n        This method \"resets\" the global configuration attributes\n\n        It is not intended to be used by production code but by testing code\n        only.\n        \"\"\"\n\n        if cls._instance:\n            cls._instance._config_map.clear()  # pylint: disable=protected-access\n            cls._instance = None\n", "path": "opentelemetry-api/src/opentelemetry/configuration/__init__.py"}]}