Python SDK for AOps — prompt version management
Project description
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
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 aops-0.8.0.tar.gz.
File metadata
- Download URL: aops-0.8.0.tar.gz
- Upload date:
- Size: 18.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9d0461e0e1012df38cf993701992ccd4bc9cc6128f88b015e3d1ca0ece81359
|
|
| MD5 |
48fa8cd1d2036e889175cd5a4d7cfe62
|
|
| BLAKE2b-256 |
3815622534db8f1667fd4a5eee55e291c7c3e60adfe034a14ecf49f1101c6831
|
Provenance
The following attestation bundles were made for aops-0.8.0.tar.gz:
Publisher:
release.yml on cow-coding/aops-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aops-0.8.0.tar.gz -
Subject digest:
c9d0461e0e1012df38cf993701992ccd4bc9cc6128f88b015e3d1ca0ece81359 - Sigstore transparency entry: 1133490634
- Sigstore integration time:
-
Permalink:
cow-coding/aops-python@628843ca127e48a816b0406d40b958aa5e91c5da -
Branch / Tag:
refs/heads/main - Owner: https://github.com/cow-coding
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@628843ca127e48a816b0406d40b958aa5e91c5da -
Trigger Event:
push
-
Statement type:
File details
Details for the file aops-0.8.0-py3-none-any.whl.
File metadata
- Download URL: aops-0.8.0-py3-none-any.whl
- Upload date:
- Size: 21.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc8813182ed17b0f7accec0c78fbe33dd9601fdde18047b24e854692f22e0519
|
|
| MD5 |
4169d6de64183df4bcb08d4754d91ef9
|
|
| BLAKE2b-256 |
3d6a3d22b8bf2af705e0336ad4007898328c1d146ca22f035115bbba312504cc
|
Provenance
The following attestation bundles were made for aops-0.8.0-py3-none-any.whl:
Publisher:
release.yml on cow-coding/aops-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aops-0.8.0-py3-none-any.whl -
Subject digest:
cc8813182ed17b0f7accec0c78fbe33dd9601fdde18047b24e854692f22e0519 - Sigstore transparency entry: 1133490643
- Sigstore integration time:
-
Permalink:
cow-coding/aops-python@628843ca127e48a816b0406d40b958aa5e91c5da -
Branch / Tag:
refs/heads/main - Owner: https://github.com/cow-coding
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@628843ca127e48a816b0406d40b958aa5e91c5da -
Trigger Event:
push
-
Statement type: