We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
opentelemetry-instrument errors by default
**Describe your environment** 
Testing out the latest version of `opentelemetry-instrument` with python 3.8.1

**Steps to reproduce**
```
opentelemetry-instrument python
```

**What is the expected behavior?**
Based on the previous behaviour, I was expecting no error to be displayed

**What is the actual behavior?**
```
Failed to auto initialize opentelemetry
...
ValueError: No credentials set in secure mode.
```

**Additional context**
The underlying problem is the default of using the OTLP exporter requires me to setup an environment variable for a certificate which I have no knowledge of prior to using this tool. This is really confusing.


--- 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/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 f:
127             credential = f.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[str] = 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         self._timeout = (
173             timeout
174             or Configuration().EXPORTER_OTLP_TIMEOUT
175             or 10  # default: 10 seconds
176         )
177         self._collector_span_kwargs = None
178 
179         if compression is None:
180             compression_algorithm = Compression.NoCompression
181         elif (
182             compression in OTLPCompression._value2member_map_
183             and OTLPCompression(compression) is OTLPCompression.gzip
184         ):
185             compression_algorithm = Compression.Gzip
186         else:
187             compression_str = Configuration().EXPORTER_OTLP_INSECURE or None
188             if compression_str is None:
189                 compression_algorithm = Compression.NoCompression
190             elif (
191                 compression_str in OTLPCompression._value2member_map_
192                 and OTLPCompression(compression_str) is OTLPCompression.gzip
193             ):
194                 compression_algorithm = Compression.Gzip
195             else:
196                 raise ValueError(
197                     "OTEL_EXPORTER_OTLP_COMPRESSION environment variable does not match gzip."
198                 )
199 
200         if insecure:
201             self._client = self._stub(
202                 insecure_channel(endpoint, compression=compression_algorithm)
203             )
204             return
205 
206         # secure mode
207         if (
208             credentials is None
209             and Configuration().EXPORTER_OTLP_CERTIFICATE is None
210         ):
211             raise ValueError("No credentials set in secure mode.")
212 
213         credentials = credentials or _load_credential_from_file(
214             Configuration().EXPORTER_OTLP_CERTIFICATE
215         )
216         self._client = self._stub(
217             secure_channel(
218                 endpoint, credentials, compression=compression_algorithm
219             )
220         )
221 
222     @abstractmethod
223     def _translate_data(
224         self, data: TypingSequence[SDKDataT]
225     ) -> ExportServiceRequestT:
226         pass
227 
228     def _export(self, data: TypingSequence[SDKDataT]) -> ExportResultT:
229         # expo returns a generator that yields delay values which grow
230         # exponentially. Once delay is greater than max_value, the yielded
231         # value will remain constant.
232         # max_value is set to 900 (900 seconds is 15 minutes) to use the same
233         # value as used in the Go implementation.
234 
235         max_value = 900
236 
237         for delay in expo(max_value=max_value):
238 
239             if delay == max_value:
240                 return self._result.FAILURE
241 
242             try:
243                 self._client.Export(
244                     request=self._translate_data(data),
245                     metadata=self._headers,
246                     timeout=self._timeout,
247                 )
248 
249                 return self._result.SUCCESS
250 
251             except RpcError as error:
252 
253                 if error.code() in [
254                     StatusCode.CANCELLED,
255                     StatusCode.DEADLINE_EXCEEDED,
256                     StatusCode.PERMISSION_DENIED,
257                     StatusCode.UNAUTHENTICATED,
258                     StatusCode.RESOURCE_EXHAUSTED,
259                     StatusCode.ABORTED,
260                     StatusCode.OUT_OF_RANGE,
261                     StatusCode.UNAVAILABLE,
262                     StatusCode.DATA_LOSS,
263                 ]:
264 
265                     retry_info_bin = dict(error.trailing_metadata()).get(
266                         "google.rpc.retryinfo-bin"
267                     )
268                     if retry_info_bin is not None:
269                         retry_info = RetryInfo()
270                         retry_info.ParseFromString(retry_info_bin)
271                         delay = (
272                             retry_info.retry_delay.seconds
273                             + retry_info.retry_delay.nanos / 1.0e9
274                         )
275 
276                     logger.debug(
277                         "Waiting %ss before retrying export of span", delay
278                     )
279                     sleep(delay)
280                     continue
281 
282                 if error.code() == StatusCode.OK:
283                     return self._result.SUCCESS
284 
285                 return self._result.FAILURE
286 
287         return self._result.FAILURE
288 
289     def shutdown(self) -> None:
290         pass
291
```
--- 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/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
@@ -208,11 +208,12 @@
             credentials is None
             and Configuration().EXPORTER_OTLP_CERTIFICATE is None
         ):
-            raise ValueError("No credentials set in secure mode.")
-
-        credentials = credentials or _load_credential_from_file(
-            Configuration().EXPORTER_OTLP_CERTIFICATE
-        )
+            # use the default location chosen by gRPC runtime
+            credentials = ssl_channel_credentials()
+        else:
+            credentials = credentials or _load_credential_from_file(
+                Configuration().EXPORTER_OTLP_CERTIFICATE
+            )
         self._client = self._stub(
             secure_channel(
                 endpoint, credentials, compression=compression_algorithm

{"golden_diff": "diff --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@@ -208,11 +208,12 @@\n             credentials is None\n             and Configuration().EXPORTER_OTLP_CERTIFICATE is None\n         ):\n-            raise ValueError(\"No credentials set in secure mode.\")\n-\n-        credentials = credentials or _load_credential_from_file(\n-            Configuration().EXPORTER_OTLP_CERTIFICATE\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", "issue": "opentelemetry-instrument errors by default\n**Describe your environment** \r\nTesting out the latest version of `opentelemetry-instrument` with python 3.8.1\r\n\r\n**Steps to reproduce**\r\n```\r\nopentelemetry-instrument python\r\n```\r\n\r\n**What is the expected behavior?**\r\nBased on the previous behaviour, I was expecting no error to be displayed\r\n\r\n**What is the actual behavior?**\r\n```\r\nFailed to auto initialize opentelemetry\r\n...\r\nValueError: No credentials set in secure mode.\r\n```\r\n\r\n**Additional context**\r\nThe underlying problem is the default of using the OTLP exporter requires me to setup an environment variable for a certificate which I have no knowledge of prior to using this tool. This is really confusing.\r\n\n", "before_files": [{"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"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 f:\n            credential = f.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[str] = 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        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            raise ValueError(\"No credentials set in secure mode.\")\n\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\"\"\"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 f:\n            credential = f.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[str] = 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        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"}]}