windlass.providers.observability.platforms¶
platforms
¶
LangSmith and Langfuse tracers.
Both give you a hosted trace viewer: nested spans, prompts, completions, token counts and latency, searchable across runs. That is the difference between "users say it got worse" and "the retriever started returning the wrong section on Tuesday".
Install with::
pip install "windlass[observability]"
Neither tracer is ever allowed to break your application. Every export path
swallows its own errors and logs a warning, and every flush runs under a
deadline — a vendor client that blocks on an internal queue must not be able to
hang the process it is observing, and an exception handler cannot catch a hang.
Example
from windlass import Windlass # doctest: +SKIP rag = Windlass.rag().observe("langfuse") # doctest: +SKIP
LangSmithTracer
¶
LangSmithTracer(
*,
api_key: str | None = None,
project: str | None = None,
api_url: str | None = None,
tags: tuple[str, ...] = (),
enabled: bool = True,
**config: Any
)
Bases: Tracer
Sends spans to LangSmith.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_key
|
str | None
|
Credential. Falls back to |
None
|
project
|
str | None
|
LangSmith project name. |
None
|
api_url
|
str | None
|
Endpoint override for self-hosted deployments. |
None
|
tags
|
tuple[str, ...]
|
Tags applied to every run. |
()
|
enabled
|
bool
|
Master switch. |
True
|
**config
|
Any
|
Forwarded to :class: |
{}
|
Raises:
| Type | Description |
|---|---|
MissingDependencyError
|
When |
ConfigurationError
|
When no API key can be found. |
Performance
The LangSmith client batches and sends in the background, so tracing adds
negligible latency to the request path. Call :meth:flush before a
short-lived process exits or you will lose the tail of your traces.
Source code in src\windlass\providers\observability\platforms.py
native
¶
start_span
¶
Create a LangSmith run for the span.
Source code in src\windlass\providers\observability\platforms.py
end_span
¶
Close the LangSmith run.
Source code in src\windlass\providers\observability\platforms.py
flush
¶
Wait for queued runs to be sent, giving up after FLUSH_TIMEOUT.
Source code in src\windlass\providers\observability\platforms.py
aclose
async
¶
Flush, then shut the client's background worker down.
Without the shutdown, the LangSmith SDK's worker thread outlives the
application and tries to spawn a new thread from its own interpreter
shutdown hook — which Python refuses once teardown has begun. The result
is a traceback printed from inside langsmith after the program has
already finished successfully, which looks like a crash and is not one.
Source code in src\windlass\providers\observability\platforms.py
LangfuseTracer
¶
LangfuseTracer(
*,
public_key: str | None = None,
secret_key: str | None = None,
host: str | None = None,
project: str | None = None,
tags: tuple[str, ...] = (),
enabled: bool = True,
flush_timeout: float = FLUSH_TIMEOUT,
**config: Any
)
Bases: Tracer
Sends spans to Langfuse.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_key
|
str | None
|
Langfuse public key. Falls back to |
None
|
secret_key
|
str | None
|
Langfuse secret key. Falls back to |
None
|
host
|
str | None
|
Endpoint. Falls back to |
None
|
project
|
str | None
|
Session / project name recorded on each trace. |
None
|
tags
|
tuple[str, ...]
|
Tags applied to every trace. |
()
|
enabled
|
bool
|
Master switch. |
True
|
**config
|
Any
|
Forwarded to :class: |
{}
|
Raises:
| Type | Description |
|---|---|
MissingDependencyError
|
When |
ConfigurationError
|
When the key pair is incomplete. |
Note
Langfuse's SDK is versioned aggressively and rewrote its span API between v2 and v3. This adapter detects which surface the installed version exposes and uses it:
- v3 / v4 —
client.start_observation(as_type=...), whose observation types map almost one-to-one onto Windlass span kinds. - v2 —
client.trace()/parent.span()/parent.generation().
If neither is present the constructor raises. Silently exporting nothing while reporting healthy is a worse failure than refusing to start: you only discover it when you go looking for traces that were never sent.
Attributes:
| Name | Type | Description |
|---|---|---|
api |
|
Source code in src\windlass\providers\observability\platforms.py
native
¶
start_span
¶
Open a Langfuse observation, nested under its parent when there is one.
Source code in src\windlass\providers\observability\platforms.py
end_span
¶
Record the outcome and close the Langfuse handle.
Source code in src\windlass\providers\observability\platforms.py
flush
¶
Send any buffered events, giving up after :attr:flush_timeout.
Langfuse's own flush joins an internal queue and can block forever
when a worker thread has already stopped with items outstanding.
Source code in src\windlass\providers\observability\platforms.py
aclose
async
¶
Flush and shut the client down, both under a deadline.