Drop-in instrumented wrappers for AI clients with zero-overhead telemetry
Project description
Weflayr SDK
Drop-in instrumented wrappers for OpenAI and Mistral AI clients. Add telemetry to your LLM calls in one line - no changes to your existing code structure required.
How it works
Weflayr wraps the official provider SDKs and automatically fires telemetry events to your Weflayr intake API before, after, and on error for every LLM call. Your application code stays identical.
your code → weflayr.sdk.openai.OpenAI → openai.OpenAI → OpenAI API
↓
Weflayr Intake API
(before / after / error events)
Installation
pip install weflayr
Quickstart
Configuration
Set the following environment variables:
| Variable | Description | Default |
|---|---|---|
WEFLAYR_INTAKE_URL |
Your Weflayr intake API base URL | https://api.weflayr.com |
WEFLAYR_CLIENT_ID |
Your client identifier | unknown_client |
WEFLAYR_CLIENT_SECRET |
Your bearer token | (empty) |
export WEFLAYR_INTAKE_URL="https://api.weflayr.com"
export WEFLAYR_CLIENT_ID="my-app"
export WEFLAYR_CLIENT_SECRET="your-secret-token"
OpenAI
Drop-in replacement for openai.OpenAI and openai.AsyncOpenAI.
Sync
from weflayr.sdk.openai.client import OpenAI
client = OpenAI(api_key="sk-...")
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
Async
import asyncio
from weflayr.sdk.openai.client import AsyncOpenAI
client = AsyncOpenAI(api_key="sk-...")
async def main():
response = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
asyncio.run(main())
Tagging calls
Pass a tags dict to attach arbitrary metadata to your telemetry events:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Summarize this."}],
tags={"feature": "summarization", "user_id": "u_123"},
)
Mistral AI
Drop-in replacement for mistralai.client.Mistral.
Sync
from weflayr.sdk.mistralai.client import Mistral
client = Mistral(api_key="sk-...")
response = client.chat.complete(
model="mistral-small-latest",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
Async
import asyncio
from weflayr.sdk.mistralai.client import Mistral
client = Mistral(api_key="sk-...")
async def main():
response = await client.chat.complete_async(
model="mistral-small-latest",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
asyncio.run(main())
Tagging calls
response = client.chat.complete(
model="mistral-small-latest",
messages=[{"role": "user", "content": "Translate this."}],
tags={"feature": "translation", "env": "production"},
)
Telemetry events
For every LLM call, Weflayr sends up to three events to your intake API:
| Event | When | Payload includes |
|---|---|---|
<call>.before |
Before the provider call | model, message_count, tags |
<call>.after |
On success | model, elapsed_ms, prompt_tokens, completion_tokens |
<call>.error |
On failure | model, elapsed_ms, error_type, error_message, status_code |
Events are sent fire-and-forget in background threads — they never block your application or raise exceptions.
Advanced: per-client configuration
Override the intake URL, client ID, and bearer token directly on the client instead of using environment variables:
from weflayr.sdk.openai.client import OpenAI
client = OpenAI(
api_key="sk-...",
intake_url="https://intake.weflayr.com",
client_id="my-service",
bearer_token="my-secret",
)
License
Elastic License 2.0 — free to use, modifications and redistribution not permitted.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file weflayr-0.1.0.tar.gz.
File metadata
- Download URL: weflayr-0.1.0.tar.gz
- Upload date:
- Size: 174.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e70d8e22ff8fe3b1c2d7323f2788b90ab6c8c275fe42e29ea516a69192745225
|
|
| MD5 |
e7e201e6dbc0baef1d8f9bbc3bf0d916
|
|
| BLAKE2b-256 |
ff95cf592a442fca1b082e0d73d58cd4943a6eeb034f334ab1933b88cdff5e01
|
File details
Details for the file weflayr-0.1.0-py3-none-any.whl.
File metadata
- Download URL: weflayr-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9957f875e55552a5bfde41b5e14d5cfa2ac830a7d7e41a0d1dca28475377d68d
|
|
| MD5 |
b2a18d88a8ab34741b962e73d2db690c
|
|
| BLAKE2b-256 |
15b46a8f286235bcc245fd74bc238232d162a7fc5413a25ec4e6f9b29dedeac3
|