Skip to main content

Official Python SDK for the Lag API

Project description

lagclient

The official Python SDK for the Lag API.

lagclient is a hand-written REST client covering the public Lag API: users, friends, DMs, servers, rooms, room messages, events, and image uploads. It does not include the WebSocket protocol or the voice client - those are out of scope for this package.

Ships both a synchronous Client (backed by httpx.Client) and an asynchronous AsyncClient (backed by httpx.AsyncClient), sharing a single Pydantic v2 model layer.

  • Typed response models with autocomplete and validation.
  • Typed exception hierarchy with automatic retries on transient failures.
  • Cursor pagination helpers (sync and async iterators).
  • Multipart image upload from path, bytes, or file-like.
  • Zero required dependencies beyond httpx and pydantic.

Install

pip install lagclient

Requires Python 3.9+.

Quickstart

Synchronous

import os
from lagclient import Client

with Client(token=os.environ["LAG_TOKEN"]) as client:
    me = client.users.me()
    print(f"Hello, {me.display_name or me.username}")

    for server in client.servers.list():
        print(f"- {server.name} ({server.member_count} members)")

Asynchronous

import asyncio
import os
from lagclient import AsyncClient

async def main() -> None:
    async with AsyncClient(token=os.environ["LAG_TOKEN"]) as client:
        me = await client.users.me()
        print(f"Hello, {me.display_name or me.username}")

        for server in await client.servers.list():
            print(f"- {server.name}")

asyncio.run(main())

Authentication

The SDK accepts any Bearer token the API would accept:

  • A Personal Access Token (lag_pat_*) - the recommended option for scripts, bots, and CI. Create one in the Lag web app under settings, or via the lag CLI with lag auth login.
  • A Supabase JWT - useful when you already have an authenticated session (e.g. inside a web backend).

The token is sent as Authorization: Bearer <token> on every request. The SDK does not implement OAuth flows, refresh tokens, or browser-based login - obtain a token elsewhere and pass it in.

Configuration

client = Client(
    token="lag_pat_...",
    base_url="https://api.trylag.com",  # default
    timeout_seconds=30.0,               # default
    max_retries=2,                       # default
    user_agent="my-app/1.0",             # optional override
    extra_headers={"X-My-Header": "v"}, # optional extra headers
    # http_client=httpx.Client(...)     # bring your own
)

max_retries controls how many times the client retries on a transient failure (5xx, 429, network error). Backoff is exponential with jitter, capped at ~8s. The server's Retry-After header is honored on 429.

Both clients are also usable without a context manager:

client = Client(token="lag_pat_...")
try:
    client.users.me()
finally:
    client.close()

Resources

Every resource hangs off the client instance. The async client has the exact same tree, just with await in front of each call.

Attribute What it covers
client.system /health, /version, /system-status, /config
client.users /users/me, /users/me/avatar, /users/:id, /users/search, Steam helpers
client.friends list, requests, send/accept/decline, remove, block
client.dms conversations + messages with cursor pagination
client.servers servers CRUD, icon upload, leave
client.servers.invites create / list / revoke / preview / join
client.servers.members kick, ban, mute (and lists of active bans/mutes)
client.servers.roles role CRUD and assignment
client.servers.rooms voice rooms
client.servers.rooms.messages room chat: list/send/edit/delete with cursor pagination
client.events server events: list/create/get/update/cancel/RSVP
client.events.guests host-side guest moderation
client.events.templates recurring event templates
client.images multipart upload, metadata, status, delete

Pagination

DM and room message endpoints return {messages, hasMore, nextCursor}. You can walk pages yourself:

cursor = None
while True:
    page = client.dms.list_messages("c1", limit=50, cursor=cursor)
    for msg in page["messages"]:
        handle(msg)
    if not page["hasMore"] or page["nextCursor"] is None:
        break
    cursor = page["nextCursor"]

Or use the built-in iterator helpers:

# Sync
for page in client.dms.iter_messages("c1", limit=50):
    for msg in page.items:
        handle(msg)

# Async
async for page in async_client.dms.iter_messages("c1", limit=50):
    for msg in page.items:
        handle(msg)

The same pattern works for room messages via client.servers.rooms.messages.iter(server_id, room_id).

Image upload

# From a file path:
client.images.upload("./avatar.png", purpose="avatar")

# From raw bytes:
with open("./avatar.png", "rb") as f:
    client.images.upload(
        f.read(),
        purpose="avatar",
        filename="avatar.png",
        content_type="image/png",
    )

# From a file-like:
with open("./cover.jpg", "rb") as f:
    client.images.upload(f, purpose="event_cover", filename="cover.jpg")

The maximum upload size is 25 MiB.

Error handling

Every non-2xx response becomes a typed exception you can catch precisely:

from lagclient import (
    LagAPIError,
    LagAuthError,
    LagPermissionError,
    LagNotFoundError,
    LagConflictError,
    LagRateLimitError,
    LagServerError,
    LagConnectionError,
)

try:
    client.servers.get("does-not-exist")
except LagNotFoundError:
    print("not there")
except LagRateLimitError as err:
    print(f"slow down - retry after {err.retry_after_seconds}s")
except LagAPIError as err:
    print(f"{err.status}: {err}")

Network failures (DNS, refused, timeouts before any response) are raised as LagConnectionError. Everything else is a subclass of LagAPIError.

Local development

python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest
mypy src/lagclient
ruff check src tests
python -m build   # produces wheel + sdist

Tests use respx to mock httpx transport - no real API is required. Every resource has its own test file in tests/.

Related

  • The Lag API itself - product/apps/api/ in the Lag monorepo.
  • @lag/sdk for TypeScript / Node - sibling package in sdks/node/.
  • The lag CLI in cli/ - also MIT licensed.

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lagclient-0.1.0.tar.gz (27.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lagclient-0.1.0-py3-none-any.whl (32.7 kB view details)

Uploaded Python 3

File details

Details for the file lagclient-0.1.0.tar.gz.

File metadata

  • Download URL: lagclient-0.1.0.tar.gz
  • Upload date:
  • Size: 27.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for lagclient-0.1.0.tar.gz
Algorithm Hash digest
SHA256 dea6e9502ff1173e22021c4f6e647a9ef12b225a6d2f9e421312bb06b7406b5c
MD5 e578c968f89071a0fc4afa27fda3b951
BLAKE2b-256 03d21c3236b5fe5e724e18886352f304d16acd68b6d53da96bc712ac53b4b2e5

See more details on using hashes here.

Provenance

The following attestation bundles were made for lagclient-0.1.0.tar.gz:

Publisher: release.yml on lag-app/sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lagclient-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: lagclient-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 32.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for lagclient-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 110a43f6c4c907893dd3339c6f971d5de7a4e4f79c54c244a808ba12804f4a58
MD5 eaef1ede5f9a22fea0758650f3fa5475
BLAKE2b-256 4ebbb42af156dceee1f9998e1b030230864a147018524cb50f20629304e529b9

See more details on using hashes here.

Provenance

The following attestation bundles were made for lagclient-0.1.0-py3-none-any.whl:

Publisher: release.yml on lag-app/sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page