Skip to main content

lyzr-memory-client

Typed sync/async Python client for the Lyzr Memory /v1 API. Use it from PepGenX (Okta bearer + API key + tenant headers, or key-only) and from Lyzr-hosted deployments (x-api-key). Built on httpx and pydantic.

PyPI CI

Install

pip install lyzr-memory-client
# or
uv add lyzr-memory-client

Requires Python 3.10+. Runtime dependencies: httpx and pydantic only.

PepGenX quick start

Composite posture: Okta client-credentials token plus the five house-style headers. for_pepgenx also seeds instance defaults project_id and owner_id=user_id so top-level calls inherit them.

import os

from lyzr_memory_client import ClientCredentials, MemoryClient

tokens = ClientCredentials(
    issuer=os.environ["LYZR_OAUTH_ISSUER"],
    client_id=os.environ["LYZR_OAUTH_CLIENT_ID"],
    client_secret=os.environ["LYZR_OAUTH_CLIENT_SECRET"],
    scope=os.environ.get("LYZR_OAUTH_SCOPE"),
)

client = MemoryClient.for_pepgenx(
    os.environ["LYZR_MEMORY_BASE_URL"],  # APIM base + memory route from onboarding
    api_key=os.environ["PEPGENX_API_KEY"],
    team_id=os.environ["PEPGENX_TEAM_ID"],
    project_id=os.environ["PEPGENX_PROJECT_ID"],
    user_id=os.environ["PEPGENX_USER_ID"],
    token_provider=tokens,
)

me = client.whoami()
print(me.subject, me.org_id, me.roles)

client.add(
    [
        {"role": "user", "content": "I prefer short answers."},
        {"role": "assistant", "content": "Understood."},
    ],
    session_id="ses_demo",
    sync_extraction=True,
)

hits = client.search("preferred answer length")
ctx = client.get_context([{"role": "user", "content": "Remind me of my preference."}])
client.clear_session(session_id="ses_demo")
print(hits.count, ctx.context_string)

Admin onboarding

Import a PepGenX onboarding key and register the service principal before memory calls succeed under MEMORY_AGENT_REGISTRY_ENFORCE:

# Use a bootstrap/admin client that can mint keys and registrations.
created = client.admin.api_keys.create(
    "my-agent-key",
    org_id=os.environ["PEPGENX_TEAM_ID"],
    project_id=os.environ["PEPGENX_PROJECT_ID"],
    secret=os.environ["PEPGENX_ONBOARDING_SECRET"],  # their onboarding key value
)

client.admin.agent_registrations.upsert(
    client_id=os.environ["PEPGENX_OIDC_CLIENT_ID"],
    asset_id="ast_my_agent",
    team_id=os.environ["PEPGENX_TEAM_ID"],
    project_id=os.environ["PEPGENX_PROJECT_ID"],
)

Without a registration (or with enabled=false), memory reads and writes return 403 memory_not_enabled. See docs/AUTH.md and docs/PEPGENX.md.

Key-only (no Okta)

When the deployment runs without bearer auth, omit token and tenant headers:

client = MemoryClient.for_pepgenx(
    os.environ["LYZR_MEMORY_BASE_URL"],
    api_key=os.environ["PEPGENX_API_KEY"],
    team_id=None,
    project_id=None,
)

Only x-pepgenx-apikey is sent. See docs/AUTH.md and docs/PEPGENX.md.

Lyzr-hosted quick start

Documented hosted base URL: https://memory.studio.lyzr.ai. Always pass base_url= or set LYZR_MEMORY_BASE_URL; there is deliberately no compiled default hostname.

import os

from lyzr_memory_client import MemoryClient

client = MemoryClient.for_lyzr(
    base_url=os.environ.get("LYZR_MEMORY_BASE_URL", "https://memory.studio.lyzr.ai"),
    api_key=os.environ["LYZR_API_KEY"],
)

Environment variables

Variable Purpose
LYZR_MEMORY_BASE_URL Service base URL (required unless base_url= is passed)
LYZR_MEMORY_TOKEN Bearer token for plain BearerAuth resolution
LYZR_API_KEY Lyzr-hosted x-api-key
PEPGENX_API_KEY PepGenX API key (x-pepgenx-apikey by default)
PEPGENX_TEAM_ID Tenant team_id header
PEPGENX_PROJECT_ID Tenant project_id header
PEPGENX_USER_ID Attribution user_id / GPID header
PEPGENX_API_KEY_HEADER Override API-key header name (default x-pepgenx-apikey)
LYZR_OAUTH_TOKEN_URL / LYZR_OAUTH_ISSUER Token endpoint, or Okta issuer (issuer → {issuer}/v1/token)
LYZR_OAUTH_CLIENT_ID OAuth client id
LYZR_OAUTH_CLIENT_SECRET OAuth client secret
LYZR_OAUTH_SCOPE Optional space-delimited scopes
LYZR_OAUTH_AUDIENCE Optional audience claim for the token request

When constructing MemoryClient(base_url=None, auth=None), auth auto-resolves in this order: PEPGENX_* → LYZR_API_KEY → LYZR_MEMORY_TOKEN.

Async

from lyzr_memory_client import AsyncMemoryClient

async with AsyncMemoryClient.for_lyzr(base_url=..., api_key=...) as client:
    me = await client.whoami()

AsyncMemoryClient mirrors MemoryClient; call await client.aclose() if you are not using the context manager.

Resources and top-level helpers

Namespaces: memories, summaries, conversations, providers, auth, admin.api_keys, admin.agent_registrations, health.

Convenience methods on the client apply instance defaults (owner_id, agent_id, session_id, project_id, provider_type): add, search, get_context, list, list_all, messages, clear_session, get, update, delete, graph_query, whoami, health, ready. Use with_defaults(...) to get a new client sharing the same transport.

Retries and timeouts

Defaults: 30 s total timeout, 5 s connect; 3 attempts with exponential backoff 1 s → 30 s (jitter); Retry-After is honoured when present.

POST /v1/memories is not idempotent server-side. The SDK retries it only on connection-phase failures and HTTP 429 / 503, never after a read timeout. Full retry rules: docs/ERRORS.md.

Eventual consistency

Fact extraction runs asynchronously unless you pass sync_extraction=True on add. Search and list may lag briefly after a fire-and-forget add.

Tenancy rules

  • Body/query project_id must match the authenticated project when the principal carries one; mismatch → 400 tenant_key_conflict.
  • Service principals (client-credentials tokens) are bound to their Okta subject as agent_id; they cannot choose a different agent_id or widen via agent_ids.

Error handling

from lyzr_memory_client import PermissionDeniedError

try:
    client.update(memory_id, content="…")
except PermissionDeniedError as e:
    print(e.code, e.request_id, e.detail)

See docs/ERRORS.md for the full hierarchy and .code vocabulary.

Transaction ids

Pass transaction_id= on any resource call. The SDK sends it as the transaction_id header; the service echoes the correlation id in X-Request-Id (available as APIError.request_id).

Security

  • Credentials are wrapped in Secret and never appear in logs or repr.
  • TLS verification is on by default (verify=True).
  • Corporate CA: MemoryClient(..., verify="/path/to/ca.pem").
  • HTTP proxies follow httpx trust_env (standard HTTP_PROXY / HTTPS_PROXY / NO_PROXY).

Compatibility

SDK 0.1.x targets Lyzr Memory API v1 as frozen in spec/SOURCE (OpenAPI pin: spec/openapi.json).

Development

Target Purpose
make sync uv sync --locked
make lint / make fmt Ruff check / format
make type mypy --strict
make test pytest with ≥90% coverage
make test-e2e Live e2e (-m e2e)
make security bandit + pip-audit
make build Wheel/sdist + twine check
make gen-models Regenerate models (scripts/gen_models.sh)
make openapi-check Diff against live export (scripts/export_openapi_memory.py) when MEMORY_REPO is set
make sync-core Vendor _core from/to the sibling RAG client
make all lint + type + test + security + build

License

MIT. See LICENSE.

Metadata

Release files for lyzr-memory-client 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lyzr-memory-client 0.1.0
File Size Uploaded
lyzr_memory_client-0.1.0.tar.gz 108.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lyzr-memory-client 0.1.0
File Interpreter ABI Platform
lyzr_memory_client-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 167.7 kB

Release files / lyzr_memory_client-0.1.0.tar.gz

Download URL lyzr_memory_client-0.1.0.tar.gz
Size 108.8 kB
Tags Source
SHA-256 checksum
How to use checksums
994cc9c3650b747f3aec585674dfaebde9195ce2e67e13bb4ff5e8b78aed63a3
BLAKE2b-256 checksum
How to use checksums
c645a8d26a50559aa96cc7455a808e98d65c5cf116937e30a22dcd7b48156a41
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 22, 2026.

Transparency log

Release files / lyzr_memory_client-0.1.0-py3-none-any.whl

Download URL lyzr_memory_client-0.1.0-py3-none-any.whl
Size 58.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cacb0127a43a0d79db54c0bc162d46b934340c89b8da1040d6858b5534d01493
BLAKE2b-256 checksum
How to use checksums
3d7d7faa9151856294d0377d835893a00e5b6ce5df0eab62c21745536ea78dbf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 22, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page