Manual setup — Python
Install token-police, call tp.init(), wrap your entrypoint, and run. Python-first.
Add TokenPolice to a Python app in three steps. You'll need your API key and the collector URL first.
1. Install
pip install token-policePython 3.10 or newer. Provider libraries (OpenAI, Anthropic, …) are auto-instrumented — no extra install for the common ones. Framework extras are on the integrations page.
2. Initialize
Call tp.init() once at startup, before you import or construct your LLM client. That
ordering lets TokenPolice wrap the client automatically.
import os
import token_police as tp
tp.init(
api_key=os.environ["TOKENPOLICE_API_KEY"], # tp_sk_...
base_url="https://collect.tokenpolice.ai", # the collector — always set this
firewall="dry_run", # watch first; flip to "enforce" later
)
# Only now import and construct your LLM client:
from openai import OpenAI
client = OpenAI()That's the whole integration. Every call client makes is now checked before it runs and
logged after — you'll see it in the dashboard.
firewall="dry_run" is the default and the right place to start: TokenPolice runs the
full check and records what it would do, but never blocks. Flip it to "enforce" once
your dashboard rules look right. See Dry-run vs enforce.
3. Attach identity (recommended)
To budget per user or per session, wrap your entrypoint with @tp.workflow. It tags every
call inside with one identity and threads them into a single trace:
@tp.workflow(name="support_agent")
def run_agent(user_id: str, paid_plan: str, session_id: str, query: str):
return client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": query}],
)By default @tp.workflow reads user_id, paid_plan, and session_id straight from the
wrapped function's arguments — so calling run_agent(user_id="u_123", paid_plan="pro", session_id="chat_42", query=...) attaches them automatically. These identities are what
budgets and rules match on. More in Identity.
4. Run it
Run your app as usual and make an LLM call. Then open app.tokenpolice.ai — the call shows up with its token counts and cost. Only token metadata is sent; your prompts and completions never leave your process (what's in that record).
Then finish the job
The three steps above get you metering. A production integration also names its steps, wraps its tool calls, flushes before a serverless function freezes, and handles a blocked call — and then proves all of it works. The integration checklist walks through the rest in order.
Next steps
init() parameters
Every option, defaults, and env vars.
Dry-run vs enforce
Turn on blocking when you're ready.
Nothing in the dashboard?
Common first-run fixes.
Integration checklist
The rest of the steps, and how to verify.
Node instead?
The same setup in Node / TypeScript.
See it in a running app →
A full support-desk chat wired exactly like this, in Python and Node.

