Skip to content

Commit 820ed1c

Browse files
committed
refactor: value type dispatch
1 parent 46f8c91 commit 820ed1c

File tree

3 files changed

+27
-31
lines changed

3 files changed

+27
-31
lines changed

otlp_json/__init__.py

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,12 @@
1818
_VALUE: TypeAlias = "_LEAF_VALUE | Sequence[_LEAF_VALUE]"
1919

2020

21-
CONTENT_TYPE = "application/json"
22-
21+
__all__ = [
22+
"CONTENT_TYPE",
23+
"encode_spans",
24+
]
2325

24-
_VALUE_TYPES = {
25-
# NOTE: order matters, for isinstance(True, int).
26-
bool: ("boolValue", bool),
27-
int: ("intValue", str),
28-
float: ("doubleValue", float),
29-
bytes: ("bytesValue", bytes),
30-
str: ("stringValue", str),
31-
Sequence: (
32-
"arrayValue",
33-
lambda value: {"values": [_value(e) for e in _homogeneous_array(value)]},
34-
),
35-
Mapping: (
36-
"kvlistValue",
37-
lambda value: {"values": [{k: _value(v) for k, v in value.items()}]},
38-
),
39-
}
26+
CONTENT_TYPE = "application/json"
4027

4128

4229
def encode_spans(spans: Sequence[ReadableSpan]) -> bytes:
@@ -93,23 +80,32 @@ def _attributes(
9380
return rv
9481

9582

96-
def _homogeneous_array(value: list[_LEAF_VALUE]) -> list[_LEAF_VALUE]:
83+
def _ensure_homogeneous(value: Sequence[_LEAF_VALUE]) -> Sequence[_LEAF_VALUE]:
9784
# TODO: empty lists are allowed, aren't they?
9885
if len(types := {type(v) for v in value}) > 1:
9986
raise ValueError(f"Attribute value arrays must be homogeneous, got {types=}")
10087
return value
10188

10289

103-
def _value(value: _VALUE) -> dict[str, Any]:
104-
# Attribute value can be a primitive type, excluging None...
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.
108-
for klass, (key, post) in _VALUE_TYPES.items():
109-
if isinstance(value, klass):
110-
return {key: post(value)}
111-
112-
raise ValueError(f"Cannot convert attribute of {type(value)=}")
90+
def _value(v: _VALUE) -> dict[str, Any]:
91+
if isinstance(v, bool):
92+
return {"boolValue": bool(v)}
93+
if isinstance(v, int):
94+
return {"intValue": str(int(v))}
95+
if isinstance(v, float):
96+
return {"doubleValue": float(v)}
97+
if isinstance(v, bytes):
98+
return {
99+
"bytesValue": bytes(v)
100+
} # FIXME this can't be right; gotta encode this somehow
101+
if isinstance(v, str):
102+
return {"stringValue": str(v)}
103+
if isinstance(v, Sequence):
104+
return {"arrayValue": {"values": [_value(e) for e in _ensure_homogeneous(v)]}}
105+
if isinstance(v, Mapping):
106+
return {"kvlistValue": {"values": [{k: _value(vv) for k, vv in v.items()}]}}
107+
108+
raise ValueError(f"Cannot convert attribute value of {type(v)=}")
113109

114110

115111
def _scope(scope: InstrumentationScope):

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "otlp-json"
3-
version = "0.9.4"
3+
version = "0.9.5"
44
description = "🐍Lightweight OTEL span to JSON converter, no dependencies, pure Python🐍"
55
requires-python = ">=3.8"
66
# https://github.com/astral-sh/uv/issues/4204

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)