Meilynx SDK for AI FinOps telemetry and outcomes ingestion.
Project description
Meilynx Python SDK
Meilynx is an AI governance and FinOps platform that gives enterprises visibility and control over LLM usage — from cost and compliance to business outcomes. This SDK lets you send structured telemetry and outcome events from your Python applications.
Install
pip install meilynx
# with OpenAI auto-instrumentation
pip install meilynx[openai]
# with Anthropic auto-instrumentation
pip install meilynx[anthropic]
# all integrations
pip install meilynx[all]
Quickstart
Option 1: Auto-instrumentation (recommended)
Add two lines at startup — your existing AI calls are tracked automatically:
from meilynx import MeilynxClient, MeilynxOptions, instrument
mx = MeilynxClient(MeilynxOptions(
api_key="mx_live_...", # base_url defaults to https://api.meilynx.com
))
instrument(client=mx) # patches OpenAI, Anthropic, etc. automatically
# use your AI clients as normal — calls are tracked
from openai import OpenAI
client = OpenAI()
client.chat.completions.create(model="gpt-4o", messages=[...])
mx.shutdown()
Option 2: Drop-in import
Change one import line for explicit control:
# OpenAI
from meilynx.integrations.openai import OpenAI
client = OpenAI(meilynx_client=mx, api_key="sk-...")
client.chat.completions.create(model="gpt-4o", messages=[...])
# Anthropic
from meilynx.integrations.anthropic import Anthropic
client = Anthropic(meilynx_client=mx, api_key="sk-ant-...")
client.messages.create(model="claude-sonnet-4-20250514", max_tokens=1024, messages=[...])
Option 3: Explicit tracking
Full control over what you send:
from meilynx import MeilynxClient, MeilynxOptions
from meilynx.types import TelemetryEventInput
mx = MeilynxClient(MeilynxOptions(
api_key="mx_live_...", # base_url defaults to https://api.meilynx.com
))
mx.track(TelemetryEventInput(
event_type="llm.response",
correlation_id="run-123",
feature_key="ask_docs",
model="gpt-4o",
provider="openai",
prompt_tokens=1200,
completion_tokens=220,
))
mx.flush()
mx.shutdown()
Which to choose? Use auto-instrumentation or drop-in imports (Options 1-2) for most cases — they automatically capture model, latency, and agentic context with zero manual work. Use explicit tracking (Option 3) when you need custom event types, non-LLM operations, or providers without built-in integration.
Context propagation with @observe
The @observe decorator propagates business context (correlation IDs, feature keys, customer IDs)
through the call stack. All instrumented AI calls inside inherit this context automatically:
from meilynx import observe
@observe(feature_key="ask_docs", customer_id="acme")
def summarize(doc: str) -> str:
# all AI calls here are tagged with feature_key="ask_docs"
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": f"Summarize: {doc}"}],
)
return response.choices[0].message.content
Nested decorators inherit the parent context and can override specific fields.
Configuration
Environment variables (convention)
The SDK does not read environment variables directly. These are recommended names for your app configuration:
MX_BASE_URL(optional) — Meilynx API URLMX_API_KEY— Project-scoped API key (mx_live_...)
Constructor options
| Option | Type | Default | Notes |
|---|---|---|---|
api_key |
str | — | Required. API key for /v1/ingest/*. |
base_url |
str | "https://api.meilynx.com" |
Base URL for the Meilynx API. |
source_system |
str | "sdk" |
Source identifier. |
flush_at |
int | 25 |
Batch size before flush. |
flush_interval_ms |
int | 5000 |
Auto-flush interval. |
max_retries |
int | 3 |
Retry attempts on 429/5xx. |
retry_delay_ms |
int | 250 |
Base delay for backoff. |
disable_validation |
bool | False |
Disable JSON schema validation. |
Agentic context
For agentic loops with multiple tool-call hops, set agent_name, tool_name, and step_index
on each step via @observe:
for i, step in enumerate(steps):
@observe(agent_name="research-agent", tool_name=step.name, step_index=i)
def run_step():
return client.chat.completions.create(model="gpt-4o", messages=[...])
run_step()
The auto-instrumentation also captures response_tool_calls (tool names the model invoked)
automatically from streaming and non-streaming responses.
Capturing outcomes
Outcomes are the business results your AI features produce:
from meilynx import mint_idempotency_key
from meilynx.types import OutcomeEventInput
mx.capture_outcome(OutcomeEventInput(
outcome_type="feature.result.accepted",
idempotency_key=mint_idempotency_key("accepted", correlation_id),
correlation_id=correlation_id,
customer_id="cust-acme",
feature_key="ask_docs",
))
Idempotency keys
Every outcome requires an idempotency_key to prevent duplicate processing. Use
mint_idempotency_key() to generate a deterministic SHA-256 key from one or more fields:
from meilynx import mint_idempotency_key
# Same inputs always produce the same key
mint_idempotency_key("accepted", "run-123") # → "a1b2c3..."
mint_idempotency_key("accepted", "run-123") # → "a1b2c3..." (same)
mint_idempotency_key("accepted", "run-456") # → "d4e5f6..." (different)
Budget status
Check current budget utilization from your application. Results are cached for 60 seconds per query-parameter combination.
status = mx.get_budget_status(customer_id="acme")
for budget in status["budgets"]:
if budget["action"] == "block":
print(f"Budget {budget['name']} exceeded: {budget['utilization_pct']}%")
Failsafe behavior
The SDK is designed to never break your application. All instrumentation, context injection, telemetry emission, and governance extraction are wrapped in defensive error handling:
- If context building or injection fails, the original LLM call proceeds unmodified.
- If telemetry emission fails, the error is swallowed silently.
- If governance response parsing fails, the result is returned as-is.
- Real LLM provider errors (rate limits, auth failures, invalid requests) always propagate normally.
In other words: a bug in the Meilynx SDK will log a warning but never cause your AI calls to fail.
Streaming
Auto-instrumentation handles streaming transparently. For both OpenAI and Anthropic:
- One telemetry event is emitted per completion (not per chunk)
is_streamingis set toTrueautomaticallylatency_msmeasures time from request start to last token received- Tool calls in the response are accumulated into
response_tool_calls
No additional configuration is needed for streaming calls.
Error handling
- 429 and 5xx responses are retried with exponential backoff.
- 401/403 errors raise
PermissionErrorimmediately.
Serverless and short-lived processes
In short-lived environments (AWS Lambda, Google Cloud Functions), flush before the handler returns to avoid losing events:
# AWS Lambda
def handler(event, context):
result = handle_request(event)
mx.flush() # flush before returning
return result
# Always call shutdown() when the process is exiting
mx.shutdown()
Compatibility
- Python 3.9+
- Thread-safe batching with background flush.
- Not intended for browsers or client-side use. API keys must stay server-side.
Docs
- Documentation: docs.meilynx.com
- JS/TS SDK: github.com/meilynx/meilynx-js
- .NET SDK: github.com/meilynx/meilynx-dotnet
License
MIT
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 meilynx-0.3.0.tar.gz.
File metadata
- Download URL: meilynx-0.3.0.tar.gz
- Upload date:
- Size: 31.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c209eb00e58e1cb8d49e0ff6cba0077a227b96ebacd80bd63527ebfbbffb627
|
|
| MD5 |
781842617229874e2082db24b0196719
|
|
| BLAKE2b-256 |
465c463686db269c6a20c52f421d026d6e0695bc76f9e3d98cd7dc09f4d5e6c5
|
Provenance
The following attestation bundles were made for meilynx-0.3.0.tar.gz:
Publisher:
release.yml on Meilynx/meilynx-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
meilynx-0.3.0.tar.gz -
Subject digest:
2c209eb00e58e1cb8d49e0ff6cba0077a227b96ebacd80bd63527ebfbbffb627 - Sigstore transparency entry: 1414485519
- Sigstore integration time:
-
Permalink:
Meilynx/meilynx-python@024e74488c08b203ef4225b32cf46d57f89c5f13 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/Meilynx
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@024e74488c08b203ef4225b32cf46d57f89c5f13 -
Trigger Event:
push
-
Statement type:
File details
Details for the file meilynx-0.3.0-py3-none-any.whl.
File metadata
- Download URL: meilynx-0.3.0-py3-none-any.whl
- Upload date:
- Size: 33.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c272a1e3881f361a5928a94282c53f8bf69864523c368069d66c8cc1dba77a82
|
|
| MD5 |
042ab90bc6db4364b2c40747b3b72981
|
|
| BLAKE2b-256 |
aab66cc0a528316adf344b9c4d47446b15fc914afe1e3519cec9e5994a25b238
|
Provenance
The following attestation bundles were made for meilynx-0.3.0-py3-none-any.whl:
Publisher:
release.yml on Meilynx/meilynx-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
meilynx-0.3.0-py3-none-any.whl -
Subject digest:
c272a1e3881f361a5928a94282c53f8bf69864523c368069d66c8cc1dba77a82 - Sigstore transparency entry: 1414485594
- Sigstore integration time:
-
Permalink:
Meilynx/meilynx-python@024e74488c08b203ef4225b32cf46d57f89c5f13 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/Meilynx
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@024e74488c08b203ef4225b32cf46d57f89c5f13 -
Trigger Event:
push
-
Statement type: