bryel 0.1.0__py3-none-any.whl

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.
bryel/__init__.py ADDED
@@ -0,0 +1,131 @@
1
+ """bryel — OpenTelemetry-native tracing for LLM apps and agents.
2
+
3
+ One call configures OpenTelemetry to ship traces to bryel; then any
4
+ OpenInference instrumentor (OpenAI, Anthropic, LangChain, LlamaIndex, …) flows
5
+ through automatically:
6
+
7
+ import bryel
8
+ bryel.init(api_key="bk_…", service_name="my-app")
9
+
10
+ from openinference.instrumentation.openai import OpenAIInstrumentor
11
+ OpenAIInstrumentor().instrument()
12
+
13
+ or let bryel instrument every installed OpenInference library for you:
14
+
15
+ bryel.init(api_key="bk_…", instrument=True)
16
+
17
+ bryel's ingest normalizes both the OpenInference (`llm.*`, `openinference.*`) and
18
+ OpenTelemetry GenAI (`gen_ai.*`) conventions, so there is nothing to map
19
+ client-side — the SDK is just the exporter.
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ import os
25
+ from typing import List, Mapping, Optional
26
+
27
+ from opentelemetry import trace
28
+ from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
29
+ from opentelemetry.sdk.resources import SERVICE_NAME, Resource
30
+ from opentelemetry.sdk.trace import TracerProvider
31
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
32
+
33
+ __all__ = ["init", "auto_instrument", "shutdown", "DEFAULT_INGEST_ENDPOINT", "__version__"]
34
+
35
+ __version__ = "0.1.0"
36
+
37
+ #: OTLP/HTTP traces endpoint for the bryel SaaS ingest. The receiver stamps
38
+ #: tenant/project from the API key server-side — the SDK never sends them.
39
+ DEFAULT_INGEST_ENDPOINT = "https://ingest.eu.bryel.ai/v1/traces"
40
+
41
+ # Common OpenInference instrumentors, tried in order by auto_instrument(). Each
42
+ # is optional — missing ones are skipped, nothing is a hard dependency.
43
+ _INSTRUMENTORS = [
44
+ ("openinference.instrumentation.openai", "OpenAIInstrumentor"),
45
+ ("openinference.instrumentation.anthropic", "AnthropicInstrumentor"),
46
+ ("openinference.instrumentation.langchain", "LangChainInstrumentor"),
47
+ ("openinference.instrumentation.llama_index", "LlamaIndexInstrumentor"),
48
+ ("openinference.instrumentation.bedrock", "BedrockInstrumentor"),
49
+ ("openinference.instrumentation.groq", "GroqInstrumentor"),
50
+ ("openinference.instrumentation.mistralai", "MistralAIInstrumentor"),
51
+ ("openinference.instrumentation.vertexai", "VertexAIInstrumentor"),
52
+ ]
53
+
54
+ _provider: Optional[TracerProvider] = None
55
+
56
+
57
+ def init(
58
+ api_key: Optional[str] = None,
59
+ *,
60
+ service_name: Optional[str] = None,
61
+ endpoint: Optional[str] = None,
62
+ headers: Optional[Mapping[str, str]] = None,
63
+ set_global: bool = True,
64
+ instrument: bool = False,
65
+ ) -> TracerProvider:
66
+ """Configure OpenTelemetry to ship traces to bryel and return the provider.
67
+
68
+ Args:
69
+ api_key: your bryel project API key (``bk_…``). Falls back to the
70
+ ``BRYEL_KEY`` environment variable.
71
+ service_name: OpenTelemetry ``service.name`` for this app. Optional.
72
+ endpoint: OTLP/HTTP traces URL. Defaults to the bryel ingest, or the
73
+ ``BRYEL_INGEST_URL`` env var if set (for self-hosting).
74
+ headers: extra headers, merged after the auth header.
75
+ set_global: register the provider as the global OpenTelemetry provider
76
+ (so instrumentors pick it up automatically). Default True.
77
+ instrument: also auto-instrument every installed OpenInference library
78
+ (see :func:`auto_instrument`). Default False.
79
+
80
+ Returns:
81
+ The configured ``TracerProvider`` (keep it to call ``.shutdown()``).
82
+ """
83
+ global _provider
84
+
85
+ key = api_key or os.environ.get("BRYEL_KEY")
86
+ if not key:
87
+ raise ValueError("bryel.init: api_key is required (pass api_key=… or set BRYEL_KEY)")
88
+
89
+ resource = Resource.create({SERVICE_NAME: service_name} if service_name else {})
90
+ exporter = OTLPSpanExporter(
91
+ endpoint=endpoint or os.environ.get("BRYEL_INGEST_URL") or DEFAULT_INGEST_ENDPOINT,
92
+ headers={"Authorization": f"Bearer {key}", **(dict(headers) if headers else {})},
93
+ )
94
+ provider = TracerProvider(resource=resource)
95
+ provider.add_span_processor(BatchSpanProcessor(exporter))
96
+
97
+ if set_global:
98
+ trace.set_tracer_provider(provider)
99
+ _provider = provider
100
+
101
+ if instrument:
102
+ auto_instrument(tracer_provider=provider)
103
+
104
+ return provider
105
+
106
+
107
+ def auto_instrument(tracer_provider: Optional[TracerProvider] = None) -> List[str]:
108
+ """Best-effort: instrument every installed OpenInference library.
109
+
110
+ Safe to call whether or not any instrumentors are installed — missing ones
111
+ are skipped. Returns the names of the libraries that were instrumented.
112
+ """
113
+ instrumented: List[str] = []
114
+ kwargs = {"tracer_provider": tracer_provider} if tracer_provider is not None else {}
115
+ for module_name, class_name in _INSTRUMENTORS:
116
+ try:
117
+ module = __import__(module_name, fromlist=[class_name])
118
+ getattr(module, class_name)().instrument(**kwargs)
119
+ instrumented.append(class_name)
120
+ except Exception:
121
+ # not installed, or already instrumented — skip it
122
+ continue
123
+ return instrumented
124
+
125
+
126
+ def shutdown() -> None:
127
+ """Flush pending spans and shut down the provider. Call on process exit."""
128
+ global _provider
129
+ if _provider is not None:
130
+ _provider.shutdown()
131
+ _provider = None
@@ -0,0 +1,101 @@
1
+ Metadata-Version: 2.4
2
+ Name: bryel
3
+ Version: 0.1.0
4
+ Summary: OpenTelemetry-native tracing for LLM apps and agents — ships OpenInference/OTLP traces to bryel.
5
+ Project-URL: Homepage, https://docs.bryel.ai
6
+ Project-URL: Documentation, https://docs.bryel.ai
7
+ Author: bryel
8
+ License-Expression: MIT
9
+ Keywords: bryel,genai,llm,observability,openinference,opentelemetry,tracing
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
+ Requires-Python: >=3.9
14
+ Requires-Dist: opentelemetry-api>=1.20.0
15
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20.0
16
+ Requires-Dist: opentelemetry-sdk>=1.20.0
17
+ Provides-Extra: anthropic
18
+ Requires-Dist: openinference-instrumentation-anthropic; extra == 'anthropic'
19
+ Provides-Extra: bedrock
20
+ Requires-Dist: openinference-instrumentation-bedrock; extra == 'bedrock'
21
+ Provides-Extra: langchain
22
+ Requires-Dist: openinference-instrumentation-langchain; extra == 'langchain'
23
+ Provides-Extra: llama-index
24
+ Requires-Dist: openinference-instrumentation-llama-index; extra == 'llama-index'
25
+ Provides-Extra: openai
26
+ Requires-Dist: openinference-instrumentation-openai; extra == 'openai'
27
+ Description-Content-Type: text/markdown
28
+
29
+ # bryel (Python)
30
+
31
+ OpenTelemetry-native tracing for LLM apps and agents. One call ships your model
32
+ calls, tool calls, tokens, and cost to [bryel](https://docs.bryel.ai) as
33
+ OpenInference traces — from any framework.
34
+
35
+ ```bash
36
+ uv add bryel # or: pip install bryel
37
+ ```
38
+
39
+ ## Quickstart
40
+
41
+ ```python
42
+ import bryel
43
+ bryel.init(api_key="bk_…", service_name="my-app")
44
+
45
+ # Trace OpenAI (any OpenInference instrumentor works the same way):
46
+ from openinference.instrumentation.openai import OpenAIInstrumentor
47
+ OpenAIInstrumentor().instrument()
48
+
49
+ from openai import OpenAI
50
+ OpenAI().chat.completions.create(
51
+ model="gpt-4o-mini",
52
+ messages=[{"role": "user", "content": "hello"}],
53
+ )
54
+ ```
55
+
56
+ Prefer bryel to wire up everything it can find? Let it instrument every installed
57
+ OpenInference library for you:
58
+
59
+ ```python
60
+ import bryel
61
+ bryel.init(api_key="bk_…", instrument=True) # instruments openai, anthropic, langchain, …
62
+ ```
63
+
64
+ ## How it works
65
+
66
+ bryel is just the exporter. It configures an OpenTelemetry `TracerProvider` with
67
+ an OTLP/HTTP exporter pointed at the bryel ingest, authenticated with your API
68
+ key. The [OpenInference instrumentors](https://github.com/Arize-ai/openinference)
69
+ emit the spans; bryel's ingest normalizes both the OpenInference (`llm.*`) and
70
+ OpenTelemetry GenAI (`gen_ai.*`) conventions — so there's nothing to map.
71
+
72
+ ## API
73
+
74
+ ### `bryel.init(api_key=None, *, service_name=None, endpoint=None, headers=None, set_global=True, instrument=False)`
75
+
76
+ Configures the exporter and returns the `TracerProvider`.
77
+
78
+ - `api_key` — your project API key (`bk_…`). Falls back to `$BRYEL_KEY`.
79
+ - `service_name` — OpenTelemetry `service.name`.
80
+ - `endpoint` — OTLP/HTTP traces URL. Defaults to the bryel ingest, or
81
+ `$BRYEL_INGEST_URL` for self-hosting.
82
+ - `headers` — extra headers, merged after auth.
83
+ - `set_global` — register as the global OTel provider (default `True`).
84
+ - `instrument` — also auto-instrument installed OpenInference libraries.
85
+
86
+ ### `bryel.auto_instrument(tracer_provider=None) -> list[str]`
87
+
88
+ Best-effort instrument every installed OpenInference library. Returns the ones it
89
+ wired up. Safe to call with none installed.
90
+
91
+ ### `bryel.shutdown()`
92
+
93
+ Flush pending spans and shut down. Call on process exit.
94
+
95
+ ## Feedback and grouping
96
+
97
+ Group turns into a conversation and attach 👍/👎 by stamping metadata on your
98
+ spans — set `session.id`, `user.id`, and a `bryel.interaction.id` you mint. See
99
+ the [docs](https://docs.bryel.ai).
100
+
101
+ MIT © bryel
@@ -0,0 +1,4 @@
1
+ bryel/__init__.py,sha256=dqV7aNlFLFET6vJ2vB1rNZ-BHMc_k_y6qTrBc9FOQt8,5219
2
+ bryel-0.1.0.dist-info/METADATA,sha256=5kCHdDytGGzuMHmedi842Flh1kpablzcFtHPG9HBZtk,3727
3
+ bryel-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
4
+ bryel-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any