From data-science
Installs and configures the PolicyEngine Python client for programmatic access to PolicyEngine REST API endpoints, authentication, rate limits, and the policyengine.py client library.
How this skill is triggered — by the user, by Claude, or both
Slash command
/data-science:policyengine-python-client-skillThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **IMPORTANT: Always use the current year (2026) in situation dictionaries and calculate() calls, not 2024 or 2025.**
IMPORTANT: Always use the current year (2026) in situation dictionaries and calculate() calls, not 2024 or 2025.
This skill covers programmatic access to PolicyEngine for analysts and researchers.
If the user asks for the latest PolicyEngine package version, verify from PyPI immediately before installing. Do not rely on search snippets, local installed packages, lockfiles, or old docs as proof of latest.
# Verify the latest umbrella package on PyPI.
python - <<'PY'
import json
import urllib.request
with urllib.request.urlopen(
"https://pypi.org/pypi/policyengine/json",
timeout=20,
) as response:
print(json.load(response)["info"]["version"])
PY
python -m pip index versions policyengine
# Install the Python client, pinned to the verified version.
uv pip install "policyengine==X.Y.Z"
# Or for local development
uv pip install policyengine-us # Just the US model (offline)
When using policyengine.py as the source of both rules and default microdata,
install the country extra at the exact verified umbrella package version:
uv pip install "policyengine[us]==X.Y.Z"
uv pip install "policyengine[uk]==X.Y.Z"
If the user instead asks for the latest direct country package, run the same
PyPI JSON + pip index check for policyengine-us, policyengine-uk, or the
specific package named by the user, then pin that exact package version.
Confirm the resolved package versions and whether any package is a direct GitHub install:
python - <<'PY'
from importlib import metadata
for package in ["policyengine", "policyengine-us", "policyengine-uk"]:
try:
print(f"{package}=={metadata.version(package)}")
direct_url = metadata.distribution(package).read_text("direct_url.json")
if direct_url:
print(f"{package} direct_url={direct_url}")
except metadata.PackageNotFoundError:
pass
PY
For bundle/data provenance, inspect the installed release manifest directly
instead of relying on a top-level import policyengine; top-level imports can
initialize countries you are not using and may require private data tokens.
python - <<'PY'
import json
from importlib import metadata
from pathlib import Path
country = "us"
manifest_path = Path(
metadata.distribution("policyengine").locate_file(
f"policyengine/data/release_manifests/{country}.json"
)
)
manifest = json.loads(manifest_path.read_text())
print(json.dumps({
"bundle_id": manifest.get("bundle_id"),
"model_package": manifest.get("model_package"),
"data_package": manifest.get("data_package"),
"default_dataset": manifest.get("default_dataset"),
"default_dataset_uri": (
manifest.get("certified_data_artifact") or {}
).get("uri"),
"certification": manifest.get("certification"),
}, indent=2, sort_keys=True))
PY
from policyengine import Simulation
# Create a household
household = {
"people": {
"you": {
"age": {"2026": 30},
"employment_income": {"2026": 50000}
}
},
"households": {
"your household": {
"members": ["you"],
"state_name": {"2026": "CA"}
}
}
}
# Run simulation
sim = Simulation(situation=household, country_id="us")
income_tax = sim.calculate("income_tax", "2026")
Web app limitations:
Python benefits:
from policyengine import Simulation
# Your household (more complex than web app)
household = {
"people": {
"you": {
"age": {"2026": 35},
"employment_income": {"2026": 75000},
"qualified_dividend_income": {"2026": 5000},
"charitable_cash_donations": {"2026": 3000}
},
"spouse": {
"age": {"2026": 33},
"employment_income": {"2026": 60000}
},
"child1": {"age": {"2026": 8}},
"child2": {"age": {"2026": 5}}
},
# ... entities setup (see policyengine-us-skill)
}
sim = Simulation(situation=household, country_id="us")
# Calculate specific values
federal_income_tax = sim.calculate("income_tax", "2026")
state_income_tax = sim.calculate("state_income_tax", "2026")
ctc = sim.calculate("ctc", "2026")
eitc = sim.calculate("eitc", "2026")
print(f"Federal income tax: ${federal_income_tax:,.0f}")
print(f"State income tax: ${state_income_tax:,.0f}")
print(f"Child Tax Credit: ${ctc:,.0f}")
print(f"EITC: ${eitc:,.0f}")
from policyengine import Simulation
# Define reform (increase CTC to $5,000)
reform = {
"gov.irs.credits.ctc.amount.base[0].amount": {
"2026-01-01.2100-12-31": 5000
}
}
# Compare baseline vs reform
household = create_household() # Your household definition
sim_baseline = Simulation(situation=household, country_id="us")
sim_reform = Simulation(situation=household, country_id="us", reform=reform)
ctc_baseline = sim_baseline.calculate("ctc", "2026")
ctc_reform = sim_reform.calculate("ctc", "2026")
print(f"CTC baseline: ${ctc_baseline:,.0f}")
print(f"CTC reform: ${ctc_reform:,.0f}")
print(f"Increase: ${ctc_reform - ctc_baseline:,.0f}")
import pandas as pd
from policyengine import Simulation
# Analyze multiple households
households = [
{"income": 30000, "children": 0},
{"income": 50000, "children": 2},
{"income": 100000, "children": 3},
]
results = []
for h in households:
situation = create_household(income=h["income"], num_children=h["children"])
sim = Simulation(situation=situation, country_id="us")
results.append({
"income": h["income"],
"children": h["children"],
"income_tax": sim.calculate("income_tax", "2026"),
"ctc": sim.calculate("ctc", "2026"),
"eitc": sim.calculate("eitc", "2026")
})
df = pd.DataFrame(results)
print(df)
Public access:
Authenticated access:
Calculate household impact:
import requests
url = "https://api.policyengine.org/us/calculate"
payload = {
"household": household_dict,
"policy_id": reform_id # or None for baseline
}
response = requests.post(url, json=payload)
result = response.json()
Get policy details:
# Get policy metadata
response = requests.get("https://api.policyengine.org/us/policy/12345")
policy = response.json()
Get parameter values:
# Get current parameter value
response = requests.get(
"https://api.policyengine.org/us/parameter/gov.irs.credits.ctc.amount.base"
)
parameter = response.json()
OpenAPI spec: https://api.policyengine.org/docs
To explore:
# View all endpoints
curl https://api.policyengine.org/docs
# Test calculate endpoint
curl -X POST https://api.policyengine.org/us/calculate \
-H "Content-Type: application/json" \
-d '{"household": {...}}'
Unauthenticated:
Authenticated:
API calls:
Local simulation (policyengine-us):
When:
Install:
uv pip install policyengine-us # US only
uv pip install policyengine-uk # UK only
Example:
from policyengine_us import Simulation
# Works offline
sim = Simulation(situation=household)
When:
Example:
import requests
# Requires internet
response = requests.post("https://api.policyengine.org/us/calculate", ...)
Repository: PolicyEngine/policyengine.py
To see implementation:
# Clone the client
git clone https://github.com/PolicyEngine/policyengine.py
# See the Simulation class
cat policyengine/simulation.py
# See API integration
cat policyengine/api.py
Architecture:
Simulation class wraps API callscalculate() method handles cachingFor maximum control and performance, use country packages directly:
from policyengine_us import Simulation
# Full control over situation structure
situation = {
# Complete situation dictionary
# See policyengine-us-skill for patterns
}
sim = Simulation(situation=situation)
result = sim.calculate("variable_name", 2026)
Benefits:
See policyengine-us-skill for detailed patterns.
PolicyEngine documentation:
Example notebooks:
Community examples:
For usage questions:
For bugs:
For collaboration:
npx claudepluginhub policyengine/policyengine-claude --plugin analysis-toolsProvides programmatic access to PolicyEngine tax and benefit calculations via a Flask REST API. Useful for household calculations, policy management, and population impact analysis.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.