We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
get_correlations return value should be immutable
According to the [spec](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/correlationcontext/api.md#get-correlations):

> the returned value can be either an immutable collection or an immutable iterator

Currently, we return a `dict` ([link](https://github.com/open-telemetry/opentelemetry-python/blob/3cae0775ba12a2f7b4214b8b8c062c5e81002a19/opentelemetry-api/src/opentelemetry/correlationcontext/__init__.py#L34-L37)): 
```python
correlations = get_value(_CORRELATION_CONTEXT_KEY, context=context)
if isinstance(correlations, dict):
    return correlations.copy()
return {}
```

This was mentioned in the PR but not definitively addressed https://github.com/open-telemetry/opentelemetry-python/pull/471#discussion_r392369812, so I thought it might be worth bringing up again before GA.

--- 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/correlationcontext/propagation/__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 import typing
16 import urllib.parse
17 
18 from opentelemetry import correlationcontext
19 from opentelemetry.context import get_current
20 from opentelemetry.context.context import Context
21 from opentelemetry.trace.propagation import httptextformat
22 
23 
24 class CorrelationContextPropagator(httptextformat.HTTPTextFormat):
25     MAX_HEADER_LENGTH = 8192
26     MAX_PAIR_LENGTH = 4096
27     MAX_PAIRS = 180
28     _CORRELATION_CONTEXT_HEADER_NAME = "otcorrelationcontext"
29 
30     def extract(
31         self,
32         get_from_carrier: httptextformat.Getter[
33             httptextformat.HTTPTextFormatT
34         ],
35         carrier: httptextformat.HTTPTextFormatT,
36         context: typing.Optional[Context] = None,
37     ) -> Context:
38         """Extract CorrelationContext from the carrier.
39 
40         See
41         `opentelemetry.trace.propagation.httptextformat.HTTPTextFormat.extract`
42         """
43 
44         if context is None:
45             context = get_current()
46 
47         header = _extract_first_element(
48             get_from_carrier(carrier, self._CORRELATION_CONTEXT_HEADER_NAME)
49         )
50 
51         if not header or len(header) > self.MAX_HEADER_LENGTH:
52             return context
53 
54         correlations = header.split(",")
55         total_correlations = self.MAX_PAIRS
56         for correlation in correlations:
57             if total_correlations <= 0:
58                 return context
59             total_correlations -= 1
60             if len(correlation) > self.MAX_PAIR_LENGTH:
61                 continue
62             try:
63                 name, value = correlation.split("=", 1)
64             except Exception:  # pylint: disable=broad-except
65                 continue
66             context = correlationcontext.set_correlation(
67                 urllib.parse.unquote(name).strip(),
68                 urllib.parse.unquote(value).strip(),
69                 context=context,
70             )
71 
72         return context
73 
74     def inject(
75         self,
76         set_in_carrier: httptextformat.Setter[httptextformat.HTTPTextFormatT],
77         carrier: httptextformat.HTTPTextFormatT,
78         context: typing.Optional[Context] = None,
79     ) -> None:
80         """Injects CorrelationContext into the carrier.
81 
82         See
83         `opentelemetry.trace.propagation.httptextformat.HTTPTextFormat.inject`
84         """
85         correlations = correlationcontext.get_correlations(context=context)
86         if not correlations:
87             return
88 
89         correlation_context_string = _format_correlations(correlations)
90         set_in_carrier(
91             carrier,
92             self._CORRELATION_CONTEXT_HEADER_NAME,
93             correlation_context_string,
94         )
95 
96 
97 def _format_correlations(correlations: typing.Dict[str, object]) -> str:
98     return ",".join(
99         key + "=" + urllib.parse.quote_plus(str(value))
100         for key, value in correlations.items()
101     )
102 
103 
104 def _extract_first_element(
105     items: typing.Iterable[httptextformat.HTTPTextFormatT],
106 ) -> typing.Optional[httptextformat.HTTPTextFormatT]:
107     if items is None:
108         return None
109     return next(iter(items), None)
110
```

Path: `opentelemetry-api/src/opentelemetry/correlationcontext/__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 import typing
16 
17 from opentelemetry.context import get_value, set_value
18 from opentelemetry.context.context import Context
19 
20 _CORRELATION_CONTEXT_KEY = "correlation-context"
21 
22 
23 def get_correlations(
24     context: typing.Optional[Context] = None,
25 ) -> typing.Dict[str, object]:
26     """Returns the name/value pairs in the CorrelationContext
27 
28     Args:
29         context: The Context to use. If not set, uses current Context
30 
31     Returns:
32         Name/value pairs in the CorrelationContext
33     """
34     correlations = get_value(_CORRELATION_CONTEXT_KEY, context=context)
35     if isinstance(correlations, dict):
36         return correlations.copy()
37     return {}
38 
39 
40 def get_correlation(
41     name: str, context: typing.Optional[Context] = None
42 ) -> typing.Optional[object]:
43     """Provides access to the value for a name/value pair in the
44     CorrelationContext
45 
46     Args:
47         name: The name of the value to retrieve
48         context: The Context to use. If not set, uses current Context
49 
50     Returns:
51         The value associated with the given name, or null if the given name is
52         not present.
53     """
54     return get_correlations(context=context).get(name)
55 
56 
57 def set_correlation(
58     name: str, value: object, context: typing.Optional[Context] = None
59 ) -> Context:
60     """Sets a value in the CorrelationContext
61 
62     Args:
63         name: The name of the value to set
64         value: The value to set
65         context: The Context to use. If not set, uses current Context
66 
67     Returns:
68         A Context with the value updated
69     """
70     correlations = get_correlations(context=context)
71     correlations[name] = value
72     return set_value(_CORRELATION_CONTEXT_KEY, correlations, context=context)
73 
74 
75 def remove_correlation(
76     name: str, context: typing.Optional[Context] = None
77 ) -> Context:
78     """Removes a value from the CorrelationContext
79 
80     Args:
81         name: The name of the value to remove
82         context: The Context to use. If not set, uses current Context
83 
84     Returns:
85         A Context with the name/value removed
86     """
87     correlations = get_correlations(context=context)
88     correlations.pop(name, None)
89 
90     return set_value(_CORRELATION_CONTEXT_KEY, correlations, context=context)
91 
92 
93 def clear_correlations(context: typing.Optional[Context] = None) -> Context:
94     """Removes all values from the CorrelationContext
95 
96     Args:
97         context: The Context to use. If not set, uses current Context
98 
99     Returns:
100         A Context with all correlations removed
101     """
102     return set_value(_CORRELATION_CONTEXT_KEY, {}, context=context)
103
```
--- 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/correlationcontext/__init__.py b/opentelemetry-api/src/opentelemetry/correlationcontext/__init__.py
--- a/opentelemetry-api/src/opentelemetry/correlationcontext/__init__.py
+++ b/opentelemetry-api/src/opentelemetry/correlationcontext/__init__.py
@@ -13,6 +13,7 @@
 # limitations under the License.
 
 import typing
+from types import MappingProxyType
 
 from opentelemetry.context import get_value, set_value
 from opentelemetry.context.context import Context
@@ -22,7 +23,7 @@
 
 def get_correlations(
     context: typing.Optional[Context] = None,
-) -> typing.Dict[str, object]:
+) -> typing.Mapping[str, object]:
     """Returns the name/value pairs in the CorrelationContext
 
     Args:
@@ -33,8 +34,8 @@
     """
     correlations = get_value(_CORRELATION_CONTEXT_KEY, context=context)
     if isinstance(correlations, dict):
-        return correlations.copy()
-    return {}
+        return MappingProxyType(correlations.copy())
+    return MappingProxyType({})
 
 
 def get_correlation(
@@ -67,7 +68,7 @@
     Returns:
         A Context with the value updated
     """
-    correlations = get_correlations(context=context)
+    correlations = dict(get_correlations(context=context))
     correlations[name] = value
     return set_value(_CORRELATION_CONTEXT_KEY, correlations, context=context)
 
@@ -84,7 +85,7 @@
     Returns:
         A Context with the name/value removed
     """
-    correlations = get_correlations(context=context)
+    correlations = dict(get_correlations(context=context))
     correlations.pop(name, None)
 
     return set_value(_CORRELATION_CONTEXT_KEY, correlations, context=context)
diff --git a/opentelemetry-api/src/opentelemetry/correlationcontext/propagation/__init__.py b/opentelemetry-api/src/opentelemetry/correlationcontext/propagation/__init__.py
--- a/opentelemetry-api/src/opentelemetry/correlationcontext/propagation/__init__.py
+++ b/opentelemetry-api/src/opentelemetry/correlationcontext/propagation/__init__.py
@@ -94,7 +94,7 @@
         )
 
 
-def _format_correlations(correlations: typing.Dict[str, object]) -> str:
+def _format_correlations(correlations: typing.Mapping[str, object]) -> str:
     return ",".join(
         key + "=" + urllib.parse.quote_plus(str(value))
         for key, value in correlations.items()

{"golden_diff": "diff --git a/opentelemetry-api/src/opentelemetry/correlationcontext/__init__.py b/opentelemetry-api/src/opentelemetry/correlationcontext/__init__.py\n--- a/opentelemetry-api/src/opentelemetry/correlationcontext/__init__.py\n+++ b/opentelemetry-api/src/opentelemetry/correlationcontext/__init__.py\n@@ -13,6 +13,7 @@\n # limitations under the License.\n \n import typing\n+from types import MappingProxyType\n \n from opentelemetry.context import get_value, set_value\n from opentelemetry.context.context import Context\n@@ -22,7 +23,7 @@\n \n def get_correlations(\n     context: typing.Optional[Context] = None,\n-) -> typing.Dict[str, object]:\n+) -> typing.Mapping[str, object]:\n     \"\"\"Returns the name/value pairs in the CorrelationContext\n \n     Args:\n@@ -33,8 +34,8 @@\n     \"\"\"\n     correlations = get_value(_CORRELATION_CONTEXT_KEY, context=context)\n     if isinstance(correlations, dict):\n-        return correlations.copy()\n-    return {}\n+        return MappingProxyType(correlations.copy())\n+    return MappingProxyType({})\n \n \n def get_correlation(\n@@ -67,7 +68,7 @@\n     Returns:\n         A Context with the value updated\n     \"\"\"\n-    correlations = get_correlations(context=context)\n+    correlations = dict(get_correlations(context=context))\n     correlations[name] = value\n     return set_value(_CORRELATION_CONTEXT_KEY, correlations, context=context)\n \n@@ -84,7 +85,7 @@\n     Returns:\n         A Context with the name/value removed\n     \"\"\"\n-    correlations = get_correlations(context=context)\n+    correlations = dict(get_correlations(context=context))\n     correlations.pop(name, None)\n \n     return set_value(_CORRELATION_CONTEXT_KEY, correlations, context=context)\ndiff --git a/opentelemetry-api/src/opentelemetry/correlationcontext/propagation/__init__.py b/opentelemetry-api/src/opentelemetry/correlationcontext/propagation/__init__.py\n--- a/opentelemetry-api/src/opentelemetry/correlationcontext/propagation/__init__.py\n+++ b/opentelemetry-api/src/opentelemetry/correlationcontext/propagation/__init__.py\n@@ -94,7 +94,7 @@\n         )\n \n \n-def _format_correlations(correlations: typing.Dict[str, object]) -> str:\n+def _format_correlations(correlations: typing.Mapping[str, object]) -> str:\n     return \",\".join(\n         key + \"=\" + urllib.parse.quote_plus(str(value))\n         for key, value in correlations.items()\n", "issue": "get_correlations return value should be immutable\nAccording to the [spec](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/correlationcontext/api.md#get-correlations):\r\n\r\n> the returned value can be either an immutable collection or an immutable iterator\r\n\r\nCurrently, we return a `dict` ([link](https://github.com/open-telemetry/opentelemetry-python/blob/3cae0775ba12a2f7b4214b8b8c062c5e81002a19/opentelemetry-api/src/opentelemetry/correlationcontext/__init__.py#L34-L37)): \r\n```python\r\ncorrelations = get_value(_CORRELATION_CONTEXT_KEY, context=context)\r\nif isinstance(correlations, dict):\r\n    return correlations.copy()\r\nreturn {}\r\n```\r\n\r\nThis was mentioned in the PR but not definitively addressed https://github.com/open-telemetry/opentelemetry-python/pull/471#discussion_r392369812, so I thought it might be worth bringing up again before GA.\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#\nimport typing\nimport urllib.parse\n\nfrom opentelemetry import correlationcontext\nfrom opentelemetry.context import get_current\nfrom opentelemetry.context.context import Context\nfrom opentelemetry.trace.propagation import httptextformat\n\n\nclass CorrelationContextPropagator(httptextformat.HTTPTextFormat):\n    MAX_HEADER_LENGTH = 8192\n    MAX_PAIR_LENGTH = 4096\n    MAX_PAIRS = 180\n    _CORRELATION_CONTEXT_HEADER_NAME = \"otcorrelationcontext\"\n\n    def extract(\n        self,\n        get_from_carrier: httptextformat.Getter[\n            httptextformat.HTTPTextFormatT\n        ],\n        carrier: httptextformat.HTTPTextFormatT,\n        context: typing.Optional[Context] = None,\n    ) -> Context:\n        \"\"\"Extract CorrelationContext from the carrier.\n\n        See\n        `opentelemetry.trace.propagation.httptextformat.HTTPTextFormat.extract`\n        \"\"\"\n\n        if context is None:\n            context = get_current()\n\n        header = _extract_first_element(\n            get_from_carrier(carrier, self._CORRELATION_CONTEXT_HEADER_NAME)\n        )\n\n        if not header or len(header) > self.MAX_HEADER_LENGTH:\n            return context\n\n        correlations = header.split(\",\")\n        total_correlations = self.MAX_PAIRS\n        for correlation in correlations:\n            if total_correlations <= 0:\n                return context\n            total_correlations -= 1\n            if len(correlation) > self.MAX_PAIR_LENGTH:\n                continue\n            try:\n                name, value = correlation.split(\"=\", 1)\n            except Exception:  # pylint: disable=broad-except\n                continue\n            context = correlationcontext.set_correlation(\n                urllib.parse.unquote(name).strip(),\n                urllib.parse.unquote(value).strip(),\n                context=context,\n            )\n\n        return context\n\n    def inject(\n        self,\n        set_in_carrier: httptextformat.Setter[httptextformat.HTTPTextFormatT],\n        carrier: httptextformat.HTTPTextFormatT,\n        context: typing.Optional[Context] = None,\n    ) -> None:\n        \"\"\"Injects CorrelationContext into the carrier.\n\n        See\n        `opentelemetry.trace.propagation.httptextformat.HTTPTextFormat.inject`\n        \"\"\"\n        correlations = correlationcontext.get_correlations(context=context)\n        if not correlations:\n            return\n\n        correlation_context_string = _format_correlations(correlations)\n        set_in_carrier(\n            carrier,\n            self._CORRELATION_CONTEXT_HEADER_NAME,\n            correlation_context_string,\n        )\n\n\ndef _format_correlations(correlations: typing.Dict[str, object]) -> str:\n    return \",\".join(\n        key + \"=\" + urllib.parse.quote_plus(str(value))\n        for key, value in correlations.items()\n    )\n\n\ndef _extract_first_element(\n    items: typing.Iterable[httptextformat.HTTPTextFormatT],\n) -> typing.Optional[httptextformat.HTTPTextFormatT]:\n    if items is None:\n        return None\n    return next(iter(items), None)\n", "path": "opentelemetry-api/src/opentelemetry/correlationcontext/propagation/__init__.py"}, {"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\nimport typing\n\nfrom opentelemetry.context import get_value, set_value\nfrom opentelemetry.context.context import Context\n\n_CORRELATION_CONTEXT_KEY = \"correlation-context\"\n\n\ndef get_correlations(\n    context: typing.Optional[Context] = None,\n) -> typing.Dict[str, object]:\n    \"\"\"Returns the name/value pairs in the CorrelationContext\n\n    Args:\n        context: The Context to use. If not set, uses current Context\n\n    Returns:\n        Name/value pairs in the CorrelationContext\n    \"\"\"\n    correlations = get_value(_CORRELATION_CONTEXT_KEY, context=context)\n    if isinstance(correlations, dict):\n        return correlations.copy()\n    return {}\n\n\ndef get_correlation(\n    name: str, context: typing.Optional[Context] = None\n) -> typing.Optional[object]:\n    \"\"\"Provides access to the value for a name/value pair in the\n    CorrelationContext\n\n    Args:\n        name: The name of the value to retrieve\n        context: The Context to use. If not set, uses current Context\n\n    Returns:\n        The value associated with the given name, or null if the given name is\n        not present.\n    \"\"\"\n    return get_correlations(context=context).get(name)\n\n\ndef set_correlation(\n    name: str, value: object, context: typing.Optional[Context] = None\n) -> Context:\n    \"\"\"Sets a value in the CorrelationContext\n\n    Args:\n        name: The name of the value to set\n        value: The value to set\n        context: The Context to use. If not set, uses current Context\n\n    Returns:\n        A Context with the value updated\n    \"\"\"\n    correlations = get_correlations(context=context)\n    correlations[name] = value\n    return set_value(_CORRELATION_CONTEXT_KEY, correlations, context=context)\n\n\ndef remove_correlation(\n    name: str, context: typing.Optional[Context] = None\n) -> Context:\n    \"\"\"Removes a value from the CorrelationContext\n\n    Args:\n        name: The name of the value to remove\n        context: The Context to use. If not set, uses current Context\n\n    Returns:\n        A Context with the name/value removed\n    \"\"\"\n    correlations = get_correlations(context=context)\n    correlations.pop(name, None)\n\n    return set_value(_CORRELATION_CONTEXT_KEY, correlations, context=context)\n\n\ndef clear_correlations(context: typing.Optional[Context] = None) -> Context:\n    \"\"\"Removes all values from the CorrelationContext\n\n    Args:\n        context: The Context to use. If not set, uses current Context\n\n    Returns:\n        A Context with all correlations removed\n    \"\"\"\n    return set_value(_CORRELATION_CONTEXT_KEY, {}, context=context)\n", "path": "opentelemetry-api/src/opentelemetry/correlationcontext/__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#\nimport typing\nimport urllib.parse\n\nfrom opentelemetry import correlationcontext\nfrom opentelemetry.context import get_current\nfrom opentelemetry.context.context import Context\nfrom opentelemetry.trace.propagation import httptextformat\n\n\nclass CorrelationContextPropagator(httptextformat.HTTPTextFormat):\n    MAX_HEADER_LENGTH = 8192\n    MAX_PAIR_LENGTH = 4096\n    MAX_PAIRS = 180\n    _CORRELATION_CONTEXT_HEADER_NAME = \"otcorrelationcontext\"\n\n    def extract(\n        self,\n        get_from_carrier: httptextformat.Getter[\n            httptextformat.HTTPTextFormatT\n        ],\n        carrier: httptextformat.HTTPTextFormatT,\n        context: typing.Optional[Context] = None,\n    ) -> Context:\n        \"\"\"Extract CorrelationContext from the carrier.\n\n        See\n        `opentelemetry.trace.propagation.httptextformat.HTTPTextFormat.extract`\n        \"\"\"\n\n        if context is None:\n            context = get_current()\n\n        header = _extract_first_element(\n            get_from_carrier(carrier, self._CORRELATION_CONTEXT_HEADER_NAME)\n        )\n\n        if not header or len(header) > self.MAX_HEADER_LENGTH:\n            return context\n\n        correlations = header.split(\",\")\n        total_correlations = self.MAX_PAIRS\n        for correlation in correlations:\n            if total_correlations <= 0:\n                return context\n            total_correlations -= 1\n            if len(correlation) > self.MAX_PAIR_LENGTH:\n                continue\n            try:\n                name, value = correlation.split(\"=\", 1)\n            except Exception:  # pylint: disable=broad-except\n                continue\n            context = correlationcontext.set_correlation(\n                urllib.parse.unquote(name).strip(),\n                urllib.parse.unquote(value).strip(),\n                context=context,\n            )\n\n        return context\n\n    def inject(\n        self,\n        set_in_carrier: httptextformat.Setter[httptextformat.HTTPTextFormatT],\n        carrier: httptextformat.HTTPTextFormatT,\n        context: typing.Optional[Context] = None,\n    ) -> None:\n        \"\"\"Injects CorrelationContext into the carrier.\n\n        See\n        `opentelemetry.trace.propagation.httptextformat.HTTPTextFormat.inject`\n        \"\"\"\n        correlations = correlationcontext.get_correlations(context=context)\n        if not correlations:\n            return\n\n        correlation_context_string = _format_correlations(correlations)\n        set_in_carrier(\n            carrier,\n            self._CORRELATION_CONTEXT_HEADER_NAME,\n            correlation_context_string,\n        )\n\n\ndef _format_correlations(correlations: typing.Mapping[str, object]) -> str:\n    return \",\".join(\n        key + \"=\" + urllib.parse.quote_plus(str(value))\n        for key, value in correlations.items()\n    )\n\n\ndef _extract_first_element(\n    items: typing.Iterable[httptextformat.HTTPTextFormatT],\n) -> typing.Optional[httptextformat.HTTPTextFormatT]:\n    if items is None:\n        return None\n    return next(iter(items), None)\n", "path": "opentelemetry-api/src/opentelemetry/correlationcontext/propagation/__init__.py"}, {"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\nimport typing\nfrom types import MappingProxyType\n\nfrom opentelemetry.context import get_value, set_value\nfrom opentelemetry.context.context import Context\n\n_CORRELATION_CONTEXT_KEY = \"correlation-context\"\n\n\ndef get_correlations(\n    context: typing.Optional[Context] = None,\n) -> typing.Mapping[str, object]:\n    \"\"\"Returns the name/value pairs in the CorrelationContext\n\n    Args:\n        context: The Context to use. If not set, uses current Context\n\n    Returns:\n        Name/value pairs in the CorrelationContext\n    \"\"\"\n    correlations = get_value(_CORRELATION_CONTEXT_KEY, context=context)\n    if isinstance(correlations, dict):\n        return MappingProxyType(correlations.copy())\n    return MappingProxyType({})\n\n\ndef get_correlation(\n    name: str, context: typing.Optional[Context] = None\n) -> typing.Optional[object]:\n    \"\"\"Provides access to the value for a name/value pair in the\n    CorrelationContext\n\n    Args:\n        name: The name of the value to retrieve\n        context: The Context to use. If not set, uses current Context\n\n    Returns:\n        The value associated with the given name, or null if the given name is\n        not present.\n    \"\"\"\n    return get_correlations(context=context).get(name)\n\n\ndef set_correlation(\n    name: str, value: object, context: typing.Optional[Context] = None\n) -> Context:\n    \"\"\"Sets a value in the CorrelationContext\n\n    Args:\n        name: The name of the value to set\n        value: The value to set\n        context: The Context to use. If not set, uses current Context\n\n    Returns:\n        A Context with the value updated\n    \"\"\"\n    correlations = dict(get_correlations(context=context))\n    correlations[name] = value\n    return set_value(_CORRELATION_CONTEXT_KEY, correlations, context=context)\n\n\ndef remove_correlation(\n    name: str, context: typing.Optional[Context] = None\n) -> Context:\n    \"\"\"Removes a value from the CorrelationContext\n\n    Args:\n        name: The name of the value to remove\n        context: The Context to use. If not set, uses current Context\n\n    Returns:\n        A Context with the name/value removed\n    \"\"\"\n    correlations = dict(get_correlations(context=context))\n    correlations.pop(name, None)\n\n    return set_value(_CORRELATION_CONTEXT_KEY, correlations, context=context)\n\n\ndef clear_correlations(context: typing.Optional[Context] = None) -> Context:\n    \"\"\"Removes all values from the CorrelationContext\n\n    Args:\n        context: The Context to use. If not set, uses current Context\n\n    Returns:\n        A Context with all correlations removed\n    \"\"\"\n    return set_value(_CORRELATION_CONTEXT_KEY, {}, context=context)\n", "path": "opentelemetry-api/src/opentelemetry/correlationcontext/__init__.py"}]}