Skip to main content

Official Python SDK for the Gjallarhorn prompt-injection detection API

Project description

gjallarhorn-hq-sdk

Official Python SDK for the Gjallarhorn prompt-injection detection API.

PyPI version License: MIT

Installation

pip install gjallarhorn-hq-sdk

Requirements: Python 3.9+, httpx.

Quickstart

import os
from gjallarhorn_hq_sdk import GjallarhornClient

client = GjallarhornClient(api_key=os.environ['GJALLARHORN_API_KEY'])

result = client.scan(input=user_input)
if result.risk_level in ('critical', 'high'):
    raise ValueError('Injection detected — request blocked')
# safe to send to LLM

Async usage

import asyncio
import os
from gjallarhorn_hq_sdk import AsyncGjallarhornClient

async def main():
    async with AsyncGjallarhornClient(api_key=os.environ['GJALLARHORN_API_KEY']) as client:
        result = await client.scan(input='some user input')
        print(result.risk_level, result.detection_layers)

asyncio.run(main())

Methods

Method Description
scan(content, *, use_classifier?, context?) Scan text for prompt injection
scan_multimodal(file, mime_type, filename?) Scan PDF/image/QR code
get_quota() Get credit usage and quota
check_canary(llm_response) L2 output integrity check (opt-in)
health() Server/DB health check — no auth required, endpoint is /health (not /v1/health)

Both GjallarhornClient (sync) and AsyncGjallarhornClient (async) expose the same methods.

Scan a PDF

from pathlib import Path

result = client.scan_multimodal(Path('user-upload.pdf'), 'application/pdf')
print(result.risk_level, result.billed_pages)

L2 Agentic Integration

check_canary() checks whether your LLM's response still contains the Gjallarhorn canary token. Absence signals a possible system-prompt override. L2 is opt-in — it only covers agents explicitly registered with Gjallarhorn; LLM calls made outside the integration are not monitored.

Privacy: L2 canary checks are stateless and content-free. Gjallarhorn receives the LLM output, performs a token presence check, and returns a boolean result. No output content, user data, or conversation text is retained server-side.

Full L2 integration example

import os
from gjallarhorn_hq_sdk import GjallarhornClient
from gjallarhorn_hq_sdk import AuthError, ServiceUnavailableError

client = GjallarhornClient(api_key=os.environ['GJALLARHORN_API_KEY'])

# Step 1: Register agent once at startup — store canary_token in your secrets.
# (Registration is a one-time REST call to POST /v1/agents/register.)
CANARY_TOKEN = os.environ['AGENT_CANARY_TOKEN']

# Step 2: Inject canary into every system prompt.
def build_system_prompt(base_prompt: str) -> str:
    return f"{base_prompt}\n{CANARY_TOKEN}"

# Step 3: After every LLM call, check output integrity.
def check_agent_output(llm_output: str) -> None:
    try:
        check = client.check_canary(llm_output)
    except AuthError:
        raise RuntimeError('Canary check: invalid API key')
    except ServiceUnavailableError:
        # Canary service down — decide whether to fail-open or fail-closed
        import warnings
        warnings.warn('Canary check unavailable — proceeding with caution')
        return

    if check.alert_code == 'RAGNARÖK':
        # Canary absent: model did not echo the token it should always produce.
        # Possible cause: system prompt was overridden by an injection attack.
        raise RuntimeError(
            f'[RAGNARÖK] Agent output integrity check failed '
            f'for agent {check.agent_id} at {check.checked_at}'
        )

# Usage in your agent loop:
system_prompt = build_system_prompt('You are a helpful customer support agent.')
llm_output = call_your_llm(system_prompt, user_message)
check_agent_output(llm_output)
# Safe to proceed

Error handling

from gjallarhorn_hq_sdk import (
    AuthError, QuotaExceededError, RateLimitError,
    ExtractionFailedError, ServiceUnavailableError,
)

try:
    result = client.scan(input=user_input)
except AuthError:
    print('Invalid API key')
except QuotaExceededError:
    print('Monthly quota hit')
except RateLimitError as e:
    print(f'Rate limited — retry after {e.retry_after}s')
except ExtractionFailedError:
    print('Could not extract file content')

The SDK retries automatically on rate-limit (respecting retry_after) and 503 errors (exponential backoff, max 3 retries).

License

MIT — see LICENSE.

Links

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

gjallarhorn_hq_sdk-1.0.2.tar.gz (7.4 kB view details)

Uploaded Source

Built Distribution

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

gjallarhorn_hq_sdk-1.0.2-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

Details for the file gjallarhorn_hq_sdk-1.0.2.tar.gz.

File metadata

  • Download URL: gjallarhorn_hq_sdk-1.0.2.tar.gz
  • Upload date:
  • Size: 7.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for gjallarhorn_hq_sdk-1.0.2.tar.gz
Algorithm Hash digest
SHA256 467cf91fa13c60cf7c779ad4cbfdbd42425db753dfeb14b19c56d9039f402519
MD5 371b65c3ac4614087a765070b7c1d0f0
BLAKE2b-256 dd315c290e8affd4c8ee4293106d87df27be217298f2fae957e6fe71a7ad17a6

See more details on using hashes here.

File details

Details for the file gjallarhorn_hq_sdk-1.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for gjallarhorn_hq_sdk-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 81fc5ec72247378bd5db6972b11489348e49da59260b181e8f48e22143a24661
MD5 15c6e2224b193201e4eceeaa1b911406
BLAKE2b-256 b0090991a2375eeea7821dc2fffb201c99510fa0bf1690773784f7476e9816f5

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