Skip to main content

lyzr-memory-client

Typed sync/async Python client for the Lyzr Memory /v1 API. Use it from PepGenX (JWT-only: an Okta bearer token and nothing else) 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

JWT-only posture: the SDK mints an Okta client-credentials token and sends Authorization: Bearer <jwt> and nothing else — no API key, no team_id / project_id / user_id headers. The server derives tenancy from the token, so pass instance defaults such as project_id= / owner_id= yourself if your calls should inherit them.

import os

from lyzr_memory_client import MemoryClient

client = MemoryClient.for_pepgenx(
    os.environ["LYZR_MEMORY_BASE_URL"],  # APIM base + memory route from onboarding
    client_id=os.environ["OIDC_CLIENT_ID"],
    client_secret=os.environ["OIDC_CLIENT_SECRET"],
    issuer=os.environ["OIDC_ISSUER"],  # Okta: token URL is {issuer}/v1/token
    scope="pepgenx2.0",
    project_id=os.environ.get("PEPGENX_PROJECT_ID"),  # optional instance default
)

for_pepgenx takes exactly one credential source: client_id + client_secret (with issuer or token_url), a caller-owned token_provider, or a static token=. A provider it mints is closed by client.close(). Anything else raises ConfigurationError.

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.

The legacy composite header contract (API key plus team_id / project_id / user_id) is compatibility only, reached by passing auth=PepGenXAuth(...) to the constructor; it is documented in 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
OIDC_TOKEN_URL / OIDC_ISSUER Token endpoint, or Okta issuer (issuer → {issuer}/v1/token)
OIDC_CLIENT_ID OAuth client id
OIDC_CLIENT_SECRET OAuth client secret
OIDC_SCOPE Optional space-delimited scopes
OIDC_AUDIENCE Optional audience claim for the token request

ClientCredentials.from_env() reads the OIDC_* variables above; pass prefix= to use a different naming scheme.

With auth=None, MemoryClient(...) resolves auth from the environment in this order: OIDC_CLIENT_ID + OIDC_CLIENT_SECRET (with OIDC_ISSUER or OIDC_TOKEN_URL) → a minting BearerAuth, then PEPGENX_API_KEY, then LYZR_API_KEY, then LYZR_MEMORY_TOKEN. A provider built from OIDC_* is owned by the client and closed with it.

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.2.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.2.0
File Size Uploaded
lyzr_memory_client-0.2.0.tar.gz 118.9 kB Details

Built distribution (wheel)

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

Total release size: 180.9 kB

Release files / lyzr_memory_client-0.2.0.tar.gz

Download URL lyzr_memory_client-0.2.0.tar.gz
Size 118.9 kB
Tags Source
SHA-256 checksum
How to use checksums
6970c1ef899d80cdae09ca6e335cc0e95c3129598321553e1645269ffdaeacce
BLAKE2b-256 checksum
How to use checksums
f44d677c52ed13558f47a69a1a548987fb716b90138b4dd754959c6e7dfee981
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.2.0-py3-none-any.whl

Download URL lyzr_memory_client-0.2.0-py3-none-any.whl
Size 62.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a86af9241588a57d427373c4f563830cacc3bfcb4adce7beb9bac206c9221426
BLAKE2b-256 checksum
How to use checksums
95726df0cf0a44f687eb23bd04b83423dea7dd4cb61036656f56196940cc952d
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

This release

0.2.0 This release

2 release files

0.1.0

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