Python SDK

Python AI Agent Guardrails with Veto SDK

Native Python SDK for AI agent authorization. Works with LangChain, CrewAI, PydanticAI, or any custom agent framework. Two lines of code.

Python AI agent guardrails, veto Python SDK, Python agent authorization, AI safety Python, LangChain guardrails, CrewAI authorization, PydanticAI guardrails

Quick start

Install the SDK via pip, initialize with your API key, and wrap your tools. Authorization happens automatically before each tool execution.

Terminalpip install veto
pip install veto

Basic usage

Wrap your tools with Veto. Every tool call is validated against your policies before execution. Blocked calls raise ToolCallDeniedError.

agent.pyPython
import asyncio
from veto import Veto, ToolCallDeniedError

# Your existing tools
async def transfer_money(amount: float, to_account: str) -> str:
    return f"Transferred $" + str(amount) + " to " + to_account

async def delete_file(path: str) -> str:
    return "Deleted " + path

async def main():
    # Initialize Veto with API key from VETO_API_KEY env var
    veto = await Veto.init()

    # Wrap your tools - authorization is now enforced
    tools = [transfer_money, delete_file]
    wrapped = veto.wrap(tools)

    # Use wrapped tools in your agent
    try:
        result = await wrapped[0].handler({"amount": 500, "to_account": "ACC123"})
        print("Allowed: " + result)
    except ToolCallDeniedError as e:
        print("Blocked: " + e.reason)

asyncio.run(main())

Tool wrapping patterns

Veto adapts to your tool structure. Works with dataclasses, LangChain tools, or any callable with a handler method.

Dataclass tool
from dataclasses import dataclass
from typing import Any

@dataclass
class MyTool:
    name: str = "my_tool"
    description: str = "Does something useful"

    async def handler(self, args: dict[str, Any]) -> str:
        return "Executed with " + str(args)

# Veto automatically detects and wraps
tool = MyTool()
wrapped = veto.wrap([tool])[0]
LangChain integration
from langchain_core.tools import tool
from pydantic import BaseModel, Field

class TransferInput(BaseModel):
    amount: float = Field(description="Amount to transfer")
    to_account: str = Field(description="Destination account")

@tool("transfer_money", args_schema=TransferInput)
def transfer_money(amount: float, to_account: str) -> str:
    """Transfer money to an account."""
    return "Transferred $" + str(amount) + " to " + to_account

# Wrap LangChain tools directly
wrapped_tools = veto.wrap([transfer_money])

# Use with your LangChain agent
agent = create_react_agent(llm, wrapped_tools)

Provider adapters

Built-in adapters convert between tool formats. Works with OpenAI, Anthropic, and Google function calling conventions.

Provider adapters
from veto import (
    to_openai, to_openai_tools,
    to_anthropic, to_anthropic_tools,
    to_google_tool,
)

# Convert tool definitions to provider formats
openai_tools = to_openai_tools(my_tools)
anthropic_tools = to_anthropic_tools(my_tools)
google_tool = to_google_tool(my_tool)

# Convert tool calls back to Veto format
from veto import from_openai_tool_call, from_anthropic_tool_use
tool_call = from_openai_tool_call(openai_message)

Features

Runtime authorization

Every tool call is validated against your policies before execution. The agent cannot bypass guardrails regardless of its reasoning.

Framework agnostic

Works with LangChain, CrewAI, PydanticAI, or any custom agent framework. No framework-specific code required.

Deterministic policies

Define constraints as code. Argument limits, required fields, pattern matching. Evaluate locally without network latency.

Cloud sync

Policies managed in Veto Cloud. Real-time updates, team collaboration, approval workflows, and audit logging.

Build vs buy

CapabilityDIYVeto Python SDK
Initial setup2-4 weeks5 minutes
Policy engine
Approval workflows
Audit logging
Framework integrations
Maintenance burdenOngoingNone

Frequently asked questions

How do I install the Python SDK?
Install via pip: `pip install veto`. Set the `VETO_API_KEY` environment variable with your API key from the dashboard. Then initialize with `await Veto.init()` in async code.
Does it work with async tools?
Yes. The SDK is fully async-native. Use `await Veto.init()` for initialization and wrapped tools expose both `handler` (async) and `invoke` methods for flexibility.
Can I use Veto without a network connection?
For deterministic policies, yes. Define constraints locally and they evaluate without network calls. Cloud policies require connectivity for real-time updates and approval workflows.
How do I handle blocked tool calls?
Blocked calls raise `ToolCallDeniedError` with a `reason` attribute. Catch it and return a fallback response, log the attempt, or escalate to human review.

Related integrations

View all integrations

Ship Python agents with confidence.