Metadata-Version: 2.4
Name: mainwave
Version: 0.1.0rc1
Summary: Python SDK for the Mainwave AI observability platform
Project-URL: Homepage, https://mainwave.ai
Project-URL: Repository, https://github.com/mainwaveai/mainwave
Project-URL: Issues, https://github.com/mainwaveai/mainwave/issues
Author: Mainwave AI
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agents,llm,mainwave,observability,openinference,opentelemetry,tracing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Monitoring
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: opentelemetry-api>=1.27
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.27
Requires-Dist: opentelemetry-sdk>=1.27
Provides-Extra: all
Requires-Dist: langchain-core; extra == 'all'
Requires-Dist: openinference-instrumentation-anthropic; extra == 'all'
Requires-Dist: openinference-instrumentation-bedrock; extra == 'all'
Requires-Dist: openinference-instrumentation-crewai; extra == 'all'
Requires-Dist: openinference-instrumentation-google-genai; extra == 'all'
Requires-Dist: openinference-instrumentation-groq; extra == 'all'
Requires-Dist: openinference-instrumentation-langchain; extra == 'all'
Requires-Dist: openinference-instrumentation-litellm; extra == 'all'
Requires-Dist: openinference-instrumentation-llama-index; extra == 'all'
Requires-Dist: openinference-instrumentation-mistralai; extra == 'all'
Requires-Dist: openinference-instrumentation-openai; extra == 'all'
Requires-Dist: openinference-instrumentation-vertexai; extra == 'all'
Provides-Extra: anthropic
Requires-Dist: openinference-instrumentation-anthropic; extra == 'anthropic'
Provides-Extra: bedrock
Requires-Dist: openinference-instrumentation-bedrock; extra == 'bedrock'
Provides-Extra: crewai
Requires-Dist: openinference-instrumentation-crewai; extra == 'crewai'
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: google-genai
Requires-Dist: openinference-instrumentation-google-genai; extra == 'google-genai'
Provides-Extra: groq
Requires-Dist: openinference-instrumentation-groq; extra == 'groq'
Provides-Extra: langchain
Requires-Dist: langchain-core; extra == 'langchain'
Requires-Dist: openinference-instrumentation-langchain; extra == 'langchain'
Provides-Extra: litellm
Requires-Dist: openinference-instrumentation-litellm; extra == 'litellm'
Provides-Extra: llama-index
Requires-Dist: openinference-instrumentation-llama-index; extra == 'llama-index'
Provides-Extra: mistralai
Requires-Dist: openinference-instrumentation-mistralai; extra == 'mistralai'
Provides-Extra: openai
Requires-Dist: openinference-instrumentation-openai; extra == 'openai'
Provides-Extra: vertexai
Requires-Dist: openinference-instrumentation-vertexai; extra == 'vertexai'
Description-Content-Type: text/markdown

# mainwave

Python SDK for the [Mainwave AI](https://mainwave.ai) observability platform.

## Install

```bash
pip install "mainwave[openai]"        # one platform
pip install "mainwave[langchain]"     # LangChain + a callback handler
pip install "mainwave[all]"           # everything (kick-the-tires only)
```

Per-platform pinning is recommended in production.

## Quickstart

```python
import mainwave

mainwave.init(
    api_key="...",                                       # or MAINWAVE_API_KEY
    use_case_id="00000000-0000-0000-0000-000000000001",  # or MAINWAVE_USE_CASE_ID
    collector_url="https://collect.mainwave.ai",         # default
)

with mainwave.run("INV-12345", metadata={"customer": "acme"}):
    # ... do work; auto-instrumented LLM calls land under this run
    ...

mainwave.flush()  # before exit
```

`init()` auto-wires every supported instrumentor that's already importable, so
the snippet above needs no `instrument()` call. Reach for `instrument()` only
to wire a framework imported *after* `init()` ran (lazy import, CLI subcommand,
FastAPI lifespan) — see [Public API](#public-api).

`mainwave.run(...)` is optional — without it, every OTel trace becomes its
own logical run. Wrap explicitly when one logical operation spans multiple
traces (loops, fan-out, multiple LLM invocations per request); the integration
guide wraps every agent execution for exactly this reason.

## Not seeing data?

The SDK never raises into your app, so a misconfigured endpoint or key fails
quietly. Turn on its logger to see what's happening:

```python
import logging
logging.getLogger("mainwave").setLevel(logging.INFO)   # add a handler if you have none
```

At `INFO` it logs the first successful export, which instrumentors wired, and a
`WARNING` for any framework that didn't. `mainwave.flush()` returns `False` on a
failed drain — check it before a hard exit. Confirm `collector_url` and the API
key, and that the framework's extra is installed (`pip install "mainwave[openai]"`).

## Public API

- `mainwave.init(...)` — set up the SDK once, at process start.
- `mainwave.instrument(name=None)` — re-wire instrumentors after late imports.
- `mainwave.run(...)` / `mainwave.arun(...)` / `mainwave.start_run(...)` — open a logical run (sync CM, async CM, imperative).
- `mainwave.span(name, attrs=...)` — escape hatch for manual spans.
- `mainwave.flush(timeout=30.0)` / `mainwave.aflush(timeout=30.0)` — drain buffers.
- `mainwave.langchain.CallbackHandler` — optional explicit LangChain handler.
- `mainwave.testing` — `reset()` + `install_in_memory_provider()` for tests.

## LangChain users

Use the native `CallbackHandler` (captures model reasoning + step trajectory) OR
auto-instrumentation (`instrument(name="langchain")`) — not both, or every call
is double-counted. You don't have to police it: attaching the handler disables
the OpenInference LangChain instrumentor automatically, and
`init(skip_instrumentors=["langchain"])` skips wiring it up front.

## See also

Spec: `docs/agent_sdk/` in the platform monorepo.
