-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
234 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import asyncio | ||
from collections.abc import AsyncIterator, Callable | ||
from contextlib import asynccontextmanager | ||
from functools import wraps | ||
from types import SimpleNamespace | ||
from typing import Any, ParamSpec, TypeVar | ||
from ragbits.core.audit.base import TraceHandler | ||
|
||
_trace_handlers: list[TraceHandler] = [] | ||
|
||
Handler = str | TraceHandler | ||
|
||
P = ParamSpec("P") | ||
R = TypeVar("R") | ||
|
||
|
||
def traceable(func: Callable[P, R]) -> Callable[P, R]: | ||
@wraps(func) | ||
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: | ||
print(*args, **kwargs) | ||
return func(*args, **kwargs) | ||
|
||
@wraps(func) | ||
async def wrapper_async(*args: P.args, **kwargs: P.kwargs) -> R: | ||
print("asuync", *args, **kwargs) | ||
return await func(*args, **kwargs) # type: ignore | ||
|
||
if asyncio.iscoroutinefunction(func): | ||
return wrapper_async # type: ignore | ||
return wrapper | ||
|
||
|
||
@asynccontextmanager | ||
async def trace(**inputs: Any) -> AsyncIterator[SimpleNamespace]: | ||
""" | ||
Context manager for processing an event. | ||
Args: | ||
event: The event to be processed. | ||
Yields: | ||
The event being processed. | ||
""" | ||
for handler in _trace_handlers: | ||
await handler.on_start(**inputs) | ||
|
||
try: | ||
yield (outputs := SimpleNamespace()) | ||
except Exception as exc: | ||
for handler in _trace_handlers: | ||
await handler.on_error(exc) | ||
raise exc | ||
|
||
for handler in _trace_handlers: | ||
await handler.on_end(**vars(outputs)) | ||
|
||
|
||
def set_trace_handlers(handlers: Handler | list[Handler]) -> None: | ||
""" | ||
Setup event handlers. | ||
Args: | ||
handlers: List of event handlers to be used. | ||
Raises: | ||
ValueError: If handler is not found. | ||
TypeError: If handler type is invalid. | ||
""" | ||
global _trace_handlers | ||
|
||
if isinstance(handlers, str): | ||
handlers = [handlers] | ||
|
||
for handler in handlers: # type: ignore | ||
if isinstance(handler, TraceHandler): | ||
_trace_handlers.append(handler) | ||
elif isinstance(handler, str): | ||
if handler == "otel": | ||
from ragbits.core.audit.otel import OtelTraceHandler | ||
_trace_handlers.append(OtelTraceHandler()) | ||
if handler == "langsmith": | ||
from ragbits.core.audit.langsmith import LangSmithTraceHandler | ||
_trace_handlers.append(LangSmithTraceHandler()) | ||
else: | ||
raise ValueError(f"Handler {handler} not found.") | ||
else: | ||
raise TypeError(f"Invalid handler type: {type(handler)}") | ||
|
||
|
||
__all__ = ["TraceHandler", "traceable", "trace", "set_trace_handlers"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from abc import ABC, abstractmethod | ||
from typing import Any | ||
|
||
|
||
class TraceHandler(ABC): | ||
""" | ||
Base class for all trace handlers. | ||
""" | ||
|
||
@abstractmethod | ||
async def on_start(self, **inputs: Any) -> None: | ||
""" | ||
Log input data at the start of the event. | ||
Args: | ||
inputs: The input data. | ||
""" | ||
|
||
@abstractmethod | ||
async def on_end(self, **outputs: Any) -> None: | ||
""" | ||
Log output data at the end of the event. | ||
Args: | ||
outputs: The output data. | ||
""" | ||
|
||
@abstractmethod | ||
async def on_error(self, error: Exception) -> None: | ||
""" | ||
Log error during the event. | ||
Args: | ||
error: The error that occurred. | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from typing import Any | ||
|
||
from opentelemetry import trace | ||
from opentelemetry.trace import Span, StatusCode | ||
from ragbits.core.audit.base import TraceHandler | ||
|
||
|
||
class OtelTraceHandler(TraceHandler): | ||
""" | ||
OpenTelemetry trace handler. | ||
""" | ||
|
||
def __init__(self) -> None: | ||
self._tracer = trace.get_tracer("ragbits.events") | ||
|
||
async def on_start(self, **inputs: Any) -> None: | ||
with self._tracer.start_as_current_span("request", end_on_exit=False) as span: | ||
for key, value in inputs.items(): | ||
span.set_attribute(key, value) | ||
|
||
async def on_end(self, **outputs: Any) -> None: | ||
span = trace.get_current_span() | ||
for key, value in outputs.items(): | ||
span.set_attribute(key, value) | ||
span.set_status(StatusCode.OK) | ||
span.end() | ||
|
||
async def on_error(self, error: Exception) -> None: | ||
print("on_error", error) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters