Tex Python SDK
SuperMemory-compatible memory SDK for Python.
Installation
pip install tex-sdk
Optional HTTP/2 support:
pip install "tex-sdk[http2]"
Requires Python 3.9+.
Quick Start
API key
from tex import Tex
client = Tex(api_key="sk-...", base_url="http://localhost:8000")
client.add("The quick brown fox jumps over the lazy dog.")
results = client.search.documents("fox")
Environment variables
Set TEX_API_KEY and TEX_BASE_URL, then:
from tex import Tex
client = Tex()
Per-user clients (production)
To act as one end user of your app, pass that user's id alongside your API key.
The SDK makes a single POST /auth/token-exchange with
{api_key, user_id, session_id} and receives a JWT minted for that user:
import os
from tex import Tex
# base_url falls back to TEX_BASE_URL, api_key to TEX_API_KEY
alice = Tex(
api_key=os.environ["TEX_API_KEY"],
base_url=os.environ["TEX_BASE_URL"],
org_id="org1", # optional; if set, must match the key's org
user_id="alice",
session_id="chat-42", # optional
)
alice.recall(q="what did I order last week?", session_id="chat-42") # every call is scoped to alice
- The API key must carry an impersonation-capable scope, normally
impersonate_user(also accepted:tenant:write:any_user,agent,service,system,*). Without one the backend refuses theuser_idand the SDK raisesPermissionDeniedErrorsaying so. - The minted token carries an
actclaim naming the key: it is locked to that user and cannot impersonate anyone else. The SDK also checks the returned token is really for the requested user. - On expiry the SDK uses the refresh token, and otherwise re-exchanges for the
same
user_id. - The per-user token is sent on every call, including the
Supermemory-compatible ones (
memories.add,documents.add,search.memories,profile, ...), so they also act as that user with that user's team scopes.container_tagon such a client must be omitted or equal the user id; naming another user is refused with 403container_tag_not_permitted. (Requires a backend that accepts per-user tokens on/v3and/v4.) - Omit
user_idto act as the key's own identity; compat calls then send the raw API key andcontainer_tagselects the end user, Supermemory-style.
Org + user login (development servers only)
from tex import Tex
client = Tex(base_url="http://localhost:8000", org_id="org1", user_id="user1")
With no API key the SDK calls POST /auth/login, which exists only when the
backend runs with DEBUG=true. Production returns 403 and the SDK raises
PermissionDeniedError pointing you to the per-user API key pattern above.
Documents
Add, retrieve, update, delete, list, and batch-manage documents.
# Top-level shortcut
resp = client.add("Document content", container_tag="notes")
# Equivalent resource call
resp = client.documents.add("Document content", container_tag="notes")
# Get by ID
doc = client.documents.get("doc_abc123")
# Update
client.documents.update("doc_abc123", content="Updated content")
# Delete
client.documents.delete("doc_abc123")
# List with filters
docs = client.documents.list(container_tags=["notes"], limit=20)
# Batch add
client.documents.batch_add(
["First document", "Second document"],
container_tag="batch-import",
)
# Bulk delete
client.documents.delete_bulk(container_tags=["old-tag"])
Search
Document search
results = client.search.documents("quarterly revenue", limit=10)
# Alias
results = client.search.execute("quarterly revenue", limit=10)
Memory search
results = client.search.memories("user preferences", container_tag="user1")
Memories
# Add memories
client.memories.add(
[{"content": "User prefers dark mode"}],
container_tag="prefs",
)
# Forget a memory
client.memories.forget("prefs", id="mem_abc123")
# Update a memory
client.memories.update_memory("prefs", "User prefers light mode", id="mem_abc123")
Profile
profile = client.profile("user-container-tag")
print(profile.profile)
Tex-Unique Features
NLQ (Natural Language Query)
result = client.nlq.execute("What meetings did I have last week?")
print(result.text)
print(result.evidence)
Episodes
# Store a conversation
client.episodes.store(
[
{"role": "user", "content": "Book a table for two"},
{"role": "assistant", "content": "Which restaurant?"},
],
episode_id="ep_001",
)
# List episodes
episodes = client.episodes.list(limit=10)
Preferences
client.preferences.store([
{"key": "drink", "value": "espresso", "confidence": 0.9},
])
DB
result = client.db.query("MATCH (n) RETURN n LIMIT $limit", params={"limit": 5})
schema = client.db.schema()
Auth
info = client.auth.whoami()
Jobs
status = client.jobs.get("job_abc123")
Error Handling
The SDK provides a detailed error hierarchy:
TexError
APIError
APIConnectionError
APITimeoutError
APIStatusError
BadRequestError (400)
AuthenticationError (401)
PermissionDeniedError (403)
NotFoundError (404)
ConflictError (409)
UnprocessableEntityError (422)
RateLimitError (429)
InternalServerError (500+)
APIResponseValidationError
from tex import Tex, NotFoundError, AuthenticationError, APIStatusError
client = Tex(api_key="sk-...", base_url="http://localhost:8000")
try:
doc = client.documents.get("nonexistent")
except NotFoundError as e:
print(f"Not found: {e}")
except AuthenticationError as e:
print(f"Auth failed: {e}")
except APIStatusError as e:
print(f"HTTP {e.status_code}: {e.message}")
print(f"Request ID: {e.request_id}")
Active memory inactivity window
Conversation turns stored with conversations.remember land in short-term active memory first. An
active-memory episode (one per session_id) is closed and consolidated into long-term memory once it has been
idle for its inactivity window — 30 minutes by default. Tune it to the use case: a support chat can close
after a few minutes, a long-running agent task may need hours.
# Per conversation (the episode keeps this window for later writes)
client.conversations.remember(turns, session_id="ticket-981", inactivity_timeout_seconds=2 * 60 * 60)
# Client-wide default for every write that does not pass its own
client = Tex(api_key="sk-...", active_inactivity_timeout_seconds=10 * 60)
- Resolution: per-call value → client default → org default (set by an org admin with
PATCH /me/settings{"active_memory_inactivity_seconds": 3600}) → 30 minutes. - Bounds: 300–86400 seconds (5 minutes to 24 hours). Invalid values raise
InvalidInactivityTimeoutErrorbefore any request. memories.addandmemories.update_memoryaccept the sameinactivity_timeout_seconds.
Configuration
Use TexConfig and TexEndpoints for advanced configuration:
from tex import Tex, TexConfig, TexEndpoints
config = TexConfig(
base_url="https://api.example.com",
api_key="sk-...",
timeout_s=30.0,
max_retries=3,
http2=True,
active_inactivity_timeout_seconds=3600, # optional; see "Active memory inactivity window"
endpoints=TexEndpoints(
db_query="/custom/db/query",
db_schema="/custom/db/schema",
),
)
client = Tex(config=config)
Default timeout is 60 seconds. Default max retries is 2.
Migration from SuperMemory
| SuperMemory | Tex SDK |
|---|---|
client.add(content) |
client.add(content) or client.documents.add(content) |
client.documents.get(id) |
client.documents.get(id) |
client.documents.update(id) |
client.documents.update(id) |
client.documents.delete(id) |
client.documents.delete(id) |
client.documents.list() |
client.documents.list() |
client.documents.batch_add(docs) |
client.documents.batch_add(docs) |
client.search.execute(q) |
client.search.execute(q) or client.search.documents(q) |
client.search.memories(q) |
client.search.memories(q) |
client.memories.add(memories) |
client.memories.add(memories) |
client.memories.forget(tag) |
client.memories.forget(tag) |
client.profile(tag) |
client.profile(tag) |
Tex extends SuperMemory with additional resources: nlq, episodes, preferences, db, auth, and jobs.
HTTP/2
HTTP/2 is enabled by default. If the h2 package is not installed, the SDK falls back to HTTP/1.1 automatically. To install with HTTP/2 support:
pip install "tex-sdk[http2]"
To explicitly disable HTTP/2:
client = Tex(api_key="sk-...", base_url="http://localhost:8000", http2=False)
Metadata
Release files for tex-sdk 1.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tex_sdk-1.2.2.tar.gz | 34.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tex_sdk-1.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 64.3 kB
Release files / tex_sdk-1.2.2.tar.gz
| Download URL | tex_sdk-1.2.2.tar.gz |
|---|---|
| Size | 34.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
919de004aa979f52af8bf1cd3b6a7397df99775756e5bcc178b2138ecc3bb163
|
|
BLAKE2b-256 checksum How to use checksums |
7aa73a0f2661fd6ab5c94e8fb55760dba05ed1d2ae11b09d2fef07a9d20d1160
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / tex_sdk-1.2.2-py3-none-any.whl
| Download URL | tex_sdk-1.2.2-py3-none-any.whl |
|---|---|
| Size | 30.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8dce02080b2059856a90036d5b4ee07fdae86d7208ff32d6f8b05207b91a111a
|
|
BLAKE2b-256 checksum How to use checksums |
97d5820b33885b84b8d6d47f1107dfeb4768a26f034a79d813ce35caf15d1959
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|