Skip to content

Commit e8f5eb5

Browse files
authored
Add type hints to OTLP exporter (open-telemetry#1121)
1 parent b923c52 commit e8f5eb5

File tree

4 files changed

+72
-32
lines changed

4 files changed

+72
-32
lines changed

exporter/opentelemetry-exporter-otlp/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Released 2020-09-17
1010
([#1095](https://github.com/open-telemetry/opentelemetry-python/pull/1095))
1111
- Add metric OTLP exporter
1212
([#835](https://github.com/open-telemetry/opentelemetry-python/pull/835))
13+
- Add type hints to OTLP exporter
14+
([#1121](https://github.com/open-telemetry/opentelemetry-python/pull/1121))
1315

1416
## Version 0.12b0
1517

exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
from abc import ABC, abstractmethod
1919
from collections.abc import Mapping, Sequence
2020
from time import sleep
21+
from typing import Any, Callable, Dict, Generic, List, Optional
22+
from typing import Sequence as TypingSequence
23+
from typing import Text, Tuple, TypeVar
2124

2225
from backoff import expo
2326
from google.rpc.error_details_pb2 import RetryInfo
@@ -31,11 +34,17 @@
3134

3235
from opentelemetry.proto.common.v1.common_pb2 import AnyValue, KeyValue
3336
from opentelemetry.proto.resource.v1.resource_pb2 import Resource
37+
from opentelemetry.sdk.resources import Resource as SDKResource
3438

3539
logger = logging.getLogger(__name__)
40+
SDKDataT = TypeVar("SDKDataT")
41+
ResourceDataT = TypeVar("ResourceDataT")
42+
TypingResourceT = TypeVar("TypingResourceT")
43+
ExportServiceRequestT = TypeVar("ExportServiceRequestT")
44+
ExportResultT = TypeVar("ExportResultT")
3645

3746

38-
def _translate_key_values(key, value):
47+
def _translate_key_values(key: Text, value: Any) -> KeyValue:
3948

4049
if isinstance(value, bool):
4150
any_value = AnyValue(bool_value=value)
@@ -64,8 +73,12 @@ def _translate_key_values(key, value):
6473

6574

6675
def _get_resource_data(
67-
sdk_resource_instrumentation_library_data, resource_class, name
68-
):
76+
sdk_resource_instrumentation_library_data: Dict[
77+
SDKResource, ResourceDataT
78+
],
79+
resource_class: Callable[..., TypingResourceT],
80+
name: str,
81+
) -> List[TypingResourceT]:
6982

7083
resource_data = []
7184

@@ -101,7 +114,9 @@ def _get_resource_data(
101114

102115

103116
# pylint: disable=no-member
104-
class OTLPExporterMixin(ABC):
117+
class OTLPExporterMixin(
118+
ABC, Generic[SDKDataT, ExportServiceRequestT, ExportResultT]
119+
):
105120
"""OTLP span/metric exporter
106121
107122
Args:
@@ -114,7 +129,7 @@ def __init__(
114129
self,
115130
endpoint: str = "localhost:55680",
116131
credentials: ChannelCredentials = None,
117-
metadata: tuple = None,
132+
metadata: Optional[Tuple[Any]] = None,
118133
):
119134
super().__init__()
120135

@@ -127,10 +142,12 @@ def __init__(
127142
self._client = self._stub(secure_channel(endpoint, credentials))
128143

129144
@abstractmethod
130-
def _translate_data(self, data):
145+
def _translate_data(
146+
self, data: TypingSequence[SDKDataT]
147+
) -> ExportServiceRequestT:
131148
pass
132149

133-
def _export(self, data):
150+
def _export(self, data: TypingSequence[SDKDataT]) -> ExportResultT:
134151
# expo returns a generator that yields delay values which grow
135152
# exponentially. Once delay is greater than max_value, the yielded
136153
# value will remain constant.
@@ -190,5 +207,5 @@ def _export(self, data):
190207

191208
return self._result.FAILURE
192209

193-
def shutdown(self):
210+
def shutdown(self) -> None:
194211
pass

exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/metrics_exporter/__init__.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515
"""OTLP Metrics Exporter"""
1616

1717
import logging
18-
from typing import Sequence
18+
from typing import List, Sequence, Type, TypeVar, Union
1919

2020
# pylint: disable=duplicate-code
2121
from opentelemetry.exporter.otlp.exporter import (
2222
OTLPExporterMixin,
2323
_get_resource_data,
2424
)
25+
from opentelemetry.metrics import InstrumentT
2526
from opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import (
2627
ExportMetricsServiceRequest,
2728
)
@@ -41,24 +42,27 @@
4142
MetricDescriptor,
4243
ResourceMetrics,
4344
)
44-
from opentelemetry.sdk.metrics import Counter
45-
from opentelemetry.sdk.metrics import Metric as SDKMetric
4645
from opentelemetry.sdk.metrics import (
46+
Counter,
4747
SumObserver,
4848
UpDownCounter,
4949
UpDownSumObserver,
5050
ValueObserver,
5151
ValueRecorder,
5252
)
5353
from opentelemetry.sdk.metrics.export import (
54+
MetricRecord,
5455
MetricsExporter,
5556
MetricsExportResult,
5657
)
5758

5859
logger = logging.getLogger(__name__)
60+
DataPointT = TypeVar("DataPointT", Int64DataPoint, DoubleDataPoint)
5961

6062

61-
def _get_data_points(sdk_metric, data_point_class):
63+
def _get_data_points(
64+
sdk_metric: MetricRecord, data_point_class: Type[DataPointT]
65+
) -> List[DataPointT]:
6266

6367
data_points = []
6468

@@ -89,7 +93,9 @@ def _get_data_points(sdk_metric, data_point_class):
8993
return data_points
9094

9195

92-
def _get_temporality(instrument):
96+
def _get_temporality(
97+
instrument: InstrumentT,
98+
) -> "MetricDescriptor.TemporalityValue":
9399
# pylint: disable=no-member
94100
if isinstance(instrument, (Counter, UpDownCounter)):
95101
temporality = MetricDescriptor.Temporality.DELTA
@@ -107,12 +113,12 @@ def _get_temporality(instrument):
107113
return temporality
108114

109115

110-
def _get_type(value_type):
116+
def _get_type(value_type: Union[int, float]) -> "MetricDescriptor.TypeValue":
111117
# pylint: disable=no-member
112-
if value_type is int:
118+
if value_type is int: # type: ignore[comparison-overlap]
113119
type_ = MetricDescriptor.Type.INT64
114120

115-
elif value_type is float:
121+
elif value_type is float: # type: ignore[comparison-overlap]
116122
type_ = MetricDescriptor.Type.DOUBLE
117123

118124
# FIXME What are the types that correspond with
@@ -126,7 +132,13 @@ def _get_type(value_type):
126132
return type_
127133

128134

129-
class OTLPMetricsExporter(MetricsExporter, OTLPExporterMixin):
135+
class OTLPMetricsExporter(
136+
MetricsExporter,
137+
OTLPExporterMixin[
138+
MetricRecord, ExportMetricsServiceRequest, MetricsExportResult
139+
],
140+
):
141+
# pylint: disable=unsubscriptable-object
130142
"""OTLP metrics exporter
131143
132144
Args:
@@ -138,7 +150,9 @@ class OTLPMetricsExporter(MetricsExporter, OTLPExporterMixin):
138150
_stub = MetricsServiceStub
139151
_result = MetricsExportResult
140152

141-
def _translate_data(self, data):
153+
def _translate_data(
154+
self, data: Sequence[MetricRecord]
155+
) -> ExportMetricsServiceRequest:
142156
# pylint: disable=too-many-locals,no-member
143157
# pylint: disable=attribute-defined-outside-init
144158

@@ -193,6 +207,6 @@ def _translate_data(self, data):
193207
)
194208
)
195209

196-
def export(self, metrics: Sequence[SDKMetric]) -> MetricsExportResult:
210+
def export(self, metrics: Sequence[MetricRecord]) -> MetricsExportResult:
197211
# pylint: disable=arguments-differ
198212
return self._export(metrics)

exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@
4141

4242

4343
# pylint: disable=no-member
44-
class OTLPSpanExporter(SpanExporter, OTLPExporterMixin):
44+
class OTLPSpanExporter(
45+
SpanExporter,
46+
OTLPExporterMixin[SDKSpan, ExportTraceServiceRequest, SpanExportResult],
47+
):
48+
# pylint: disable=unsubscriptable-object
4549
"""OTLP span exporter
4650
4751
Args:
@@ -53,34 +57,34 @@ class OTLPSpanExporter(SpanExporter, OTLPExporterMixin):
5357
_result = SpanExportResult
5458
_stub = TraceServiceStub
5559

56-
def _translate_name(self, sdk_span):
60+
def _translate_name(self, sdk_span: SDKSpan) -> None:
5761
self._collector_span_kwargs["name"] = sdk_span.name
5862

59-
def _translate_start_time(self, sdk_span):
63+
def _translate_start_time(self, sdk_span: SDKSpan) -> None:
6064
self._collector_span_kwargs[
6165
"start_time_unix_nano"
6266
] = sdk_span.start_time
6367

64-
def _translate_end_time(self, sdk_span):
68+
def _translate_end_time(self, sdk_span: SDKSpan) -> None:
6569
self._collector_span_kwargs["end_time_unix_nano"] = sdk_span.end_time
6670

67-
def _translate_span_id(self, sdk_span):
71+
def _translate_span_id(self, sdk_span: SDKSpan) -> None:
6872
self._collector_span_kwargs[
6973
"span_id"
7074
] = sdk_span.context.span_id.to_bytes(8, "big")
7175

72-
def _translate_trace_id(self, sdk_span):
76+
def _translate_trace_id(self, sdk_span: SDKSpan) -> None:
7377
self._collector_span_kwargs[
7478
"trace_id"
7579
] = sdk_span.context.trace_id.to_bytes(16, "big")
7680

77-
def _translate_parent(self, sdk_span):
81+
def _translate_parent(self, sdk_span: SDKSpan) -> None:
7882
if sdk_span.parent is not None:
7983
self._collector_span_kwargs[
8084
"parent_span_id"
8185
] = sdk_span.parent.span_id.to_bytes(8, "big")
8286

83-
def _translate_context_trace_state(self, sdk_span):
87+
def _translate_context_trace_state(self, sdk_span: SDKSpan) -> None:
8488
if sdk_span.context.trace_state is not None:
8589
self._collector_span_kwargs["trace_state"] = ",".join(
8690
[
@@ -89,7 +93,7 @@ def _translate_context_trace_state(self, sdk_span):
8993
]
9094
)
9195

92-
def _translate_attributes(self, sdk_span):
96+
def _translate_attributes(self, sdk_span: SDKSpan) -> None:
9397
if sdk_span.attributes:
9498

9599
self._collector_span_kwargs["attributes"] = []
@@ -103,7 +107,7 @@ def _translate_attributes(self, sdk_span):
103107
except Exception as error: # pylint: disable=broad-except
104108
logger.exception(error)
105109

106-
def _translate_events(self, sdk_span):
110+
def _translate_events(self, sdk_span: SDKSpan) -> None:
107111
if sdk_span.events:
108112
self._collector_span_kwargs["events"] = []
109113

@@ -127,7 +131,7 @@ def _translate_events(self, sdk_span):
127131
collector_span_event
128132
)
129133

130-
def _translate_links(self, sdk_span):
134+
def _translate_links(self, sdk_span: SDKSpan) -> None:
131135
if sdk_span.links:
132136
self._collector_span_kwargs["links"] = []
133137

@@ -153,14 +157,17 @@ def _translate_links(self, sdk_span):
153157
collector_span_link
154158
)
155159

156-
def _translate_status(self, sdk_span):
160+
def _translate_status(self, sdk_span: SDKSpan) -> None:
157161
if sdk_span.status is not None:
158162
self._collector_span_kwargs["status"] = Status(
159163
code=sdk_span.status.canonical_code.value,
160164
message=sdk_span.status.description,
161165
)
162166

163-
def _translate_data(self, data) -> ExportTraceServiceRequest:
167+
def _translate_data(
168+
self, data: Sequence[SDKSpan]
169+
) -> ExportTraceServiceRequest:
170+
# pylint: disable=attribute-defined-outside-init
164171

165172
sdk_resource_instrumentation_library_spans = {}
166173

0 commit comments

Comments
 (0)