prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Add support for OTEL_PROPAGATORS
  The spec describes environment variables that should be supported to configure propagators, this feature request is to add support in the current implementation.
  
  https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/sdk-environment-variables.md
  
  --- 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/propagators/__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 API for propagation of context.
  17 
  18 Example::
  19 
  20     import flask
  21     import requests
  22     from opentelemetry import propagators
  23 
  24 
  25     PROPAGATOR = propagators.get_global_textmap()
  26 
  27 
  28     def get_header_from_flask_request(request, key):
  29         return request.headers.get_all(key)
  30 
  31     def set_header_into_requests_request(request: requests.Request,
  32                                             key: str, value: str):
  33         request.headers[key] = value
  34 
  35     def example_route():
  36         context = PROPAGATOR.extract(
  37             get_header_from_flask_request,
  38             flask.request
  39         )
  40         request_to_downstream = requests.Request(
  41             "GET", "http://httpbin.org/get"
  42         )
  43         PROPAGATOR.inject(
  44             set_header_into_requests_request,
  45             request_to_downstream,
  46             context=context
  47         )
  48         session = requests.Session()
  49         session.send(request_to_downstream.prepare())
  50 
  51 
  52 .. _Propagation API Specification:
  53     https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/api-propagators.md
  54 """
  55 
  56 import typing
  57 
  58 from opentelemetry.baggage.propagation import BaggagePropagator
  59 from opentelemetry.context.context import Context
  60 from opentelemetry.propagators import composite
  61 from opentelemetry.trace.propagation import textmap
  62 from opentelemetry.trace.propagation.tracecontext import (
  63     TraceContextTextMapPropagator,
  64 )
  65 
  66 
  67 def extract(
  68     get_from_carrier: textmap.Getter[textmap.TextMapPropagatorT],
  69     carrier: textmap.TextMapPropagatorT,
  70     context: typing.Optional[Context] = None,
  71 ) -> Context:
  72     """ Uses the configured propagator to extract a Context from the carrier.
  73 
  74     Args:
  75         get_from_carrier: a function that can retrieve zero
  76             or more values from the carrier. In the case that
  77             the value does not exist, return an empty list.
  78         carrier: and object which contains values that are
  79             used to construct a Context. This object
  80             must be paired with an appropriate get_from_carrier
  81             which understands how to extract a value from it.
  82         context: an optional Context to use. Defaults to current
  83             context if not set.
  84     """
  85     return get_global_textmap().extract(get_from_carrier, carrier, context)
  86 
  87 
  88 def inject(
  89     set_in_carrier: textmap.Setter[textmap.TextMapPropagatorT],
  90     carrier: textmap.TextMapPropagatorT,
  91     context: typing.Optional[Context] = None,
  92 ) -> None:
  93     """ Uses the configured propagator to inject a Context into the carrier.
  94 
  95     Args:
  96         set_in_carrier: A setter function that can set values
  97             on the carrier.
  98         carrier: An object that contains a representation of HTTP
  99             headers. Should be paired with set_in_carrier, which
  100             should know how to set header values on the carrier.
  101         context: an optional Context to use. Defaults to current
  102             context if not set.
  103     """
  104     get_global_textmap().inject(set_in_carrier, carrier, context)
  105 
  106 
  107 _HTTP_TEXT_FORMAT = composite.CompositeHTTPPropagator(
  108     [TraceContextTextMapPropagator(), BaggagePropagator()],
  109 )  # type: textmap.TextMapPropagator
  110 
  111 
  112 def get_global_textmap() -> textmap.TextMapPropagator:
  113     return _HTTP_TEXT_FORMAT
  114 
  115 
  116 def set_global_textmap(http_text_format: textmap.TextMapPropagator,) -> None:
  117     global _HTTP_TEXT_FORMAT  # pylint:disable=global-statement
  118     _HTTP_TEXT_FORMAT = http_text_format
  119
  ```
  --- 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/opentelemetry-api/src/opentelemetry/propagators/__init__.py b/opentelemetry-api/src/opentelemetry/propagators/__init__.py
  --- a/opentelemetry-api/src/opentelemetry/propagators/__init__.py
  +++ b/opentelemetry-api/src/opentelemetry/propagators/__init__.py
  @@ -15,6 +15,21 @@
   """
   API for propagation of context.
   
  +The propagators for the
  +``opentelemetry.propagators.composite.CompositeHTTPPropagator`` can be defined
  +via configuration in the ``OTEL_PROPAGATORS`` environment variable. This
  +variable should be set to a comma-separated string of names of values for the
  +``opentelemetry_propagator`` entry point. For example, setting
  +``OTEL_PROPAGATORS`` to ``tracecontext,baggage`` (which is the default value)
  +would instantiate
  +``opentelemetry.propagators.composite.CompositeHTTPPropagator`` with 2
  +propagators, one of type
  +``opentelemetry.trace.propagation.tracecontext.TraceContextTextMapPropagator``
  +and other of type ``opentelemetry.baggage.propagation.BaggagePropagator``.
  +Notice that these propagator classes are defined as
  +``opentelemetry_propagator`` entry points in the ``setup.cfg`` file of
  +``opentelemetry``.
  +
   Example::
   
       import flask
  @@ -54,14 +69,16 @@
   """
   
   import typing
  +from logging import getLogger
  +
  +from pkg_resources import iter_entry_points
   
  -from opentelemetry.baggage.propagation import BaggagePropagator
  +from opentelemetry.configuration import Configuration
   from opentelemetry.context.context import Context
   from opentelemetry.propagators import composite
   from opentelemetry.trace.propagation import textmap
  -from opentelemetry.trace.propagation.tracecontext import (
  -    TraceContextTextMapPropagator,
  -)
  +
  +logger = getLogger(__name__)
   
   
   def extract(
  @@ -104,9 +121,25 @@
       get_global_textmap().inject(set_in_carrier, carrier, context)
   
   
  -_HTTP_TEXT_FORMAT = composite.CompositeHTTPPropagator(
  -    [TraceContextTextMapPropagator(), BaggagePropagator()],
  -)  # type: textmap.TextMapPropagator
  +try:
  +
  +    propagators = []
  +
  +    for propagator in (  # type: ignore
  +        Configuration().get("PROPAGATORS", "tracecontext,baggage").split(",")  # type: ignore
  +    ):
  +
  +        propagators.append(  # type: ignore
  +            next(  # type: ignore
  +                iter_entry_points("opentelemetry_propagator", propagator)  # type: ignore
  +            ).load()()
  +        )
  +
  +except Exception:  # pylint: disable=broad-except
  +    logger.exception("Failed to load configured propagators")
  +    raise
  +
  +_HTTP_TEXT_FORMAT = composite.CompositeHTTPPropagator(propagators)  # type: ignore
   
   
   def get_global_textmap() -> textmap.TextMapPropagator:
  @@ -115,4 +148,4 @@
   
   def set_global_textmap(http_text_format: textmap.TextMapPropagator,) -> None:
       global _HTTP_TEXT_FORMAT  # pylint:disable=global-statement
  -    _HTTP_TEXT_FORMAT = http_text_format
  +    _HTTP_TEXT_FORMAT = http_text_format  # type: ignore
  
verification_info: {"golden_diff": "diff --git a/opentelemetry-api/src/opentelemetry/propagators/__init__.py b/opentelemetry-api/src/opentelemetry/propagators/__init__.py\n--- a/opentelemetry-api/src/opentelemetry/propagators/__init__.py\n+++ b/opentelemetry-api/src/opentelemetry/propagators/__init__.py\n@@ -15,6 +15,21 @@\n \"\"\"\n API for propagation of context.\n \n+The propagators for the\n+``opentelemetry.propagators.composite.CompositeHTTPPropagator`` can be defined\n+via configuration in the ``OTEL_PROPAGATORS`` environment variable. This\n+variable should be set to a comma-separated string of names of values for the\n+``opentelemetry_propagator`` entry point. For example, setting\n+``OTEL_PROPAGATORS`` to ``tracecontext,baggage`` (which is the default value)\n+would instantiate\n+``opentelemetry.propagators.composite.CompositeHTTPPropagator`` with 2\n+propagators, one of type\n+``opentelemetry.trace.propagation.tracecontext.TraceContextTextMapPropagator``\n+and other of type ``opentelemetry.baggage.propagation.BaggagePropagator``.\n+Notice that these propagator classes are defined as\n+``opentelemetry_propagator`` entry points in the ``setup.cfg`` file of\n+``opentelemetry``.\n+\n Example::\n \n     import flask\n@@ -54,14 +69,16 @@\n \"\"\"\n \n import typing\n+from logging import getLogger\n+\n+from pkg_resources import iter_entry_points\n \n-from opentelemetry.baggage.propagation import BaggagePropagator\n+from opentelemetry.configuration import Configuration\n from opentelemetry.context.context import Context\n from opentelemetry.propagators import composite\n from opentelemetry.trace.propagation import textmap\n-from opentelemetry.trace.propagation.tracecontext import (\n-    TraceContextTextMapPropagator,\n-)\n+\n+logger = getLogger(__name__)\n \n \n def extract(\n@@ -104,9 +121,25 @@\n     get_global_textmap().inject(set_in_carrier, carrier, context)\n \n \n-_HTTP_TEXT_FORMAT = composite.CompositeHTTPPropagator(\n-    [TraceContextTextMapPropagator(), BaggagePropagator()],\n-)  # type: textmap.TextMapPropagator\n+try:\n+\n+    propagators = []\n+\n+    for propagator in (  # type: ignore\n+        Configuration().get(\"PROPAGATORS\", \"tracecontext,baggage\").split(\",\")  # type: ignore\n+    ):\n+\n+        propagators.append(  # type: ignore\n+            next(  # type: ignore\n+                iter_entry_points(\"opentelemetry_propagator\", propagator)  # type: ignore\n+            ).load()()\n+        )\n+\n+except Exception:  # pylint: disable=broad-except\n+    logger.exception(\"Failed to load configured propagators\")\n+    raise\n+\n+_HTTP_TEXT_FORMAT = composite.CompositeHTTPPropagator(propagators)  # type: ignore\n \n \n def get_global_textmap() -> textmap.TextMapPropagator:\n@@ -115,4 +148,4 @@\n \n def set_global_textmap(http_text_format: textmap.TextMapPropagator,) -> None:\n     global _HTTP_TEXT_FORMAT  # pylint:disable=global-statement\n-    _HTTP_TEXT_FORMAT = http_text_format\n+    _HTTP_TEXT_FORMAT = http_text_format  # type: ignore\n", "issue": "Add support for OTEL_PROPAGATORS\nThe spec describes environment variables that should be supported to configure propagators, this feature request is to add support in the current implementation.\r\n\r\nhttps://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/sdk-environment-variables.md\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\"\"\"\nAPI for propagation of context.\n\nExample::\n\n    import flask\n    import requests\n    from opentelemetry import propagators\n\n\n    PROPAGATOR = propagators.get_global_textmap()\n\n\n    def get_header_from_flask_request(request, key):\n        return request.headers.get_all(key)\n\n    def set_header_into_requests_request(request: requests.Request,\n                                            key: str, value: str):\n        request.headers[key] = value\n\n    def example_route():\n        context = PROPAGATOR.extract(\n            get_header_from_flask_request,\n            flask.request\n        )\n        request_to_downstream = requests.Request(\n            \"GET\", \"http://httpbin.org/get\"\n        )\n        PROPAGATOR.inject(\n            set_header_into_requests_request,\n            request_to_downstream,\n            context=context\n        )\n        session = requests.Session()\n        session.send(request_to_downstream.prepare())\n\n\n.. _Propagation API Specification:\n    https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/api-propagators.md\n\"\"\"\n\nimport typing\n\nfrom opentelemetry.baggage.propagation import BaggagePropagator\nfrom opentelemetry.context.context import Context\nfrom opentelemetry.propagators import composite\nfrom opentelemetry.trace.propagation import textmap\nfrom opentelemetry.trace.propagation.tracecontext import (\n    TraceContextTextMapPropagator,\n)\n\n\ndef extract(\n    get_from_carrier: textmap.Getter[textmap.TextMapPropagatorT],\n    carrier: textmap.TextMapPropagatorT,\n    context: typing.Optional[Context] = None,\n) -> Context:\n    \"\"\" Uses the configured propagator to extract a Context from the carrier.\n\n    Args:\n        get_from_carrier: a function that can retrieve zero\n            or more values from the carrier. In the case that\n            the value does not exist, return an empty list.\n        carrier: and object which contains values that are\n            used to construct a Context. This object\n            must be paired with an appropriate get_from_carrier\n            which understands how to extract a value from it.\n        context: an optional Context to use. Defaults to current\n            context if not set.\n    \"\"\"\n    return get_global_textmap().extract(get_from_carrier, carrier, context)\n\n\ndef inject(\n    set_in_carrier: textmap.Setter[textmap.TextMapPropagatorT],\n    carrier: textmap.TextMapPropagatorT,\n    context: typing.Optional[Context] = None,\n) -> None:\n    \"\"\" Uses the configured propagator to inject a Context into the carrier.\n\n    Args:\n        set_in_carrier: A setter function that can set values\n            on the carrier.\n        carrier: An object that contains a representation of HTTP\n            headers. Should be paired with set_in_carrier, which\n            should know how to set header values on the carrier.\n        context: an optional Context to use. Defaults to current\n            context if not set.\n    \"\"\"\n    get_global_textmap().inject(set_in_carrier, carrier, context)\n\n\n_HTTP_TEXT_FORMAT = composite.CompositeHTTPPropagator(\n    [TraceContextTextMapPropagator(), BaggagePropagator()],\n)  # type: textmap.TextMapPropagator\n\n\ndef get_global_textmap() -> textmap.TextMapPropagator:\n    return _HTTP_TEXT_FORMAT\n\n\ndef set_global_textmap(http_text_format: textmap.TextMapPropagator,) -> None:\n    global _HTTP_TEXT_FORMAT  # pylint:disable=global-statement\n    _HTTP_TEXT_FORMAT = http_text_format\n", "path": "opentelemetry-api/src/opentelemetry/propagators/__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\"\"\"\nAPI for propagation of context.\n\nThe propagators for the\n``opentelemetry.propagators.composite.CompositeHTTPPropagator`` can be defined\nvia configuration in the ``OTEL_PROPAGATORS`` environment variable. This\nvariable should be set to a comma-separated string of names of values for the\n``opentelemetry_propagator`` entry point. For example, setting\n``OTEL_PROPAGATORS`` to ``tracecontext,baggage`` (which is the default value)\nwould instantiate\n``opentelemetry.propagators.composite.CompositeHTTPPropagator`` with 2\npropagators, one of type\n``opentelemetry.trace.propagation.tracecontext.TraceContextTextMapPropagator``\nand other of type ``opentelemetry.baggage.propagation.BaggagePropagator``.\nNotice that these propagator classes are defined as\n``opentelemetry_propagator`` entry points in the ``setup.cfg`` file of\n``opentelemetry``.\n\nExample::\n\n    import flask\n    import requests\n    from opentelemetry import propagators\n\n\n    PROPAGATOR = propagators.get_global_textmap()\n\n\n    def get_header_from_flask_request(request, key):\n        return request.headers.get_all(key)\n\n    def set_header_into_requests_request(request: requests.Request,\n                                            key: str, value: str):\n        request.headers[key] = value\n\n    def example_route():\n        context = PROPAGATOR.extract(\n            get_header_from_flask_request,\n            flask.request\n        )\n        request_to_downstream = requests.Request(\n            \"GET\", \"http://httpbin.org/get\"\n        )\n        PROPAGATOR.inject(\n            set_header_into_requests_request,\n            request_to_downstream,\n            context=context\n        )\n        session = requests.Session()\n        session.send(request_to_downstream.prepare())\n\n\n.. _Propagation API Specification:\n    https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/api-propagators.md\n\"\"\"\n\nimport typing\nfrom logging import getLogger\n\nfrom pkg_resources import iter_entry_points\n\nfrom opentelemetry.configuration import Configuration\nfrom opentelemetry.context.context import Context\nfrom opentelemetry.propagators import composite\nfrom opentelemetry.trace.propagation import textmap\n\nlogger = getLogger(__name__)\n\n\ndef extract(\n    get_from_carrier: textmap.Getter[textmap.TextMapPropagatorT],\n    carrier: textmap.TextMapPropagatorT,\n    context: typing.Optional[Context] = None,\n) -> Context:\n    \"\"\" Uses the configured propagator to extract a Context from the carrier.\n\n    Args:\n        get_from_carrier: a function that can retrieve zero\n            or more values from the carrier. In the case that\n            the value does not exist, return an empty list.\n        carrier: and object which contains values that are\n            used to construct a Context. This object\n            must be paired with an appropriate get_from_carrier\n            which understands how to extract a value from it.\n        context: an optional Context to use. Defaults to current\n            context if not set.\n    \"\"\"\n    return get_global_textmap().extract(get_from_carrier, carrier, context)\n\n\ndef inject(\n    set_in_carrier: textmap.Setter[textmap.TextMapPropagatorT],\n    carrier: textmap.TextMapPropagatorT,\n    context: typing.Optional[Context] = None,\n) -> None:\n    \"\"\" Uses the configured propagator to inject a Context into the carrier.\n\n    Args:\n        set_in_carrier: A setter function that can set values\n            on the carrier.\n        carrier: An object that contains a representation of HTTP\n            headers. Should be paired with set_in_carrier, which\n            should know how to set header values on the carrier.\n        context: an optional Context to use. Defaults to current\n            context if not set.\n    \"\"\"\n    get_global_textmap().inject(set_in_carrier, carrier, context)\n\n\ntry:\n\n    propagators = []\n\n    for propagator in (  # type: ignore\n        Configuration().get(\"PROPAGATORS\", \"tracecontext,baggage\").split(\",\")  # type: ignore\n    ):\n\n        propagators.append(  # type: ignore\n            next(  # type: ignore\n                iter_entry_points(\"opentelemetry_propagator\", propagator)  # type: ignore\n            ).load()()\n        )\n\nexcept Exception:  # pylint: disable=broad-except\n    logger.exception(\"Failed to load configured propagators\")\n    raise\n\n_HTTP_TEXT_FORMAT = composite.CompositeHTTPPropagator(propagators)  # type: ignore\n\n\ndef get_global_textmap() -> textmap.TextMapPropagator:\n    return _HTTP_TEXT_FORMAT\n\n\ndef set_global_textmap(http_text_format: textmap.TextMapPropagator,) -> None:\n    global _HTTP_TEXT_FORMAT  # pylint:disable=global-statement\n    _HTTP_TEXT_FORMAT = http_text_format  # type: ignore\n", "path": "opentelemetry-api/src/opentelemetry/propagators/__init__.py"}]}