We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Update default port for OTLP exporter to 4317
With this change https://github.com/open-telemetry/opentelemetry-specification/pull/1221 default port for OTLP exporter is 4317, the current default port in the OTLP exporter is 55680. This should be updated.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__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 """
17 This library allows to export tracing data to an OTLP collector.
18 
19 Usage
20 -----
21 
22 The **OTLP Span Exporter** allows to export `OpenTelemetry`_ traces to the
23 `OTLP`_ collector.
24 
25 
26 .. _OTLP: https://github.com/open-telemetry/opentelemetry-collector/
27 .. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/
28 
29 .. envvar:: OTEL_EXPORTER_OTLP_COMPRESSION
30 
31 The :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` environment variable allows a
32 compression algorithm to be passed to the OTLP exporter. The compression
33 algorithms that are supported include gzip and no compression. The value should
34 be in the format of a string "gzip" for gzip compression, and no value specified
35 if no compression is the desired choice.
36 Additional details are available `in the specification
37 <https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/protocol/exporter.md#opentelemetry-protocol-exporter>`_.
38 
39 .. code:: python
40 
41     from opentelemetry import trace
42     from opentelemetry.exporter.otlp.trace_exporter import OTLPSpanExporter
43     from opentelemetry.sdk.resources import Resource
44     from opentelemetry.sdk.trace import TracerProvider
45     from opentelemetry.sdk.trace.export import BatchExportSpanProcessor
46 
47     # Resource can be required for some backends, e.g. Jaeger
48     # If resource wouldn't be set - traces wouldn't appears in Jaeger
49     resource = Resource(attributes={
50         "service.name": "service"
51     })
52 
53     trace.set_tracer_provider(TracerProvider(resource=resource))
54     tracer = trace.get_tracer(__name__)
55 
56     otlp_exporter = OTLPSpanExporter(endpoint="localhost:55680", insecure=True)
57 
58     span_processor = BatchExportSpanProcessor(otlp_exporter)
59 
60     trace.get_tracer_provider().add_span_processor(span_processor)
61 
62     with tracer.start_as_current_span("foo"):
63         print("Hello world!")
64 
65 API
66 ---
67 """
68
```

Path: `exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.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 """OTLP Exporter"""
16 
17 import enum
18 import logging
19 from abc import ABC, abstractmethod
20 from collections.abc import Mapping, Sequence
21 from time import sleep
22 from typing import Any, Callable, Dict, Generic, List, Optional
23 from typing import Sequence as TypingSequence
24 from typing import Text, TypeVar
25 
26 from backoff import expo
27 from google.rpc.error_details_pb2 import RetryInfo
28 from grpc import (
29     ChannelCredentials,
30     Compression,
31     RpcError,
32     StatusCode,
33     insecure_channel,
34     secure_channel,
35     ssl_channel_credentials,
36 )
37 
38 from opentelemetry.configuration import Configuration
39 from opentelemetry.proto.common.v1.common_pb2 import AnyValue, KeyValue
40 from opentelemetry.proto.resource.v1.resource_pb2 import Resource
41 from opentelemetry.sdk.resources import Resource as SDKResource
42 
43 logger = logging.getLogger(__name__)
44 SDKDataT = TypeVar("SDKDataT")
45 ResourceDataT = TypeVar("ResourceDataT")
46 TypingResourceT = TypeVar("TypingResourceT")
47 ExportServiceRequestT = TypeVar("ExportServiceRequestT")
48 ExportResultT = TypeVar("ExportResultT")
49 
50 
51 class OTLPCompression(enum.Enum):
52     gzip = "gzip"
53 
54 
55 def _translate_key_values(key: Text, value: Any) -> KeyValue:
56 
57     if isinstance(value, bool):
58         any_value = AnyValue(bool_value=value)
59 
60     elif isinstance(value, str):
61         any_value = AnyValue(string_value=value)
62 
63     elif isinstance(value, int):
64         any_value = AnyValue(int_value=value)
65 
66     elif isinstance(value, float):
67         any_value = AnyValue(double_value=value)
68 
69     elif isinstance(value, Sequence):
70         any_value = AnyValue(array_value=value)
71 
72     elif isinstance(value, Mapping):
73         any_value = AnyValue(kvlist_value=value)
74 
75     else:
76         raise Exception(
77             "Invalid type {} of value {}".format(type(value), value)
78         )
79 
80     return KeyValue(key=key, value=any_value)
81 
82 
83 def _get_resource_data(
84     sdk_resource_instrumentation_library_data: Dict[
85         SDKResource, ResourceDataT
86     ],
87     resource_class: Callable[..., TypingResourceT],
88     name: str,
89 ) -> List[TypingResourceT]:
90 
91     resource_data = []
92 
93     for (
94         sdk_resource,
95         instrumentation_library_data,
96     ) in sdk_resource_instrumentation_library_data.items():
97 
98         collector_resource = Resource()
99 
100         for key, value in sdk_resource.attributes.items():
101 
102             try:
103                 # pylint: disable=no-member
104                 collector_resource.attributes.append(
105                     _translate_key_values(key, value)
106                 )
107             except Exception as error:  # pylint: disable=broad-except
108                 logger.exception(error)
109 
110         resource_data.append(
111             resource_class(
112                 **{
113                     "resource": collector_resource,
114                     "instrumentation_library_{}".format(name): [
115                         instrumentation_library_data
116                     ],
117                 }
118             )
119         )
120 
121     return resource_data
122 
123 
124 def _load_credential_from_file(filepath) -> ChannelCredentials:
125     try:
126         with open(filepath, "rb") as creds_file:
127             credential = creds_file.read()
128             return ssl_channel_credentials(credential)
129     except FileNotFoundError:
130         logger.exception("Failed to read credential file")
131         return None
132 
133 
134 # pylint: disable=no-member
135 class OTLPExporterMixin(
136     ABC, Generic[SDKDataT, ExportServiceRequestT, ExportResultT]
137 ):
138     """OTLP span/metric exporter
139 
140     Args:
141         endpoint: OpenTelemetry Collector receiver endpoint
142         insecure: Connection type
143         credentials: ChannelCredentials object for server authentication
144         headers: Headers to send when exporting
145         compression: Compression algorithm to be used in channel
146         timeout: Backend request timeout in seconds
147     """
148 
149     def __init__(
150         self,
151         endpoint: Optional[str] = None,
152         insecure: Optional[bool] = None,
153         credentials: Optional[ChannelCredentials] = None,
154         headers: Optional[Sequence] = None,
155         timeout: Optional[int] = None,
156         compression: str = None,
157     ):
158         super().__init__()
159 
160         endpoint = (
161             endpoint
162             or Configuration().EXPORTER_OTLP_ENDPOINT
163             or "localhost:55680"
164         )
165 
166         if insecure is None:
167             insecure = Configuration().EXPORTER_OTLP_INSECURE
168         if insecure is None:
169             insecure = False
170 
171         self._headers = headers or Configuration().EXPORTER_OTLP_HEADERS
172         if isinstance(self._headers, str):
173             self._headers = tuple(
174                 tuple(item.split("=")) for item in self._headers.split(",")
175             )
176         self._timeout = (
177             timeout
178             or Configuration().EXPORTER_OTLP_TIMEOUT
179             or 10  # default: 10 seconds
180         )
181         self._collector_span_kwargs = None
182 
183         if compression is None:
184             compression_algorithm = Compression.NoCompression
185         elif (
186             compression in OTLPCompression._value2member_map_
187             and OTLPCompression(compression) is OTLPCompression.gzip
188         ):
189             compression_algorithm = Compression.Gzip
190         else:
191             compression_str = Configuration().EXPORTER_OTLP_INSECURE or None
192             if compression_str is None:
193                 compression_algorithm = Compression.NoCompression
194             elif (
195                 compression_str in OTLPCompression._value2member_map_
196                 and OTLPCompression(compression_str) is OTLPCompression.gzip
197             ):
198                 compression_algorithm = Compression.Gzip
199             else:
200                 raise ValueError(
201                     "OTEL_EXPORTER_OTLP_COMPRESSION environment variable does not match gzip."
202                 )
203 
204         if insecure:
205             self._client = self._stub(
206                 insecure_channel(endpoint, compression=compression_algorithm)
207             )
208             return
209 
210         # secure mode
211         if (
212             credentials is None
213             and Configuration().EXPORTER_OTLP_CERTIFICATE is None
214         ):
215             # use the default location chosen by gRPC runtime
216             credentials = ssl_channel_credentials()
217         else:
218             credentials = credentials or _load_credential_from_file(
219                 Configuration().EXPORTER_OTLP_CERTIFICATE
220             )
221         self._client = self._stub(
222             secure_channel(
223                 endpoint, credentials, compression=compression_algorithm
224             )
225         )
226 
227     @abstractmethod
228     def _translate_data(
229         self, data: TypingSequence[SDKDataT]
230     ) -> ExportServiceRequestT:
231         pass
232 
233     def _export(self, data: TypingSequence[SDKDataT]) -> ExportResultT:
234         # expo returns a generator that yields delay values which grow
235         # exponentially. Once delay is greater than max_value, the yielded
236         # value will remain constant.
237         # max_value is set to 900 (900 seconds is 15 minutes) to use the same
238         # value as used in the Go implementation.
239 
240         max_value = 900
241 
242         for delay in expo(max_value=max_value):
243 
244             if delay == max_value:
245                 return self._result.FAILURE
246 
247             try:
248                 self._client.Export(
249                     request=self._translate_data(data),
250                     metadata=self._headers,
251                     timeout=self._timeout,
252                 )
253 
254                 return self._result.SUCCESS
255 
256             except RpcError as error:
257 
258                 if error.code() in [
259                     StatusCode.CANCELLED,
260                     StatusCode.DEADLINE_EXCEEDED,
261                     StatusCode.PERMISSION_DENIED,
262                     StatusCode.UNAUTHENTICATED,
263                     StatusCode.RESOURCE_EXHAUSTED,
264                     StatusCode.ABORTED,
265                     StatusCode.OUT_OF_RANGE,
266                     StatusCode.UNAVAILABLE,
267                     StatusCode.DATA_LOSS,
268                 ]:
269 
270                     retry_info_bin = dict(error.trailing_metadata()).get(
271                         "google.rpc.retryinfo-bin"
272                     )
273                     if retry_info_bin is not None:
274                         retry_info = RetryInfo()
275                         retry_info.ParseFromString(retry_info_bin)
276                         delay = (
277                             retry_info.retry_delay.seconds
278                             + retry_info.retry_delay.nanos / 1.0e9
279                         )
280 
281                     logger.debug(
282                         "Waiting %ss before retrying export of span", delay
283                     )
284                     sleep(delay)
285                     continue
286 
287                 if error.code() == StatusCode.OK:
288                     return self._result.SUCCESS
289 
290                 return self._result.FAILURE
291 
292         return self._result.FAILURE
293 
294     def shutdown(self) -> None:
295         pass
296
```
--- 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/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py
--- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py
+++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py
@@ -53,7 +53,7 @@
     trace.set_tracer_provider(TracerProvider(resource=resource))
     tracer = trace.get_tracer(__name__)
 
-    otlp_exporter = OTLPSpanExporter(endpoint="localhost:55680", insecure=True)
+    otlp_exporter = OTLPSpanExporter(endpoint="localhost:4317", insecure=True)
 
     span_processor = BatchExportSpanProcessor(otlp_exporter)
 
diff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py
--- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py
+++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py
@@ -160,7 +160,7 @@
         endpoint = (
             endpoint
             or Configuration().EXPORTER_OTLP_ENDPOINT
-            or "localhost:55680"
+            or "localhost:4317"
         )
 
         if insecure is None:

{"golden_diff": "diff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py\n--- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py\n+++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py\n@@ -53,7 +53,7 @@\n     trace.set_tracer_provider(TracerProvider(resource=resource))\n     tracer = trace.get_tracer(__name__)\n \n-    otlp_exporter = OTLPSpanExporter(endpoint=\"localhost:55680\", insecure=True)\n+    otlp_exporter = OTLPSpanExporter(endpoint=\"localhost:4317\", insecure=True)\n \n     span_processor = BatchExportSpanProcessor(otlp_exporter)\n \ndiff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py\n--- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py\n+++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py\n@@ -160,7 +160,7 @@\n         endpoint = (\n             endpoint\n             or Configuration().EXPORTER_OTLP_ENDPOINT\n-            or \"localhost:55680\"\n+            or \"localhost:4317\"\n         )\n \n         if insecure is None:\n", "issue": "Update default port for OTLP exporter to 4317\nWith this change https://github.com/open-telemetry/opentelemetry-specification/pull/1221 default port for OTLP exporter is 4317, the current default port in the OTLP exporter is 55680. This should be updated.\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\n\"\"\"\nThis library allows to export tracing data to an OTLP collector.\n\nUsage\n-----\n\nThe **OTLP Span Exporter** allows to export `OpenTelemetry`_ traces to the\n`OTLP`_ collector.\n\n\n.. _OTLP: https://github.com/open-telemetry/opentelemetry-collector/\n.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/\n\n.. envvar:: OTEL_EXPORTER_OTLP_COMPRESSION\n\nThe :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` environment variable allows a\ncompression algorithm to be passed to the OTLP exporter. The compression\nalgorithms that are supported include gzip and no compression. The value should\nbe in the format of a string \"gzip\" for gzip compression, and no value specified\nif no compression is the desired choice.\nAdditional details are available `in the specification\n<https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/protocol/exporter.md#opentelemetry-protocol-exporter>`_.\n\n.. code:: python\n\n    from opentelemetry import trace\n    from opentelemetry.exporter.otlp.trace_exporter import OTLPSpanExporter\n    from opentelemetry.sdk.resources import Resource\n    from opentelemetry.sdk.trace import TracerProvider\n    from opentelemetry.sdk.trace.export import BatchExportSpanProcessor\n\n    # Resource can be required for some backends, e.g. Jaeger\n    # If resource wouldn't be set - traces wouldn't appears in Jaeger\n    resource = Resource(attributes={\n        \"service.name\": \"service\"\n    })\n\n    trace.set_tracer_provider(TracerProvider(resource=resource))\n    tracer = trace.get_tracer(__name__)\n\n    otlp_exporter = OTLPSpanExporter(endpoint=\"localhost:55680\", insecure=True)\n\n    span_processor = BatchExportSpanProcessor(otlp_exporter)\n\n    trace.get_tracer_provider().add_span_processor(span_processor)\n\n    with tracer.start_as_current_span(\"foo\"):\n        print(\"Hello world!\")\n\nAPI\n---\n\"\"\"\n", "path": "exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__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\n\"\"\"OTLP Exporter\"\"\"\n\nimport enum\nimport logging\nfrom abc import ABC, abstractmethod\nfrom collections.abc import Mapping, Sequence\nfrom time import sleep\nfrom typing import Any, Callable, Dict, Generic, List, Optional\nfrom typing import Sequence as TypingSequence\nfrom typing import Text, TypeVar\n\nfrom backoff import expo\nfrom google.rpc.error_details_pb2 import RetryInfo\nfrom grpc import (\n    ChannelCredentials,\n    Compression,\n    RpcError,\n    StatusCode,\n    insecure_channel,\n    secure_channel,\n    ssl_channel_credentials,\n)\n\nfrom opentelemetry.configuration import Configuration\nfrom opentelemetry.proto.common.v1.common_pb2 import AnyValue, KeyValue\nfrom opentelemetry.proto.resource.v1.resource_pb2 import Resource\nfrom opentelemetry.sdk.resources import Resource as SDKResource\n\nlogger = logging.getLogger(__name__)\nSDKDataT = TypeVar(\"SDKDataT\")\nResourceDataT = TypeVar(\"ResourceDataT\")\nTypingResourceT = TypeVar(\"TypingResourceT\")\nExportServiceRequestT = TypeVar(\"ExportServiceRequestT\")\nExportResultT = TypeVar(\"ExportResultT\")\n\n\nclass OTLPCompression(enum.Enum):\n    gzip = \"gzip\"\n\n\ndef _translate_key_values(key: Text, value: Any) -> KeyValue:\n\n    if isinstance(value, bool):\n        any_value = AnyValue(bool_value=value)\n\n    elif isinstance(value, str):\n        any_value = AnyValue(string_value=value)\n\n    elif isinstance(value, int):\n        any_value = AnyValue(int_value=value)\n\n    elif isinstance(value, float):\n        any_value = AnyValue(double_value=value)\n\n    elif isinstance(value, Sequence):\n        any_value = AnyValue(array_value=value)\n\n    elif isinstance(value, Mapping):\n        any_value = AnyValue(kvlist_value=value)\n\n    else:\n        raise Exception(\n            \"Invalid type {} of value {}\".format(type(value), value)\n        )\n\n    return KeyValue(key=key, value=any_value)\n\n\ndef _get_resource_data(\n    sdk_resource_instrumentation_library_data: Dict[\n        SDKResource, ResourceDataT\n    ],\n    resource_class: Callable[..., TypingResourceT],\n    name: str,\n) -> List[TypingResourceT]:\n\n    resource_data = []\n\n    for (\n        sdk_resource,\n        instrumentation_library_data,\n    ) in sdk_resource_instrumentation_library_data.items():\n\n        collector_resource = Resource()\n\n        for key, value in sdk_resource.attributes.items():\n\n            try:\n                # pylint: disable=no-member\n                collector_resource.attributes.append(\n                    _translate_key_values(key, value)\n                )\n            except Exception as error:  # pylint: disable=broad-except\n                logger.exception(error)\n\n        resource_data.append(\n            resource_class(\n                **{\n                    \"resource\": collector_resource,\n                    \"instrumentation_library_{}\".format(name): [\n                        instrumentation_library_data\n                    ],\n                }\n            )\n        )\n\n    return resource_data\n\n\ndef _load_credential_from_file(filepath) -> ChannelCredentials:\n    try:\n        with open(filepath, \"rb\") as creds_file:\n            credential = creds_file.read()\n            return ssl_channel_credentials(credential)\n    except FileNotFoundError:\n        logger.exception(\"Failed to read credential file\")\n        return None\n\n\n# pylint: disable=no-member\nclass OTLPExporterMixin(\n    ABC, Generic[SDKDataT, ExportServiceRequestT, ExportResultT]\n):\n    \"\"\"OTLP span/metric exporter\n\n    Args:\n        endpoint: OpenTelemetry Collector receiver endpoint\n        insecure: Connection type\n        credentials: ChannelCredentials object for server authentication\n        headers: Headers to send when exporting\n        compression: Compression algorithm to be used in channel\n        timeout: Backend request timeout in seconds\n    \"\"\"\n\n    def __init__(\n        self,\n        endpoint: Optional[str] = None,\n        insecure: Optional[bool] = None,\n        credentials: Optional[ChannelCredentials] = None,\n        headers: Optional[Sequence] = None,\n        timeout: Optional[int] = None,\n        compression: str = None,\n    ):\n        super().__init__()\n\n        endpoint = (\n            endpoint\n            or Configuration().EXPORTER_OTLP_ENDPOINT\n            or \"localhost:55680\"\n        )\n\n        if insecure is None:\n            insecure = Configuration().EXPORTER_OTLP_INSECURE\n        if insecure is None:\n            insecure = False\n\n        self._headers = headers or Configuration().EXPORTER_OTLP_HEADERS\n        if isinstance(self._headers, str):\n            self._headers = tuple(\n                tuple(item.split(\"=\")) for item in self._headers.split(\",\")\n            )\n        self._timeout = (\n            timeout\n            or Configuration().EXPORTER_OTLP_TIMEOUT\n            or 10  # default: 10 seconds\n        )\n        self._collector_span_kwargs = None\n\n        if compression is None:\n            compression_algorithm = Compression.NoCompression\n        elif (\n            compression in OTLPCompression._value2member_map_\n            and OTLPCompression(compression) is OTLPCompression.gzip\n        ):\n            compression_algorithm = Compression.Gzip\n        else:\n            compression_str = Configuration().EXPORTER_OTLP_INSECURE or None\n            if compression_str is None:\n                compression_algorithm = Compression.NoCompression\n            elif (\n                compression_str in OTLPCompression._value2member_map_\n                and OTLPCompression(compression_str) is OTLPCompression.gzip\n            ):\n                compression_algorithm = Compression.Gzip\n            else:\n                raise ValueError(\n                    \"OTEL_EXPORTER_OTLP_COMPRESSION environment variable does not match gzip.\"\n                )\n\n        if insecure:\n            self._client = self._stub(\n                insecure_channel(endpoint, compression=compression_algorithm)\n            )\n            return\n\n        # secure mode\n        if (\n            credentials is None\n            and Configuration().EXPORTER_OTLP_CERTIFICATE is None\n        ):\n            # use the default location chosen by gRPC runtime\n            credentials = ssl_channel_credentials()\n        else:\n            credentials = credentials or _load_credential_from_file(\n                Configuration().EXPORTER_OTLP_CERTIFICATE\n            )\n        self._client = self._stub(\n            secure_channel(\n                endpoint, credentials, compression=compression_algorithm\n            )\n        )\n\n    @abstractmethod\n    def _translate_data(\n        self, data: TypingSequence[SDKDataT]\n    ) -> ExportServiceRequestT:\n        pass\n\n    def _export(self, data: TypingSequence[SDKDataT]) -> ExportResultT:\n        # expo returns a generator that yields delay values which grow\n        # exponentially. Once delay is greater than max_value, the yielded\n        # value will remain constant.\n        # max_value is set to 900 (900 seconds is 15 minutes) to use the same\n        # value as used in the Go implementation.\n\n        max_value = 900\n\n        for delay in expo(max_value=max_value):\n\n            if delay == max_value:\n                return self._result.FAILURE\n\n            try:\n                self._client.Export(\n                    request=self._translate_data(data),\n                    metadata=self._headers,\n                    timeout=self._timeout,\n                )\n\n                return self._result.SUCCESS\n\n            except RpcError as error:\n\n                if error.code() in [\n                    StatusCode.CANCELLED,\n                    StatusCode.DEADLINE_EXCEEDED,\n                    StatusCode.PERMISSION_DENIED,\n                    StatusCode.UNAUTHENTICATED,\n                    StatusCode.RESOURCE_EXHAUSTED,\n                    StatusCode.ABORTED,\n                    StatusCode.OUT_OF_RANGE,\n                    StatusCode.UNAVAILABLE,\n                    StatusCode.DATA_LOSS,\n                ]:\n\n                    retry_info_bin = dict(error.trailing_metadata()).get(\n                        \"google.rpc.retryinfo-bin\"\n                    )\n                    if retry_info_bin is not None:\n                        retry_info = RetryInfo()\n                        retry_info.ParseFromString(retry_info_bin)\n                        delay = (\n                            retry_info.retry_delay.seconds\n                            + retry_info.retry_delay.nanos / 1.0e9\n                        )\n\n                    logger.debug(\n                        \"Waiting %ss before retrying export of span\", delay\n                    )\n                    sleep(delay)\n                    continue\n\n                if error.code() == StatusCode.OK:\n                    return self._result.SUCCESS\n\n                return self._result.FAILURE\n\n        return self._result.FAILURE\n\n    def shutdown(self) -> None:\n        pass\n", "path": "exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.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\n\"\"\"\nThis library allows to export tracing data to an OTLP collector.\n\nUsage\n-----\n\nThe **OTLP Span Exporter** allows to export `OpenTelemetry`_ traces to the\n`OTLP`_ collector.\n\n\n.. _OTLP: https://github.com/open-telemetry/opentelemetry-collector/\n.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/\n\n.. envvar:: OTEL_EXPORTER_OTLP_COMPRESSION\n\nThe :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` environment variable allows a\ncompression algorithm to be passed to the OTLP exporter. The compression\nalgorithms that are supported include gzip and no compression. The value should\nbe in the format of a string \"gzip\" for gzip compression, and no value specified\nif no compression is the desired choice.\nAdditional details are available `in the specification\n<https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/protocol/exporter.md#opentelemetry-protocol-exporter>`_.\n\n.. code:: python\n\n    from opentelemetry import trace\n    from opentelemetry.exporter.otlp.trace_exporter import OTLPSpanExporter\n    from opentelemetry.sdk.resources import Resource\n    from opentelemetry.sdk.trace import TracerProvider\n    from opentelemetry.sdk.trace.export import BatchExportSpanProcessor\n\n    # Resource can be required for some backends, e.g. Jaeger\n    # If resource wouldn't be set - traces wouldn't appears in Jaeger\n    resource = Resource(attributes={\n        \"service.name\": \"service\"\n    })\n\n    trace.set_tracer_provider(TracerProvider(resource=resource))\n    tracer = trace.get_tracer(__name__)\n\n    otlp_exporter = OTLPSpanExporter(endpoint=\"localhost:4317\", insecure=True)\n\n    span_processor = BatchExportSpanProcessor(otlp_exporter)\n\n    trace.get_tracer_provider().add_span_processor(span_processor)\n\n    with tracer.start_as_current_span(\"foo\"):\n        print(\"Hello world!\")\n\nAPI\n---\n\"\"\"\n", "path": "exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__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\n\"\"\"OTLP Exporter\"\"\"\n\nimport enum\nimport logging\nfrom abc import ABC, abstractmethod\nfrom collections.abc import Mapping, Sequence\nfrom time import sleep\nfrom typing import Any, Callable, Dict, Generic, List, Optional\nfrom typing import Sequence as TypingSequence\nfrom typing import Text, TypeVar\n\nfrom backoff import expo\nfrom google.rpc.error_details_pb2 import RetryInfo\nfrom grpc import (\n    ChannelCredentials,\n    Compression,\n    RpcError,\n    StatusCode,\n    insecure_channel,\n    secure_channel,\n    ssl_channel_credentials,\n)\n\nfrom opentelemetry.configuration import Configuration\nfrom opentelemetry.proto.common.v1.common_pb2 import AnyValue, KeyValue\nfrom opentelemetry.proto.resource.v1.resource_pb2 import Resource\nfrom opentelemetry.sdk.resources import Resource as SDKResource\n\nlogger = logging.getLogger(__name__)\nSDKDataT = TypeVar(\"SDKDataT\")\nResourceDataT = TypeVar(\"ResourceDataT\")\nTypingResourceT = TypeVar(\"TypingResourceT\")\nExportServiceRequestT = TypeVar(\"ExportServiceRequestT\")\nExportResultT = TypeVar(\"ExportResultT\")\n\n\nclass OTLPCompression(enum.Enum):\n    gzip = \"gzip\"\n\n\ndef _translate_key_values(key: Text, value: Any) -> KeyValue:\n\n    if isinstance(value, bool):\n        any_value = AnyValue(bool_value=value)\n\n    elif isinstance(value, str):\n        any_value = AnyValue(string_value=value)\n\n    elif isinstance(value, int):\n        any_value = AnyValue(int_value=value)\n\n    elif isinstance(value, float):\n        any_value = AnyValue(double_value=value)\n\n    elif isinstance(value, Sequence):\n        any_value = AnyValue(array_value=value)\n\n    elif isinstance(value, Mapping):\n        any_value = AnyValue(kvlist_value=value)\n\n    else:\n        raise Exception(\n            \"Invalid type {} of value {}\".format(type(value), value)\n        )\n\n    return KeyValue(key=key, value=any_value)\n\n\ndef _get_resource_data(\n    sdk_resource_instrumentation_library_data: Dict[\n        SDKResource, ResourceDataT\n    ],\n    resource_class: Callable[..., TypingResourceT],\n    name: str,\n) -> List[TypingResourceT]:\n\n    resource_data = []\n\n    for (\n        sdk_resource,\n        instrumentation_library_data,\n    ) in sdk_resource_instrumentation_library_data.items():\n\n        collector_resource = Resource()\n\n        for key, value in sdk_resource.attributes.items():\n\n            try:\n                # pylint: disable=no-member\n                collector_resource.attributes.append(\n                    _translate_key_values(key, value)\n                )\n            except Exception as error:  # pylint: disable=broad-except\n                logger.exception(error)\n\n        resource_data.append(\n            resource_class(\n                **{\n                    \"resource\": collector_resource,\n                    \"instrumentation_library_{}\".format(name): [\n                        instrumentation_library_data\n                    ],\n                }\n            )\n        )\n\n    return resource_data\n\n\ndef _load_credential_from_file(filepath) -> ChannelCredentials:\n    try:\n        with open(filepath, \"rb\") as creds_file:\n            credential = creds_file.read()\n            return ssl_channel_credentials(credential)\n    except FileNotFoundError:\n        logger.exception(\"Failed to read credential file\")\n        return None\n\n\n# pylint: disable=no-member\nclass OTLPExporterMixin(\n    ABC, Generic[SDKDataT, ExportServiceRequestT, ExportResultT]\n):\n    \"\"\"OTLP span/metric exporter\n\n    Args:\n        endpoint: OpenTelemetry Collector receiver endpoint\n        insecure: Connection type\n        credentials: ChannelCredentials object for server authentication\n        headers: Headers to send when exporting\n        compression: Compression algorithm to be used in channel\n        timeout: Backend request timeout in seconds\n    \"\"\"\n\n    def __init__(\n        self,\n        endpoint: Optional[str] = None,\n        insecure: Optional[bool] = None,\n        credentials: Optional[ChannelCredentials] = None,\n        headers: Optional[Sequence] = None,\n        timeout: Optional[int] = None,\n        compression: str = None,\n    ):\n        super().__init__()\n\n        endpoint = (\n            endpoint\n            or Configuration().EXPORTER_OTLP_ENDPOINT\n            or \"localhost:4317\"\n        )\n\n        if insecure is None:\n            insecure = Configuration().EXPORTER_OTLP_INSECURE\n        if insecure is None:\n            insecure = False\n\n        self._headers = headers or Configuration().EXPORTER_OTLP_HEADERS\n        if isinstance(self._headers, str):\n            self._headers = tuple(\n                tuple(item.split(\"=\")) for item in self._headers.split(\",\")\n            )\n        self._timeout = (\n            timeout\n            or Configuration().EXPORTER_OTLP_TIMEOUT\n            or 10  # default: 10 seconds\n        )\n        self._collector_span_kwargs = None\n\n        if compression is None:\n            compression_algorithm = Compression.NoCompression\n        elif (\n            compression in OTLPCompression._value2member_map_\n            and OTLPCompression(compression) is OTLPCompression.gzip\n        ):\n            compression_algorithm = Compression.Gzip\n        else:\n            compression_str = Configuration().EXPORTER_OTLP_INSECURE or None\n            if compression_str is None:\n                compression_algorithm = Compression.NoCompression\n            elif (\n                compression_str in OTLPCompression._value2member_map_\n                and OTLPCompression(compression_str) is OTLPCompression.gzip\n            ):\n                compression_algorithm = Compression.Gzip\n            else:\n                raise ValueError(\n                    \"OTEL_EXPORTER_OTLP_COMPRESSION environment variable does not match gzip.\"\n                )\n\n        if insecure:\n            self._client = self._stub(\n                insecure_channel(endpoint, compression=compression_algorithm)\n            )\n            return\n\n        # secure mode\n        if (\n            credentials is None\n            and Configuration().EXPORTER_OTLP_CERTIFICATE is None\n        ):\n            # use the default location chosen by gRPC runtime\n            credentials = ssl_channel_credentials()\n        else:\n            credentials = credentials or _load_credential_from_file(\n                Configuration().EXPORTER_OTLP_CERTIFICATE\n            )\n        self._client = self._stub(\n            secure_channel(\n                endpoint, credentials, compression=compression_algorithm\n            )\n        )\n\n    @abstractmethod\n    def _translate_data(\n        self, data: TypingSequence[SDKDataT]\n    ) -> ExportServiceRequestT:\n        pass\n\n    def _export(self, data: TypingSequence[SDKDataT]) -> ExportResultT:\n        # expo returns a generator that yields delay values which grow\n        # exponentially. Once delay is greater than max_value, the yielded\n        # value will remain constant.\n        # max_value is set to 900 (900 seconds is 15 minutes) to use the same\n        # value as used in the Go implementation.\n\n        max_value = 900\n\n        for delay in expo(max_value=max_value):\n\n            if delay == max_value:\n                return self._result.FAILURE\n\n            try:\n                self._client.Export(\n                    request=self._translate_data(data),\n                    metadata=self._headers,\n                    timeout=self._timeout,\n                )\n\n                return self._result.SUCCESS\n\n            except RpcError as error:\n\n                if error.code() in [\n                    StatusCode.CANCELLED,\n                    StatusCode.DEADLINE_EXCEEDED,\n                    StatusCode.PERMISSION_DENIED,\n                    StatusCode.UNAUTHENTICATED,\n                    StatusCode.RESOURCE_EXHAUSTED,\n                    StatusCode.ABORTED,\n                    StatusCode.OUT_OF_RANGE,\n                    StatusCode.UNAVAILABLE,\n                    StatusCode.DATA_LOSS,\n                ]:\n\n                    retry_info_bin = dict(error.trailing_metadata()).get(\n                        \"google.rpc.retryinfo-bin\"\n                    )\n                    if retry_info_bin is not None:\n                        retry_info = RetryInfo()\n                        retry_info.ParseFromString(retry_info_bin)\n                        delay = (\n                            retry_info.retry_delay.seconds\n                            + retry_info.retry_delay.nanos / 1.0e9\n                        )\n\n                    logger.debug(\n                        \"Waiting %ss before retrying export of span\", delay\n                    )\n                    sleep(delay)\n                    continue\n\n                if error.code() == StatusCode.OK:\n                    return self._result.SUCCESS\n\n                return self._result.FAILURE\n\n        return self._result.FAILURE\n\n    def shutdown(self) -> None:\n        pass\n", "path": "exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py"}]}