aops
Python SDK for AOps — prompt version management and agent observability platform.
- Pull prompts from the AOps backend at runtime (any LLM SDK)
- Trace runs — record which chains were called, in what order, and with what latency
- Capture LLM I/O — log inputs and outputs per chain for full observability
- Live updates — background polling reflects prompt edits without redeployment
Installation
pip install aops
With LangChain integration:
pip install "aops[langchain]" langchain-openai
Quick Start
1. Get an API key
In the AOps UI: Agent detail page → API Keys → New API Key
The key embeds the server host — no separate base_url needed.
2. Initialize and pull a prompt
import aops
aops.init(api_key="aops_...", agent="my-agent")
prompt = aops.pull("my-chain") # returns str
3. Trace a run
Wrap your agent logic in aops.run() to record chain call order and latency:
with aops.run():
classify_prompt = aops.pull("classify") # traced
category = call_llm(classify_prompt, user_input)
respond_prompt = aops.pull(f"respond-{category}") # traced
return call_llm(respond_prompt, user_input)
# → posted to backend on exit, visible in the Flow tab
Capturing LLM Input / Output
Input is captured at pull() time by passing variables. Output is captured after the LLM responds via your chosen integration.
Step 1 — Pass variables to pull()
with aops.run():
prompt = aops.pull("classify", variables={"inquiry": user_input})
# ↑ input = rendered prompt (chain instructions + substituted user_input)
Step 2 — Capture output
Choose the integration that fits your stack.
Option A — LangChain / LCEL (AopsCallbackHandler)
from aops.langchain import AopsCallbackHandler
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage
handler = AopsCallbackHandler()
llm = ChatOpenAI(model="gpt-4o-mini", callbacks=[handler])
with aops.run():
prompt = aops.pull("classify", variables={"inquiry": user_input})
result = llm.invoke([SystemMessage(content=prompt), HumanMessage(content=user_input)])
# output recorded automatically by handler
Option B — OpenAI SDK (wrap())
import openai
from aops import wrap
client = wrap(openai.OpenAI())
with aops.run():
prompt = aops.pull("classify", variables={"inquiry": user_input})
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "system", "content": prompt}, {"role": "user", "content": user_input}],
)
# output recorded automatically by proxy
wrap()supportsopenai.OpenAI(sync) only. For async, useAopsCallbackHandler.
Option C — Any framework (@aops.trace decorator)
Captures the function's first argument as input and return value as output. Works with any LLM library.
@aops.trace("classify")
def classify(user_input: str) -> str:
prompt = aops.pull("classify", variables={"inquiry": user_input})
return call_any_llm(prompt, user_input)
with aops.run():
result = classify(user_input)
Supports async def and class methods transparently.
Supported LLM SDKs
aops.pull() returns a plain str — works with any LLM SDK out of the box.
OpenAI
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "system", "content": aops.pull("my-chain")}, ...],
)
Anthropic
from anthropic import Anthropic
client = Anthropic()
message = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=1024,
system=aops.pull("my-chain"),
messages=[{"role": "user", "content": "Hello!"}],
)
LangChain (prompt as SystemMessagePromptTemplate)
from aops.langchain import pull # returns SystemMessagePromptTemplate
from langchain_core.prompts import ChatPromptTemplate, HumanMessagePromptTemplate
from langchain_openai import ChatOpenAI
prompt = pull("my-chain")
chain = (
ChatPromptTemplate.from_messages([
prompt,
HumanMessagePromptTemplate.from_template("{user_input}"),
])
| ChatOpenAI(model="gpt-4o-mini")
)
result = chain.invoke({"user_input": "Hello!"})
Requirements
- Python 3.12+
- AOps backend running (self-hosted) — see github.com/cow-coding/aops
- API key from the AOps UI
Examples
examples/
openai_example.py pull() + wrap() + OpenAI SDK
anthropic_example.py pull() + Anthropic SDK
langchain_example.py AopsCallbackHandler + @chain_prompt
live_updates.py background polling / live update detection
Documentation
| Guide | Description |
|---|---|
| Quickstart | Step-by-step: from zero to first trace |
| Configuration | aops.init(), API keys, environment variables |
| API Reference | All public APIs: pull(), run(), wrap(), @trace, AopsCallbackHandler |
| Run Tracing | aops.run(), I/O capture, concurrency |
| Live Updates | Background polling, prompt refresh patterns |
| LangChain | LCEL patterns, class-based chains, callback handler |
Integration Quick References
| Integration | Guide |
|---|---|
| LangChain / LCEL | docs/integrations/langchain.md |
| OpenAI SDK | docs/integrations/openai.md |
@aops.trace decorator |
docs/integrations/decorator.md |
License
MIT
Metadata
Release files for aops 0.8.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| aops-0.8.0.tar.gz | 18.3 kB | With provenance | Details for aops-0.8.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| aops-0.8.0-py3-none-any.whl | Python 3 | none | any | Details for aops-0.8.0-py3-none-any.whl |
Total release size: 39.5 kB
Release files / aops-0.8.0.tar.gz
| Download URL | aops-0.8.0.tar.gz |
|---|---|
| Size | 18.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c9d0461e0e1012df38cf993701992ccd4bc9cc6128f88b015e3d1ca0ece81359
|
|
BLAKE2b-256 checksum How to use checksums |
3815622534db8f1667fd4a5eee55e291c7c3e60adfe034a14ecf49f1101c6831
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 19, 2026.
Transparency logRelease files / aops-0.8.0-py3-none-any.whl
| Download URL | aops-0.8.0-py3-none-any.whl |
|---|---|
| Size | 21.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cc8813182ed17b0f7accec0c78fbe33dd9601fdde18047b24e854692f22e0519
|
|
BLAKE2b-256 checksum How to use checksums |
3d6a3d22b8bf2af705e0336ad4007898328c1d146ca22f035115bbba312504cc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 19, 2026.
Transparency logSecurity for aops 0.8.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for aops-0.8.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 19, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.