Skip to main content

Gateforge SDK (Python)

Privacy-first LLMOps SDK — Transparent client wrapping with automatic PII masking, cost tracking, A/B testing, guardrails, agent tracing, and prompt management.

Python 3.10+ PyPI License


What it does

Gateforge wraps your existing provider client (OpenAI, Anthropic, Gemini) with a transparent proxy. Your code is unchanged — the SDK intercepts each call to run the full pipeline locally:

Your code
    │
    ▼
pre-call  → A/B variant selection → system prompt injection
          → PII anonymize (local)
          → input guardrail check
    │
    ▼
LLM provider (sees masked content only)
    │
    ▼
post-call → PII rehydrate (local)
          → output guardrail check
          → cost + latency compute
          → span emission (metadata only)
    │
    ▼
Your code receives: original PII restored, guardrails applied

PII detection, anonymization and rehydration run in your process. The LLM provider receives the anonymized prompt. Gateforge telemetry is disabled when no exporter or control-plane URL is configured; when enabled it can include metadata and, if store_content is explicitly enabled, anonymized content. The optional LLM quality judge also sends anonymized prompt/response excerpts to the configured judge provider. See Privacy and data flow.


Installation

pip install gateforge-sdk

With provider extras:

pip install gateforge-sdk[openai]      # OpenAI only
pip install gateforge-sdk[anthropic]   # Anthropic only
pip install gateforge-sdk[gemini]      # Google Gemini only
pip install gateforge-sdk[all]         # All providers
pip install gateforge-sdk[dev]         # Development tools

An API key is only needed when using a Gateforge-compatible hosted or self-hosted control plane. Fully local use does not require one.


Quick Start

Option 1: Fully local (recommended for first use)

import gateforge
from openai import OpenAI

gateforge.init(config={
    "pii_domain": "generic",
    "pii_backend": "presidio",
    "features": {"pii_enabled": True, "guardrails_enabled": False},
})

# Wrapping is required. An unwrapped provider client is not protected.
client = gateforge.wrap_openai(OpenAI(api_key="sk-..."))

Option 2: Hosted or self-hosted control plane

import gateforge
from openai import OpenAI

gateforge.init(
    api_key="gf-live-YOUR_KEY",
    base_url="https://your-gateforge-control-plane.example",
)

# Wrap your client
client = gateforge.wrap_openai(OpenAI(api_key="sk-..."))

# Use exactly as before — pipeline runs automatically
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello!"}],
)

Option 3: Provider auto-detection

import gateforge
from openai import OpenAI
from anthropic import Anthropic
from google import genai

gateforge.init(config={"features": {"pii_enabled": True}})

# Auto-detects provider
client1 = gateforge.wrap(OpenAI(api_key="sk-..."))
client2 = gateforge.wrap(Anthropic(api_key="sk-ant-..."))
client3 = gateforge.wrap(genai.Client(api_key="AIza-..."))

Key Features

1. Auto-Initialization

import gateforge
from openai import OpenAI

# Requires GATEFORGE_API_KEY and, for remote config/telemetry,
# GATEFORGE_BASE_URL. It does not monkey-patch provider clients.

gateforge.auto_init(enable_pii=True, enable_guardrails=False)
client = gateforge.wrap_openai(OpenAI(api_key="sk-..."))

2. Decorator-Based Tracing

import gateforge

# Tool with automatic tracing
@gateforge.tool()
def get_weather(location: str) -> str:
    import requests
    return requests.get(f"https://wttr.in/{location}?format=3").text

# Agent with automatic tracing
@gateforge.agent()
def weather_agent(message: str) -> str:
    return get_weather("Madrid")

# Session to group multiple calls
with gateforge.session(user_id="user-123"):
    response = weather_agent("What's the weather?")

3. Conversation Management

from gateforge import SessionManager, trace

# Manage sessions
manager = SessionManager()
session = manager.create_session(
    user_id="user-123",
    tags=["weather-chat"],
)

# Use in trace
with trace(conversation_id=session.conversation_id):
    response = run_agent(message)

# Track activity
manager.touch(session.conversation_id)
session.set_metadata("last_model", "gpt-4o-mini")

4. Prompt System

from gateforge import Prompt, PromptBuilder, PromptCache

# Create prompt with variables
prompt = Prompt(
    name="greeting",
    content="Hello, {{name}}! You are {{role}}.",
    variables={"name": "User", "role": "a developer"},
)
rendered = prompt.render(name="Alice")  # "Hello, Alice!..."

# Compose prompts
builder = PromptBuilder()
builder.add_system("You are helpful")
builder.add_user("What's the weather?")
builder.add_variable("location", "Madrid")
prompt = builder.build()

# Cache prompts (memory + file + backend)
cache = PromptCache(memory_ttl=300, file_ttl=3600)
cache.set(prompt)
retrieved = cache.get("greeting")

Provider Wrappers

All wrappers are transparent — input params and return types match the underlying SDK.

OpenAI

import gateforge
from openai import OpenAI, AsyncOpenAI

gateforge.init(api_key="gf-live-...")

# Sync
client = gateforge.wrap_openai(OpenAI(api_key="sk-..."))
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello!"}],
)

# Async
async_client = gateforge.wrap_openai(AsyncOpenAI(api_key="sk-..."))
response = await async_client.chat.completions.create(...)

# Streaming
for chunk in client.chat.completions.create(..., stream=True):
    print(chunk.choices[0].delta.content, end="")

Anthropic

import gateforge
from anthropic import Anthropic

client = gateforge.wrap_anthropic(Anthropic(api_key="sk-ant-..."))
response = client.messages.create(
    model="claude-haiku-4-5",
    max_tokens=512,
    messages=[{"role": "user", "content": "Hello!"}],
)

Gemini

import gateforge
from google import genai

client = gateforge.wrap_gemini(genai.Client(api_key="AIza-..."))
response = client.models.generate_content(
    model="gemini-2.5-flash",
    contents=[{"role": "user", "parts": [{"text": "Hello!"}]}],
)

Agent Tracing

Basic Multi-Step Trace

import gateforge
from openai import OpenAI

gateforge.init(api_key="gf-live-...")
client = gateforge.wrap_openai(OpenAI(api_key="sk-..."))

with gateforge.trace(conversation_id="conv_abc123"):
    # Each LLM call gets auto-incremented step number
    r1 = client.chat.completions.create(...)  # step 1
    r2 = client.chat.completions.create(...)  # step 2

Agent with Tool Calls

import gateforge

@gateforge.tool()
def search_flights(destination: str, date: str) -> list:
    ...

@gateforge.tool()
def book_flight(flight_id: str, passenger: str) -> str:
    ...

@gateforge.agent()
def travel_agent(request: str) -> str:
    flights = search_flights("Paris", "2026-06-10")
    confirmation = book_flight(flights[0]["id"], "John Doe")
    return f"Booked: {confirmation}"

# All tool calls automatically traced
with gateforge.session(user_id="user-123"):
    response = travel_agent("Book me a flight to Paris")

Session Management

from gateforge import SessionManager, get_current_conversation_id

manager = SessionManager()

# Create session
session = manager.create_session(user_id="user-123")

# Get current conversation from active trace
cid = get_current_conversation_id()

# List sessions
sessions = manager.list_sessions(user_id="user-123", limit=10)

# Serialize for persistence
data = manager.to_dict()  # Save to DB
manager2 = SessionManager.from_dict(data)  # Load

A/B Testing

from gateforge import CallOptions

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Help me write an email"}],
    gateforge_options=CallOptions(
        experiment_id="exp_email_v2",
        session_id="user_123",  # Deterministic variant
    ),
)
# Variant A or B injected automatically

Guardrails

from gateforge import CallOptions, GuardrailBlocked

try:
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": "..."}],
        gateforge_options=CallOptions(guardrails=True),
    )
except GuardrailBlocked as e:
    print(f"Blocked by rule: {e.rule_id}")

PII Protection

PII protection only applies to clients returned by gateforge.wrap(...) or a provider-specific wrapper. Creating an ordinary OpenAI, Anthropic or Gemini client after initialization does not intercept its calls.

Detected Entities

Category Examples
Personal Names, emails, phones, addresses
Financial Credit cards, bank accounts, SSN
Healthcare Medical records, symptoms, diagnoses
Technical IP addresses, URLs, API keys
Custom Your own regex patterns

Direct Anonymization

import gateforge

result = gateforge.anonymize("My email is john@example.com")
print(result["sanitized"])  # "My email is [EMAIL_001]"
print(result["entities"])   # ["EMAIL"]

original = gateforge.rehydrate("[EMAIL_001]", context=result["context"])
print(original)  # "john@example.com"

Privacy and data flow

Configuration Network behavior
Local config, no exporter No Gateforge telemetry or config traffic
base_url + API key Fetches remote config and exports telemetry to that URL
store_content=False (default) Telemetry omits content previews
store_content=True Telemetry may include anonymized content previews
LLM quality judge enabled Sends anonymized excerpts to the configured judge provider

The wrapped model provider always receives the anonymized prompt required to produce a response. PII detection is not infallible; validate the selected backend and locale against your data before relying on it for compliance.


CallOptions Reference

from gateforge import CallOptions

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[...],
    gateforge_options=CallOptions(
        # Trace grouping
        conversation_id="conv_abc",
        
        # A/B testing
        experiment_id="exp_abc",
        session_id="user_123",
        
        # Feature overrides
        pii=True,
        guardrails=True,
        track_cost=False,
    ),
)

API Reference

Initialization

Function Description
gateforge.init(api_key, ...) Manual initialization
gateforge.auto_init() Auto from environment

Wrapping

Function Description
gateforge.wrap(client) Auto-detect provider
gateforge.wrap_openai(client) Wrap OpenAI
gateforge.wrap_anthropic(client) Wrap Anthropic
gateforge.wrap_gemini(client) Wrap Gemini

Tracing

Function Description
gateforge.trace(conversation_id) Context manager for traces
gateforge.continue_session(id) Resume existing conversation
gateforge.session(user_id) Session context manager
gateforge.tool() Decorator for tool tracing
gateforge.agent() Decorator for agent tracing

Session Management

Function Description
SessionManager() Create session manager
manager.create_session() Create new session
manager.get_session(id) Get existing session
manager.list_sessions() List with filters
get_current_conversation_id() Get active trace ID
get_current_trace_info() Get full trace info

Prompts

Function Description
Prompt(...) Create prompt
PromptBuilder() Compose prompts
PromptCache() Multi-level cache
gateforge.get_prompt(name) Get from cache/backend
gateforge.set_prompt(prompt) Set in cache

Utilities

Function Description
gateforge.anonymize(text) Anonymize PII
gateforge.rehydrate(text, ctx) Restore PII
gateforge.track_metrics(data) Send metadata

Supported Models

OpenAI

  • GPT-4o, GPT-4o-mini
  • GPT-4.1, GPT-4.1-mini, GPT-4.1-nano

Anthropic

  • Claude Haiku 4-5
  • Claude Sonnet 4-5
  • Claude Opus 4

Google Gemini

  • Gemini 2.5 Flash
  • Gemini 2.5 Pro

Dashboard

https://app.gateforge.dev/dashboard

  • Request volume and trends
  • Cost breakdown by model/provider
  • Latency analytics
  • PII detection statistics
  • A/B experiment results
  • Guardrail violation alerts
  • Agent waterfall traces
  • API key management

Changelog

See CHANGELOG.md for release notes.


Documentation


Troubleshooting

ImportError: No module named 'gateforge'

pip install gateforge-sdk

RuntimeError: Call gateforge.init() first

# Fully local
gateforge.init(config={"features": {"pii_enabled": True}})

# Or from GATEFORGE_API_KEY + GATEFORGE_BASE_URL
gateforge.auto_init()

PII not detected

  1. Check domain setting matches your data
  2. Add custom patterns in dashboard

Steps not appearing in trace

  1. Ensure tracing_enabled=True
  2. Confirm conversation_id is active

Links


License

MIT — see LICENSE.

The SDK is free software and has no runtime dependency on any Gateforge service: it runs the full pipeline locally and sends telemetry only to the destination you configure, if any. Gateforge also offers a hosted control plane and dashboard as a commercial product; using it is optional and never required to run this library.

Download files

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

Source Distribution

gateforge_sdk-0.4.0.tar.gz (113.3 kB view details)

Uploaded Source

Built Distribution

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

gateforge_sdk-0.4.0-py3-none-any.whl (82.0 kB view details)

Uploaded Python 3

File details

Details for the file gateforge_sdk-0.4.0.tar.gz.

File metadata

  • Download URL: gateforge_sdk-0.4.0.tar.gz
  • Upload date:
  • Size: 113.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.7

File hashes

Hashes for gateforge_sdk-0.4.0.tar.gz
Algorithm Hash digest
SHA256 30fdce9e6f4797b945fd6274806a2fb361c1b0d52700ed7c4a4017e0bc966c31
MD5 dab22b0315bea36a6b73fc75315c9980
BLAKE2b-256 320bba28552721e66e1dae87d1ceb7e4282686dc6fb22fcca086aa1acbd7cb2e

See more details on using hashes here.

File details

Details for the file gateforge_sdk-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: gateforge_sdk-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 82.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.7

File hashes

Hashes for gateforge_sdk-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6aab7cee29fc3b088f7473a16d56eef04cd4d62fbb914b69f0afc89417ac9091
MD5 108cfdf4794b76d2303575dbfba37460
BLAKE2b-256 bfcd015cf4272e730b8efbdb2eaedbcfb5b6f7062112462a02260c1d0dacae2e

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 files

0.3.7

2 files

0.3.6

2 files

0.3.5

2 files

0.3.4

2 files

0.2.25

2 files

0.2.24

2 files

0.2.23

2 files

0.2.22

2 files

0.2.21

2 files

0.2.20

2 files

0.2.19

2 files

0.2.18

2 files

0.2.17

2 files

0.2.16

2 files

0.2.15

2 files

0.2.14

2 files

0.2.12

2 files

0.2.11

2 files

0.2.10

2 files

0.2.9

2 files

0.2.8

2 files

0.2.7

2 files

0.2.6

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.1.1

2 files

0.1.0

2 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