Skip to main content

Self-hosted LLM observability SDK — trace any model call to your own dashboard

Project description

LangProtect Python SDK

Every model call is scanned by Armor for threats and PII, routed to the right provider, and linked to the LangProtect dashboard — all with a single import change.


Install

pip install git+https://github.com/Quokka-Labs-LLP/langprotect-armor-sdk.git#subdirectory=python

Quick Start

import langprotect

langprotect.init(
    openai_api_key  = "sk-...",
    armour_base_url = "https://langprotect-xxx.run.app",
    armour_api_key  = "your-armour-key",
    security_on     = True,
)

from langprotect.langfuse.openai import openai

response = openai.chat.completions.create(
    model    = "gpt-4o-mini",
    messages = [{"role": "user", "content": "Hello!"}],
    session_id = "sess_001",
    user_id    = "user_42",
)

print(response.choices[0].message.content)

Configuration

All configuration is passed to langprotect.init() — no .env file required.

import langprotect

langprotect.init(
    # LLM provider
    openai_api_key   = "sk-...",

    # Armor security scanning
    armour_base_url  = "https://langprotect-xxx.run.app",
    armour_api_key   = "your-armour-key",
    security_on      = False,   # True  → sanitize/block unsafe input
                                # False → scanning disabled entirely
    trace_only       = False,   # True  → log only, never enforce
    scan_timeout     = 60,      # Armor HTTP timeout in seconds

    # LangProtect dashboard (used by score())
    langprotect_host = "http://localhost:8000",

    # LiteLLM proxy (optional — enables non-OpenAI models)
    litellm_host     = "",      # e.g. "http://localhost:4000"
)
Parameter Default Description
openai_api_key "" OpenAI API key
armour_base_url "" Armor API base URL
armour_api_key "" Armor X-API-Key header
security_on False Enforce sanitization / blocking
trace_only False Log only — never block or sanitize
scan_timeout 60 Armor HTTP timeout (seconds)
langprotect_host http://localhost:8000 Dashboard URL for score()
litellm_host "" LiteLLM proxy URL for non-OpenAI models

init() must be called before from langprotect.langfuse.openai import openai.


Usage

Chat completions

from langprotect.langfuse.openai import openai

response = openai.chat.completions.create(
    model      = "gpt-4o",
    messages   = [{"role": "user", "content": "Explain async/await"}],
    session_id = "sess_123",
    user_id    = "u_42",
    metadata   = {"turn_number": 1},
)

print(response.choices[0].message.content)

Handling blocked responses

When security_on=True and Armor hard-blocks a request, a BlockedResponse is returned instead of a normal completion. Check for it before reading .choices:

if getattr(response, "blocked", False):
    print(response.content)  # "This response has been blocked by security policy."
else:
    print(response.choices[0].message.content)

Toggling security at runtime

from langprotect.langfuse.openai import set_security

set_security(True)   # Armor ON
set_security(False)  # Armor OFF

Feedback scoring

from langprotect.langfuse.openai import score

score(trace_id="abc123", value=1,  comment="Correct and concise")
score(trace_id="abc123", value=-1)

value is 1 (positive) or -1 (negative). Scores are posted to {langprotect_host}/api/feedback.

Supported call parameters

These are stripped before the OpenAI call and used for metadata only:

Parameter Type Description
session_id str Groups all turns of a conversation
user_id str Identifies the end user
name str Trace label
metadata dict Any JSON key-value context
trace_id str Override the auto-generated UUID
tags list Labels for filtering

Security Scanning

The SDK calls the Armor /v1/scan endpoint on every input and output.

Scan modes

trace_only security_on Behaviour
True any Log the scan result, always proceed
False False Block if input is not safe, no sanitization
False True Sanitize if possible, block otherwise

Anonymization

When Armor returns a sanitized_prompt (PII replaced with tokens like [PERSON_1], [EMAIL_ADDRESS_1]), the SDK:

  1. Replaces the user message with the sanitized version
  2. Injects a system prompt hint so the LLM treats tokens as real values
  3. On the output scan, restores the original values via sanitized_output transparently

The caller always receives the deanonymized response.


Model Routing

The SDK detects the provider from the model name and routes accordingly:

Model prefix Provider Route
gpt-, o1, o3, text-davinci, text-embedding OpenAI Direct to OpenAI API
claude, anthropic Anthropic Via LiteLLM proxy
gemini, palm Google Via LiteLLM proxy
llama, mistral, mixtral, codellama, phi, qwen Ollama Via LiteLLM proxy
anything else LiteLLM Via LiteLLM proxy

Non-OpenAI models require litellm_host to be set.

Starting LiteLLM

litellm --model claude-3-5-sonnet-20241022 --port 4000

Then in init():

langprotect.init(
    ...
    litellm_host = "http://localhost:4000",
)

Adding a new model via config

# litellm_config.yaml
- model_name: phi3
  litellm_params:
    model: ollama/phi3
    api_base: http://localhost:11434
ollama pull phi3
litellm --config litellm_config.yaml --port 4000

Data Flow

Your App
  openai.chat.completions.create(model="gpt-4o", messages=[...])
        │
        ▼
langprotect SDK
  1. Armor input scan  →  sanitize / block / log
  2. LLM call          →  OpenAI direct or LiteLLM proxy
  3. Armor output scan →  deanonymize + eval trigger
        │
        ▼
  Response returned to caller
  (eval runs as background task on LangProtect backend)

Troubleshooting

ModuleNotFoundError: langprotect Ensure the SDK is installed in your active virtualenv and init() is called before importing submodules.

Response not deanonymized Check that security_on=True and ARMOUR_BASE_URL / ARMOUR_API_KEY are set correctly. The Armor output scan must return sanitized_output.

Non-OpenAI model fails Set litellm_host in init() and ensure the LiteLLM proxy is running with the model configured.

Armor scan times out Increase scan_timeout in init() (default 60 s). Check that armour_base_url is reachable from your environment.

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

langprotect_armor-0.1.0.tar.gz (14.1 kB view details)

Uploaded Source

Built Distribution

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

langprotect_armor-0.1.0-py3-none-any.whl (14.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: langprotect_armor-0.1.0.tar.gz
  • Upload date:
  • Size: 14.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for langprotect_armor-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f183c43d774a8c140dc0b4aa1aeb47a22a271762dc0807cc72ae2470b592834b
MD5 f04362fd2207857fa4c1e4a2f5862db1
BLAKE2b-256 f69c868d3a5851c75247efd29bf90efe39980696d43021aaf2234252d2200284

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for langprotect_armor-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9bdda8bd727d0ec3afa394e196059a3ac581485ec2f867c30bafb9b8469e99ba
MD5 b50844a4947ff07deb083851ec4a85e3
BLAKE2b-256 6857c83fc156188a176e2d45852ed76471030adece136ad2519ef99688a8a7ee

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