Skip to main content

Official Python SDK for the LaroGuard AI security gateway

Project description

LaroGuard Python SDK

PyPI version Python ≥ 3.9 License: MIT

Official Python SDK for the LaroGuard AI security gateway. Route your LLM traffic through LaroGuard to apply input/output security rules, PII masking, prompt-injection detection, and rate limiting — without changing your application logic.


Requirements

Minimum
Python 3.9
httpx 0.27

Installation

pip install laroguard

Quick start

from laroguard import LaroGuard

lg = LaroGuard(
    api_key="your-project-api-key",   # → X-API-Key header
    project_id="proj_xxx",            # → X-Project-ID header + body field
    integration_id="openai_primary",  # → integration_id body field
    base_url="https://gateway.example.com",
)

# Non-streaming — returns a complete ProcessResponse
resp = lg.process(messages=[{"role": "user", "content": "Hello"}])
print(resp.content)          # cleaned / masked LLM response text
print(resp.decision)         # "ALLOW" | "MASK" | "REDACT" | "BLOCK"
print(resp.triggered_rules)  # e.g. ["pii_email", "prompt_injection"]

# Streaming — yields StreamEvent objects
for event in lg.stream(messages=[{"role": "user", "content": "Tell me a story"}]):
    if event.type == "chunk":
        print(event.content, end="", flush=True)
    elif event.type == "blocked":
        print("\n[BLOCKED BY SECURITY RULE]")
    elif event.type == "done":
        print()  # newline after stream ends

Constructor parameters

Parameter Type Required Default Description
api_key str Project API key. Sent as the X-API-Key request header.
project_id str Project identifier. Sent as the X-Project-ID header and project_id body field.
integration_id str Default integration to invoke. Can be overridden per call. See Finding your integration_id.
base_url str http://localhost:8000 Root URL of the LaroGuard gateway.
timeout float 120.0 Per-request timeout in seconds.

process() — non-streaming

resp = lg.process(
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is the capital of France?"},
    ],
    session_id="sess_abc",          # optional: link turns into a conversation
    integration_id="openai_gpt4o",  # optional: override the instance default
    skip_guard=False,               # optional: bypass security rules (use with care)
)

Response fields

Field Type Description
request_id str Unique request identifier assigned by the gateway.
trace_id str Internal trace identifier for debugging.
decision str Gateway decision: "ALLOW", "MASK", "REDACT", or "BLOCK".
content str The LLM response after any masking or redaction has been applied. Empty when decision == "BLOCK".
blocked bool True when the request was blocked before reaching the LLM.
masked bool True when at least one rule masked or redacted part of the output.
triggered_rules list[str] Names of the security rules that fired, e.g. ["pii_email", "api_key_leak"].

stream() — server-sent events

for event in lg.stream(
    messages=[{"role": "user", "content": "Explain quantum computing"}],
    session_id="sess_xyz",
):
    if event.type == "chunk":
        print(event.content, end="", flush=True)
    elif event.type == "blocked":
        print("\n[Stream terminated by security rule]")
    elif event.type == "done":
        print("\n[Stream complete]")

Stream event types

event.type Class Attributes When emitted
"chunk" StreamChunkEvent content: str For every safe text token from the LLM.
"blocked" StreamBlockedEvent (none) When the gateway terminates the stream due to a triggered rule. Iteration stops.
"done" StreamDoneEvent (none) After the stream completes normally. Always the last event.

Async usage

import asyncio
from laroguard import AsyncLaroGuard

async def main() -> None:
    async with AsyncLaroGuard(
        api_key="your-project-api-key",
        project_id="proj_xxx",
        integration_id="openai_primary",
        base_url="https://gateway.example.com",
    ) as lg:
        # Non-streaming
        resp = await lg.process(
            messages=[{"role": "user", "content": "Hello"}],
        )
        print(resp.content)

        # Streaming
        async for event in lg.stream(
            messages=[{"role": "user", "content": "Tell me a story"}],
        ):
            if event.type == "chunk":
                print(event.content, end="", flush=True)
            elif event.type == "blocked":
                print("\n[BLOCKED]")

asyncio.run(main())

AsyncLaroGuard accepts the same constructor parameters as LaroGuard and exposes identical process() and stream() methods, both async.


Error handling

All SDK exceptions inherit from LaroGuardError, so you can use a single broad handler or catch specific subclasses for fine-grained control.

from laroguard import (
    LaroGuardError,      # base — catch-all
    SecurityBlockError,  # 403 — input or output blocked by a rule
    AuthenticationError, # 401 — invalid or missing API key
    NotFoundError,       # 404 — integration_id not found / project not found
    RateLimitError,      # 429 — quota exceeded
    APIError,            # other 4xx / 5xx HTTP errors
    ConnectionError,     # network failure (timeout, DNS, refused)
    StreamBlockedError,  # mid-stream block sentinel (raised inside stream loop)
)

try:
    resp = lg.process(messages=[{"role": "user", "content": "Hello"}])
except SecurityBlockError as e:
    print(f"Blocked: {e.message}")
except AuthenticationError:
    print("Check your API key")
except RateLimitError:
    print("Back off and retry")
except NotFoundError:
    print("Verify your integration_id in the dashboard")
except ConnectionError:
    print("Cannot reach the gateway — check your base_url")
except APIError as e:
    print(f"Gateway error {e.status_code}: {e.message}")

Exception hierarchy

LaroGuardError
├── APIError               — 4xx / 5xx HTTP responses
│   ├── SecurityBlockError — 403
│   ├── AuthenticationError— 401
│   ├── NotFoundError      — 404
│   └── RateLimitError     — 429
├── StreamBlockedError     — mid-stream block sentinel
└── ConnectionError        — network-level failure

Context managers

Both clients support the context-manager protocol, which ensures the underlying HTTP connection pool is closed cleanly on exit.

# Synchronous
with LaroGuard(api_key=..., project_id=..., integration_id=...) as lg:
    resp = lg.process(messages=[...])

# Asynchronous
async with AsyncLaroGuard(api_key=..., project_id=..., integration_id=...) as lg:
    resp = await lg.process(messages=[...])

Finding your integration_id

  1. Open the LaroGuard management dashboard.
  2. Navigate to Project → Integrations.
  3. Copy the identifier shown next to your LLM integration (e.g. openai_primary).

The integration_id tells the gateway which LLM provider credential to use when forwarding your request. You can configure multiple integrations per project and switch between them per call by passing integration_id= to process() or stream().


License

MIT — see LICENSE for details.

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

laroguard-2.0.0.tar.gz (24.7 kB view details)

Uploaded Source

Built Distribution

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

laroguard-2.0.0-py3-none-any.whl (21.4 kB view details)

Uploaded Python 3

File details

Details for the file laroguard-2.0.0.tar.gz.

File metadata

  • Download URL: laroguard-2.0.0.tar.gz
  • Upload date:
  • Size: 24.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for laroguard-2.0.0.tar.gz
Algorithm Hash digest
SHA256 cf0099ec619517d5d511eb6fcaabae4acc22a5ea346fe95e7157ed3f89794eff
MD5 d18b3f0c9ba8ce6de08831fe4d9a5b07
BLAKE2b-256 40793713056d549802bdc95c02897fff33bb79ac79cad7df2164af07a154bdd8

See more details on using hashes here.

File details

Details for the file laroguard-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: laroguard-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 21.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for laroguard-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b064ab2156e9df8c198f4dcb259bdd61ce96da8734952b34641b53cef0b0b2a7
MD5 73773bd71bfb44450ef1fbf547487092
BLAKE2b-256 1b670b862efaeabbe02b3fee79ba3f76072696ee8f3c236d82660480a0cc4084

See more details on using hashes here.

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