Skip to content

Commit dce6a81

Browse files
committed
refactor!: Make opentelemetry an optional dependency
1 parent 270ea9b commit dce6a81

File tree

3 files changed

+45
-14
lines changed

3 files changed

+45
-14
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ To install with gRPC support:
3939
uv add "a2a-sdk[grpc]"
4040
```
4141

42+
To install with OpenTelemetry tracing support:
43+
44+
```bash
45+
uv add "a2a-sdk[telemetry]"
46+
```
47+
4248
To install with database support:
4349

4450
```bash
@@ -69,6 +75,12 @@ To install with gRPC support:
6975
pip install "a2a-sdk[grpc]"
7076
```
7177

78+
To install with OpenTelemetry tracing support:
79+
80+
```bash
81+
pip install "a2a-sdk[telemetry]"
82+
```
83+
7284
To install with database support:
7385

7486
```bash

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ dependencies = [
1111
"fastapi>=0.115.2",
1212
"httpx>=0.28.1",
1313
"httpx-sse>=0.4.0",
14-
"opentelemetry-api>=1.33.0",
15-
"opentelemetry-sdk>=1.33.0",
1614
"pydantic>=2.11.3",
1715
"sse-starlette",
1816
"starlette"
@@ -38,6 +36,7 @@ sqlite = ["sqlalchemy[asyncio,aiosqlite]>=2.0.0"]
3836
sql = ["sqlalchemy[asyncio,postgresql-asyncpg,aiomysql,aiosqlite]>=2.0.0"]
3937
encryption = ["cryptography>=43.0.0"]
4038
grpc = ["grpcio>=1.60", "grpcio-tools>=1.60", "grpcio_reflection>=1.7.0", "protobuf==5.29.5", "google-api-core>=1.26.0"]
39+
telemetry = ["opentelemetry-api>=1.33.0", "opentelemetry-sdk>=1.33.0", "opentelemetry-semantic-conventions>=0.55b1"]
4140

4241
[project.urls]
4342
homepage = "https://a2a-protocol.org/"

src/a2a/utils/telemetry.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,45 @@ def internal_method(self):
6161
from collections.abc import Callable
6262
from typing import Any, TypeAlias
6363

64-
from opentelemetry import trace
65-
from opentelemetry.trace import SpanKind as _SpanKind
66-
from opentelemetry.trace import StatusCode
6764

65+
logger = logging.getLogger(__name__)
66+
67+
try:
68+
from opentelemetry import trace
69+
from opentelemetry.trace import SpanKind as _SpanKind
70+
from opentelemetry.trace import StatusCode
71+
72+
except ImportError:
73+
logger.debug(
74+
'OpenTelemetry not found. Tracing will be disabled. '
75+
'Install with: \'pip install "a2a-sdk[telemetry]"\''
76+
)
77+
78+
class _NoOp:
79+
"""A no-op object that absorbs all tracing calls when OpenTelemetry is not installed."""
80+
81+
def __call__(self, *args: Any, **kwargs: Any) -> '_NoOp':
82+
return self
83+
84+
def __enter__(self) -> '_NoOp':
85+
return self
86+
87+
def __exit__(self, *args: object, **kwargs: Any) -> None:
88+
pass
89+
90+
def __getattr__(self, name: str) -> '_NoOp':
91+
return self
92+
93+
trace = _NoOp()
94+
_SpanKind = _NoOp()
95+
StatusCode = _NoOp()
6896

6997
SpanKind: TypeAlias = _SpanKind
7098
__all__ = ['SpanKind']
99+
71100
INSTRUMENTING_MODULE_NAME = 'a2a-python-sdk'
72101
INSTRUMENTING_MODULE_VERSION = '1.0.0'
73102

74-
logger = logging.getLogger(__name__)
75-
76103

77104
def trace_function( # noqa: PLR0915
78105
func: Callable | None = None,
@@ -280,22 +307,15 @@ def not_traced_method(self):
280307
exclude_list = exclude_list or []
281308

282309
def decorator(cls: Any) -> Any:
283-
all_methods = {}
284310
for name, method in inspect.getmembers(cls, inspect.isfunction):
285-
# Skip Dunders
286311
if name.startswith('__') and name.endswith('__'):
287312
continue
288-
289-
# Skip if include list is defined but the method not included.
290313
if include_list and name not in include_list:
291314
continue
292-
# Skip if include list is not defined but the method is in excludes.
293315
if not include_list and name in exclude_list:
294316
continue
295317

296-
all_methods[name] = method
297318
span_name = f'{cls.__module__}.{cls.__name__}.{name}'
298-
# Set the decorator on the method.
299319
setattr(
300320
cls,
301321
name,

0 commit comments

Comments
 (0)