(
keep_span_id: bool = False, keep_trace_id: bool = False
)
| 94 | |
| 95 | |
| 96 | def fetch_normalized_spans( |
| 97 | keep_span_id: bool = False, keep_trace_id: bool = False |
| 98 | ) -> list[dict[str, Any]]: |
| 99 | nodes: dict[tuple[str, str | None], dict[str, Any]] = {} |
| 100 | traces = [] |
| 101 | for trace_obj in fetch_traces(): |
| 102 | trace = trace_obj.export() |
| 103 | assert trace |
| 104 | assert trace.pop("object") == "trace" |
| 105 | assert trace["id"].startswith("trace_") |
| 106 | if not keep_trace_id: |
| 107 | del trace["id"] |
| 108 | trace = {k: v for k, v in trace.items() if v is not None} |
| 109 | nodes[(trace_obj.trace_id, None)] = trace |
| 110 | traces.append(trace) |
| 111 | |
| 112 | assert traces, "Use assert_no_traces() to check for empty traces" |
| 113 | |
| 114 | for span_obj in fetch_ordered_spans(): |
| 115 | span = span_obj.export() |
| 116 | assert span |
| 117 | assert span.pop("object") == "trace.span" |
| 118 | assert span["id"].startswith("span_") |
| 119 | if not keep_span_id: |
| 120 | del span["id"] |
| 121 | assert datetime.fromisoformat(span.pop("started_at")) |
| 122 | assert datetime.fromisoformat(span.pop("ended_at")) |
| 123 | parent_id = span.pop("parent_id") |
| 124 | assert "type" not in span |
| 125 | span_data = span.pop("span_data") |
| 126 | span = {"type": span_data.pop("type")} | {k: v for k, v in span.items() if v is not None} |
| 127 | span_data = {k: v for k, v in span_data.items() if v is not None} |
| 128 | if span_data: |
| 129 | span["data"] = span_data |
| 130 | trace_id = span.pop("trace_id") |
| 131 | sdk_span_type = None |
| 132 | if span["type"] == "custom": |
| 133 | custom_data = span_data.get("data") |
| 134 | if isinstance(custom_data, dict): |
| 135 | sdk_span_type = custom_data.get("sdk_span_type") |
| 136 | if span["type"] in {"task", "turn"} or sdk_span_type in {"task", "turn"}: |
| 137 | parent = nodes[(trace_id, parent_id)] |
| 138 | if "error" in span and "error" not in parent: |
| 139 | parent["error"] = span["error"] |
| 140 | nodes[(trace_id, span_obj.span_id)] = parent |
| 141 | continue |
| 142 | |
| 143 | nodes[(span_obj.trace_id, span_obj.span_id)] = span |
| 144 | nodes[(trace_id, parent_id)].setdefault("children", []).append(span) |
| 145 | return traces |
no test coverage detected