raindrop-langchain
Raindrop integration for LangChain (Python). Automatically captures LLM calls, tool usage, chains, and retrievers via LangChain's callback system.
Installation
pip install raindrop-langchain langchain-core
Quick Start
from raindrop_langchain import RaindropLangchain
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
raindrop = RaindropLangchain(
api_key="rk_...",
user_id="user-123",
)
model = ChatOpenAI(model="gpt-4o")
result = model.invoke(
[HumanMessage(content="Hello!")],
config={"callbacks": [raindrop.handler]},
)
raindrop.flush()
Factory Function (alternative)
from raindrop_langchain import create_raindrop_langchain
raindrop = create_raindrop_langchain(api_key="rk_...", user_id="user-123")
model = ChatOpenAI(model="gpt-4o")
result = model.invoke("Hello!", config={"callbacks": [raindrop.handler]})
raindrop.flush()
Projects
Route events to a specific project by passing its slug as project_id:
raindrop = RaindropLangchain(
api_key="rk_...",
project_id="support-prod",
)
project_id sets the X-Raindrop-Project-Id header on every event. Omit it (or pass "default") to use your org's default Production project, which is the existing behavior. The same option is accepted by the create_raindrop_langchain(...) factory. Invalid slugs are ignored with a warning and no header is sent.
What Gets Captured
- LLM calls — model name, input, output, token usage, finish reason
- Tool calls — tool name, input arguments, output, duration (via
interaction.track_tool()spans) - Chains — execution tracking
- Retrievers — query and document count
- Errors — error type and message captured in event properties
- Extended token categories — cached tokens (
ai.usage.cached_tokens) and reasoning tokens (ai.usage.thoughts_tokens) when available from the provider (e.g. OpenAI) - Finish reason — captured as
ai.finish_reasonin event properties (e.g."stop","length")
Debug Mode
Enable verbose logging with debug=True:
raindrop = RaindropLangchain(
api_key="rk_...",
debug=True,
)
Identify Users
Associate events with a user after initialization:
raindrop.identify("user-123", {"name": "Alice", "plan": "pro"})
Track Signals
Send feedback, edits, or custom signals:
raindrop.track_signal(
event_id="evt-abc",
name="thumbs_up",
signal_type="feedback",
sentiment="POSITIVE",
)
Flushing and Shutdown
raindrop.flush() # flush pending data
raindrop.shutdown() # flush + release resources
API Reference
RaindropLangchain
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key |
Optional[str] |
None |
Raindrop API key. If None, telemetry is disabled |
user_id |
Optional[str] |
None |
Associate all events with a user |
convo_id |
Optional[str] |
None |
Group events into a conversation |
project_id |
Optional[str] |
None |
Route events to a specific project (slug); omit for the default Production project |
trace_chains |
bool |
True |
Track chain execution |
trace_retrievers |
bool |
True |
Track retriever calls |
filter_langgraph_internals |
bool |
True |
Filter LangGraph-internal chain events and deduplicate LLM callbacks |
event_name |
str |
"ai_generation" |
Event name applied to every event (the event field in the dashboard) |
tracing_enabled |
bool |
True |
Enable distributed tracing |
bypass_otel_for_tools |
bool |
True |
Bypass OTEL for tool spans |
debug |
bool |
False |
Enable debug logging |
Methods
| Method | Description |
|---|---|
handler |
Property — the LangChain callback handler to pass into config={"callbacks": [...]} |
flush() |
Flush all pending events to the Raindrop API |
shutdown() |
Flush remaining events and release resources |
identify(user_id, traits) |
Identify a user with optional traits |
track_signal(event_id, name, ...) |
Track a signal event |
Async Support
The callback handler inherits from LangChain's AsyncCallbackHandler and works with both synchronous and asynchronous LangChain invocations.
result = await model.ainvoke(
[HumanMessage(content="Hello!")],
config={"callbacks": [raindrop.handler]},
)
LangGraph Support
Works with LangGraph out of the box. The handler automatically filters LangGraph-internal chain events and deduplicates LLM callbacks. Pass the handler to the model inside your LLM node — not to graph.invoke(). See examples/langchain-langgraph-python-basic/ for a full example.
LangSmith Coexistence
Raindrop and LangSmith can run simultaneously. Set LANGSMITH_TRACING=false to disable LangSmith if you only want Raindrop.
Payload size bounds
Payloads the handler serializes itself — multi-modal chat content lists and
agent-action tool inputs — are bounded to 1,000,000 characters with a
...[truncated by raindrop] marker. The bound is enforced during
serialization (cost proportional to the cap, not the payload), so a multi-MB
content list (e.g. base64 image parts) can't stall your event loop inside a
synchronous callback. Plain-string prompts and tool outputs are capped by
the Raindrop SDK's own per-field limit (max_text_field_chars, raindrop-ai
= 0.0.51).
Known Limitations
- Multi-LLM chain data: In ReAct loops with multiple child LLMs, only the last child's data survives (Python SDK uses one-shot
track_aivs TS's accumulativeEventShipper.patch). - Error-path input loss: On LLM errors, the input captured during
on_llm_startis not forwarded to the finalized event.
Application Git metadata
RaindropLangchain(...) and create_raindrop_langchain(...) accept the keyword-only app_git option. It defaults to True: explicit Raindrop Git environment or deployment context is applied immediately, and the base SDK may perform one bounded background local-Git lookup from the process working directory. Event capture, flush, and shutdown never wait for that lookup. Pass False to disable enrichment, or pass an AppGitOptions mapping with commit_sha, commit_dirty, branch, source_directory, detect_branch, and/or auto_detect. Automatic branch discovery remains opt-in through detect_branch=True (or RAINDROP_GIT_DETECT_BRANCH=true).
For an ordinary in-process application, the process working directory is treated as the application-under-test checkout. A remote, coding, workflow, or observer process must not rely on its own checkout: pass app_git=False, provide explicit revision values, or set source_directory to the actual application checkout. Canonical per-operation properties remain authoritative. When supplying client=, configure app_git while constructing that Raindrop client; the supplied client is authoritative and the wrapper's app_git argument does not reconfigure it.
Release order is deliberate: first publish the base SDK feature, then publish the wrapper feature release with its minimum dependency coordinated to that base release. The existing raindrop-ai lower bound remains compatible, but application Git metadata is unavailable on an older core and must not be claimed complete until the base is upgraded. Until coordination assigns a released version, the wrapper checks for an explicit base app_git parameter and omits the option when unsupported. Explicit non-default configuration is debug-logged and omitted. Unsupported app_git is determined by signature inspection before construction, not by retrying initialization after a TypeError; Git configuration adds no initialization attempts and does not change any existing framework-specific initialization fallback. RaindropCallbackHandler(...) is unchanged and does not accept this option.
Testing
cd packages/langchain-python
pip install -e .
python -m pytest tests/ -v # unit tests (no external services)
End-to-end behavior is verified by the cross-SDK conformance harness. This
package ships a thin conformance driver at
conformance/driver.py that maps the shared scenario
corpus onto the wrapper's public API; known gaps are tracked as ticket-linked
entries in conformance/failures.txt. The fault
lane runs on every PR touching packages/*-python/**
(.github/workflows/conformance-wrappers-python.yml) against a local capture
server; the prod lane verifies delivery by reading back through the public
Query API. The harness is
pinned by commit SHA (HARNESS_REF). See the harness docs:
HOW-IT-WORKS ·
AGENTS ·
README.
Metadata
Release files for raindrop-langchain 0.0.12
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| raindrop_langchain-0.0.12.tar.gz | 33.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| raindrop_langchain-0.0.12-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.3 kB
Release files / raindrop_langchain-0.0.12.tar.gz
| Download URL | raindrop_langchain-0.0.12.tar.gz |
|---|---|
| Size | 33.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4381715f25f528a3599f0b6b3a8ca5a598bdf07bf277adb906cdbe61b9c5eb41
|
|
BLAKE2b-256 checksum How to use checksums |
cf3d70aac113bdb5456e6723d9f52e22883ae1b22ec68750ccb2ba3f8d5324de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / raindrop_langchain-0.0.12-py3-none-any.whl
| Download URL | raindrop_langchain-0.0.12-py3-none-any.whl |
|---|---|
| Size | 16.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
727b0df99368ebafc1e8e35a7670c78577f19065e714c834924762e54a288a75
|
|
BLAKE2b-256 checksum How to use checksums |
0b363eb7fda3e26397b89ecff37be147b788165986550bca376c5f2844bcb181
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|