otlp-json 0.9.2__tar.gz → 0.9.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: otlp-json
3
- Version: 0.9.2
3
+ Version: 0.9.4
4
4
  Summary: 🐍Lightweight OTEL span to JSON converter, no dependencies, pure Python🐍
5
5
  Project-URL: Repository, https://github.com/dimaqq/otlp-json
6
6
  Project-URL: Issues, https://github.com/dimaqq/otlp-json/issues
@@ -7,6 +7,8 @@ from typing import Any, TYPE_CHECKING
7
7
  if TYPE_CHECKING:
8
8
  from typing_extensions import TypeAlias
9
9
 
10
+ from opentelemetry.trace import Link
11
+ from opentelemetry._logs import LogRecord
10
12
  from opentelemetry.sdk.trace import ReadableSpan, Event
11
13
  from opentelemetry.sdk.resources import Resource
12
14
  from opentelemetry.sdk.util.instrumentation import InstrumentationScope
@@ -66,26 +68,27 @@ def encode_spans(spans: Sequence[ReadableSpan]) -> bytes:
66
68
 
67
69
 
68
70
  def _resource(resource: Resource):
69
- rv = {"attributes": []}
70
- for k, v in resource.attributes.items():
71
+ # TODO: add schema_url once that lands in opentelemetry-sdk
72
+ return _attributes(resource)
73
+
74
+
75
+ def _attributes(
76
+ thing: Resource | InstrumentationScope | ReadableSpan | Event | Link | LogRecord,
77
+ ) -> dict[str, Any]:
78
+ rv = {"attributes": [], "dropped_attributes_count": 0}
79
+
80
+ assert thing.attributes is not None
81
+ for k, v in thing.attributes.items():
71
82
  try:
72
83
  rv["attributes"].append({"key": k, "value": _value(v)})
73
84
  except ValueError:
74
85
  pass
75
86
 
76
- # NOTE: blocks that contain droppedAttributesCount:
77
- # - Event
78
- # - Link
79
- # - InstrumentationScope
80
- # - LogRecord (out of scope for this library)
81
- # - Resource
82
- rv["dropped_attributes_count"] = len(resource.attributes) - len(rv["attributes"]) # type: ignore
87
+ rv["dropped_attributes_count"] = len(thing.attributes) - len(rv["attributes"]) # type: ignore
83
88
 
84
- if not rv["attributes"]:
85
- del rv["attributes"]
86
-
87
- if not rv["dropped_attributes_count"]:
88
- del rv["dropped_attributes_count"]
89
+ for k in ("attributes", "dropped_attributes_count"):
90
+ if not rv[k]:
91
+ del rv[k]
89
92
 
90
93
  return rv
91
94
 
@@ -99,8 +102,9 @@ def _homogeneous_array(value: list[_LEAF_VALUE]) -> list[_LEAF_VALUE]:
99
102
 
100
103
  def _value(value: _VALUE) -> dict[str, Any]:
101
104
  # Attribute value can be a primitive type, excluging None...
102
- # TODO: protobuf allows bytes, but I think OTLP doesn't.
103
- # TODO: protobuf allows k:v pairs, but I think OTLP doesn't.
105
+ # protobuf allows bytes, but I think OTLP spec does not?
106
+ # protobuf allows k:v pairs, but I think OTLP doesn't.
107
+ # TODO: read up the spec and validate the allowed type range.
104
108
  for klass, (key, post) in _VALUE_TYPES.items():
105
109
  if isinstance(value, klass):
106
110
  return {key: post(value)}
@@ -109,7 +113,10 @@ def _value(value: _VALUE) -> dict[str, Any]:
109
113
 
110
114
 
111
115
  def _scope(scope: InstrumentationScope):
112
- rv = {"name": scope.name}
116
+ rv = {
117
+ "name": scope.name,
118
+ **_attributes(scope),
119
+ }
113
120
  if scope.version:
114
121
  rv["version"] = scope.version
115
122
  return rv
@@ -123,29 +130,16 @@ def _span(span: ReadableSpan):
123
130
  "traceId": _trace_id(span.context.trace_id),
124
131
  "spanId": _span_id(span.context.span_id),
125
132
  "flags": 0x100 | ([0, 0x200][bool(span.parent and span.parent.is_remote)]),
126
- "startTimeUnixNano": str(span.start_time), # TODO: is it ever optional?
127
- "endTimeUnixNano": str(span.end_time), # -"-
133
+ "startTimeUnixNano": str(span.start_time),
134
+ "endTimeUnixNano": str(span.end_time), # can this be unset?
128
135
  "status": _status(span.status),
129
- "attributes": [],
136
+ **_attributes(span),
130
137
  }
131
138
 
132
139
  if span.parent:
133
140
  rv["parentSpanId"] = _span_id(span.parent.span_id)
134
141
 
135
- for k, v in span.attributes.items(): # type: ignore
136
- try:
137
- rv["attributes"].append({"key": k, "value": _value(v)})
138
- except ValueError:
139
- pass
140
-
141
- rv["dropped_attributes_count"] = len(span.attributes) - len(rv["attributes"]) # type: ignore
142
-
143
- if not rv["attributes"]:
144
- del rv["attributes"]
145
-
146
- if not rv["dropped_attributes_count"]:
147
- del rv["dropped_attributes_count"]
148
-
142
+ # TODO: is this field really nullable?
149
143
  if span.events:
150
144
  rv["events"] = [_event(e) for e in span.events]
151
145
 
@@ -165,7 +159,7 @@ def _span_id(span_id: int) -> str:
165
159
 
166
160
 
167
161
  def _status(status: Status) -> dict[str, Any]:
168
- # FIXME
162
+ # FIXME: need an example of bad status
169
163
  return {}
170
164
 
171
165
 
@@ -173,21 +167,7 @@ def _event(event: Event) -> dict[str, Any]:
173
167
  rv = {
174
168
  "name": event.name,
175
169
  "timeUnixNano": str(event.timestamp),
176
- "attributes": [],
170
+ **_attributes(event),
177
171
  }
178
-
179
- for k, v in event.attributes.items(): # type: ignore
180
- try:
181
- rv["attributes"].append({"key": k, "value": _value(v)})
182
- except ValueError:
183
- pass
184
-
185
- rv["dropped_attributes_count"] = len(event.attributes) - len(rv["attributes"]) # type: ignore
186
-
187
- if not rv["attributes"]:
188
- del rv["attributes"]
189
-
190
- if not rv["dropped_attributes_count"]:
191
- del rv["dropped_attributes_count"]
192
-
172
+ # TODO: any optional attributes?
193
173
  return rv
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "otlp-json"
3
- version = "0.9.2"
3
+ version = "0.9.4"
4
4
  description = "🐍Lightweight OTEL span to JSON converter, no dependencies, pure Python🐍"
5
5
  requires-python = ">=3.8"
6
6
  # https://github.com/astral-sh/uv/issues/4204
@@ -374,7 +374,7 @@ wheels = [
374
374
 
375
375
  [[package]]
376
376
  name = "otlp-json"
377
- version = "0.9.2"
377
+ version = "0.9.3"
378
378
  source = { editable = "." }
379
379
 
380
380
  [package.dev-dependencies]
@@ -405,7 +405,7 @@ testing = [
405
405
 
406
406
  [[package]]
407
407
  name = "otlp-test-data"
408
- version = "0.11.0"
408
+ version = "0.11.2"
409
409
  source = { registry = "https://pypi.org/simple" }
410
410
  dependencies = [
411
411
  { name = "freezegun" },
@@ -414,9 +414,9 @@ dependencies = [
414
414
  { name = "opentelemetry-exporter-otlp" },
415
415
  { name = "opentelemetry-exporter-otlp-proto-http" },
416
416
  ]
417
- sdist = { url = "https://files.pythonhosted.org/packages/70/c9/bb8de92ae3eea7ba501e38661270d505ec094453fcfaa6d4aa1da120fc8f/otlp_test_data-0.11.0.tar.gz", hash = "sha256:01855e4d84afa76a33457594c30023b1e33accdcf8aaef4611159274f2dd66c3", size = 37638 }
417
+ sdist = { url = "https://files.pythonhosted.org/packages/df/d7/21bed69e7f201abbdb27bf84bea1a02f65991efc60d88aaeb4001c9069ad/otlp_test_data-0.11.2.tar.gz", hash = "sha256:6be622eaa675e08568d140ce0863f0dfbf3eeb7dd1b567d66633ddd79d4d9632", size = 37707 }
418
418
  wheels = [
419
- { url = "https://files.pythonhosted.org/packages/28/b3/464748f40e489fc335c2d01147c0cbbe19eb2ec2ab95bdb6b33b74649ea4/otlp_test_data-0.11.0-py3-none-any.whl", hash = "sha256:254955385a4ee1fc30b8514c08600f65b8b7dca55073b6cbdca555c02c533e8b", size = 3373 },
419
+ { url = "https://files.pythonhosted.org/packages/4c/62/462acb3181f178832c286e8b6f9787a6983dd5bdd9588564624a861db837/otlp_test_data-0.11.2-py3-none-any.whl", hash = "sha256:419190181f221d611d24dba8850e980d69bc7e1195bd36f0c4e5ec6a3bcdcc7e", size = 3584 },
420
420
  ]
421
421
 
422
422
  [[package]]
@@ -457,15 +457,15 @@ wheels = [
457
457
 
458
458
  [[package]]
459
459
  name = "pyright"
460
- version = "1.1.394"
460
+ version = "1.1.395"
461
461
  source = { registry = "https://pypi.org/simple" }
462
462
  dependencies = [
463
463
  { name = "nodeenv" },
464
464
  { name = "typing-extensions" },
465
465
  ]
466
- sdist = { url = "https://files.pythonhosted.org/packages/b1/e4/79f4d8a342eed6790fdebdb500e95062f319ee3d7d75ae27304ff995ae8c/pyright-1.1.394.tar.gz", hash = "sha256:56f2a3ab88c5214a451eb71d8f2792b7700434f841ea219119ade7f42ca93608", size = 3809348 }
466
+ sdist = { url = "https://files.pythonhosted.org/packages/fb/47/a2e1dfd70f9f0db34f70d5b108c82be57bf24185af69c95acff57f9239fa/pyright-1.1.395.tar.gz", hash = "sha256:53703169068c160bfb41e1b44ba3e2512492869c26cfad927e1268cb3fbb1b1c", size = 3813566 }
467
467
  wheels = [
468
- { url = "https://files.pythonhosted.org/packages/d6/4c/50c74e3d589517a9712a61a26143b587dba6285434a17aebf2ce6b82d2c3/pyright-1.1.394-py3-none-any.whl", hash = "sha256:5f74cce0a795a295fb768759bbeeec62561215dea657edcaab48a932b031ddbb", size = 5679540 },
468
+ { url = "https://files.pythonhosted.org/packages/5f/a1/531897f8caa6c6cc99862cd1c908ddd8a366a51d968e83ab4523ded98b30/pyright-1.1.395-py3-none-any.whl", hash = "sha256:f9bc726870e740c6c77c94657734d90563a3e9765bb523b39f5860198ed75eef", size = 5688787 },
469
469
  ]
470
470
 
471
471
  [[package]]
File without changes
File without changes
File without changes