Guides
Python quickstart
Install the Python SDK and give your app working memory in under 10 minutes — copy, paste, run.
This is the fastest path from nothing to a running Aether integration in Python. You'll install the SDK, set one environment variable, and store and recall per-user memories. Every snippet below is a complete, runnable script.
1. Install the SDK
pip install aether-ai
The package installs as aether-ai; the import name is aether. Python 3.9+ is supported. The only runtime dependency is httpx, which pip pulls in automatically.
2. Set your API key
Create a key in the Aether Dashboard and export it. Keep it out of your source — load it from the environment, a .env file, or your secrets manager.
export AETHER_API_KEY="your-api-key"
3. Store and recall memory
The Memory facade is the shortcut for per-user or per-agent memory. You give it an entity_id (a user, agent, session — whatever you want to scope memory to), then remember and recall in plain language. Every operation is automatically scoped to that entity, so one user never sees another's memories.
import os
from aether import Memory
# Scope all memory to one entity (here, a user)
memory = Memory("user-42", api_key=os.environ["AETHER_API_KEY"])
# Store a few memories
memory.remember("Prefers concise, bullet-point answers")
memory.remember("Working on a Next.js + Postgres side project")
memory.remember("Based in Berlin; books meetings in CET")
# Recall the most relevant ones for a query
for item in memory.recall("how should I format my replies?", k=3):
print(round(item.score, 3), item.text)
Run it. recall returns the memories ranked by relevance — the formatting preference comes back first, because Aether searches by meaning, not keywords:
0.61 Prefers concise, bullet-point answers
0.42 Working on a Next.js + Postgres side project
0.31 Based in Berlin; books meetings in CET
Each item carries the remembered text, its underlying id, and a score (higher is more relevant; the value is relative within a single recall call). That's working memory — persistent across processes, scoped to the entity, no schema to manage.
Use it in a prompt
To ground an LLM reply, recall the relevant memories and fold them into your system prompt:
context = "\n".join(f"- {m.text}" for m in memory.recall(user_message, k=5))
system = f"What you know about this user:\n{context}"
4. Manage memories
The same facade lists and deletes memories, all scoped to the entity:
# Newest-first chronological view
for item in memory.list(limit=10):
print(item.id, item.text)
# Delete one memory, or wipe everything for this entity
memory.forget("doc-id-from-a-memory-item")
deleted = memory.forget_all()
print(f"Deleted {deleted} memories")
5. Document round-trip
When you need direct control over documents and search instead of per-entity memory, use AetherClient. This is the lowest-friction round trip: insert text, search by meaning, and print the matched passage.
import os
from aether import AetherClient
client = AetherClient(api_key=os.environ["AETHER_API_KEY"])
doc = client.insert_text(
"Employees accrue 20 days of PTO per year.",
filename="pto-policy.txt",
)
print("inserted", doc.doc_id)
results = client.search("vacation days", k=3)
for hit in results:
print(hit.score, hit.doc_id, hit.passage)
Use retrieve instead of search when you want full document text for a RAG prompt:
results = client.retrieve("How much PTO do employees get?", k=3)
for hit in results:
print(hit.score, hit.content)
Use search instead of retrieve when you only need the ranked passage and score without downloading full content. See the 5-minute RAG guide for the full retrieve-then-generate pattern.
6. Async client
Use AsyncAetherClient in FastAPI, Starlette, async workers, or any app that already runs an event loop:
import asyncio
import os
from aether import AsyncAetherClient
async def main():
async with AsyncAetherClient(api_key=os.environ["AETHER_API_KEY"]) as client:
doc = await client.insert_text(
"Support is available Monday through Friday.",
filename="support-hours.txt",
)
results = await client.search("when is support open?", k=3)
print(doc.doc_id, results[0].score)
asyncio.run(main())
7. Handle errors
Catch AetherApiError for HTTP responses from Aether. Inspect status_code, error_code, and is_retryable to decide whether to retry, show an upgrade prompt, or fail fast.
from aether import AetherApiError, AetherClient
client = AetherClient()
try:
client.insert_text("Important note", filename="note.txt")
except AetherApiError as exc:
if exc.status_code == 429:
print("Rate limited. Back off before retrying.")
elif exc.error_code == "free_limit_exceeded":
print("Plan limit reached. Upgrade before retrying this insert.")
elif exc.is_retryable:
print(f"Transient Aether error: {exc.status_code}")
else:
raise
Next steps
- PyPI package — published versions and install command
- 5-minute RAG — wire retrieval into an LLM for grounded answers
- Tuning retrieval — pick
k, read score, filter weak matches - Multi-tenant patterns — scope memory and documents per tenant safely
- API Reference — full endpoint and method documentation