Claude Code Plugins

Community-maintained marketplace

Feedback

policyengine-python-client

@PolicyEngine/policyengine-claude
0
0

Using PolicyEngine programmatically via Python client or REST API

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name policyengine-python-client
description Using PolicyEngine programmatically via Python client or REST API

PolicyEngine Python Client

This skill covers programmatic access to PolicyEngine for analysts and researchers.

Installation

# Install the Python client
pip install policyengine

# Or for local development
pip install policyengine-us  # Just the US model (offline)

Quick Start: Python Client

from policyengine import Simulation

# Create a household
household = {
    "people": {
        "you": {
            "age": {"2024": 30},
            "employment_income": {"2024": 50000}
        }
    },
    "households": {
        "your household": {
            "members": ["you"],
            "state_name": {"2024": "CA"}
        }
    }
}

# Run simulation
sim = Simulation(situation=household, country_id="us")
income_tax = sim.calculate("income_tax", "2024")

For Users: Why Use Python?

Web app limitations:

  • ✅ Great for exploring policies interactively
  • ❌ Can't analyze many households at once
  • ❌ Can't automate repetitive analyses
  • ❌ Limited customization of charts

Python benefits:

  • ✅ Analyze thousands of households in batch
  • ✅ Automate regular policy analysis
  • ✅ Create custom visualizations
  • ✅ Integrate with other data sources
  • ✅ Reproducible research

For Analysts: Common Workflows

Workflow 1: Calculate Your Own Taxes

from policyengine import Simulation

# Your household (more complex than web app)
household = {
    "people": {
        "you": {
            "age": {"2024": 35},
            "employment_income": {"2024": 75000},
            "qualified_dividend_income": {"2024": 5000},
            "charitable_cash_donations": {"2024": 3000}
        },
        "spouse": {
            "age": {"2024": 33},
            "employment_income": {"2024": 60000}
        },
        "child1": {"age": {"2024": 8}},
        "child2": {"age": {"2024": 5}}
    },
    # ... entities setup (see policyengine-us-skill)
}

sim = Simulation(situation=household, country_id="us")

# Calculate specific values
federal_income_tax = sim.calculate("income_tax", "2024")
state_income_tax = sim.calculate("state_income_tax", "2024")
ctc = sim.calculate("ctc", "2024")
eitc = sim.calculate("eitc", "2024")

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}")

Workflow 2: Analyze a Policy Reform

from policyengine import Simulation

# Define reform (increase CTC to $5,000)
reform = {
    "gov.irs.credits.ctc.amount.base_amount": {
        "2024-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", "2024")
ctc_reform = sim_reform.calculate("ctc", "2024")

print(f"CTC baseline: ${ctc_baseline:,.0f}")
print(f"CTC reform: ${ctc_reform:,.0f}")
print(f"Increase: ${ctc_reform - ctc_baseline:,.0f}")

Workflow 3: Batch Analysis

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", "2024"),
        "ctc": sim.calculate("ctc", "2024"),
        "eitc": sim.calculate("eitc", "2024")
    })

df = pd.DataFrame(results)
print(df)

Using the REST API Directly

Authentication

Public access:

  • 100 requests per minute (unauthenticated)
  • No API key needed for basic use

Authenticated access:

Key Endpoints

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_amount"
)
parameter = response.json()

For Full API Documentation

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": {...}}'

Limitations and Considerations

Rate Limits

Unauthenticated:

  • 100 requests/minute
  • Good for exploratory analysis

Authenticated:

  • 1,000 requests/minute
  • Required for production use

Data Privacy

  • PolicyEngine does not store household data
  • All calculations happen server-side and are not logged
  • Reform URLs are public (don't include personal info in reforms)

Performance

API calls:

  • Simple household: ~200-500ms
  • Population impact: ~5-30 seconds (varies by reform)
  • Use caching for repeated calculations

Local simulation (policyengine-us):

  • Faster for batch analysis
  • No rate limits
  • No network dependency
  • Limited to one country per package

Choosing Local vs API

Use Local (policyengine-us package)

When:

  • Batch analysis of many households
  • Need offline capability
  • Analyzing parameter sweeps (axes)
  • Development/testing

Install:

pip install policyengine-us  # US only
pip install policyengine-uk  # UK only

Example:

from policyengine_us import Simulation

# Works offline
sim = Simulation(situation=household)

Use API (policyengine or requests)

When:

  • Multi-country analysis
  • Using latest model version
  • Don't want to manage dependencies
  • Integration with web services

Example:

import requests

# Requires internet
response = requests.post("https://api.policyengine.org/us/calculate", ...)

For Contributors: Understanding the Client

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 calls
  • calculate() method handles caching
  • Transparent fallback between API and local

Advanced: Direct Country Package Usage

For 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", 2024)

Benefits:

  • No API dependency
  • Faster (no network)
  • Full access to all variables
  • Use axes for parameter sweeps

See policyengine-us-skill for detailed patterns.

Examples and Tutorials

PolicyEngine documentation:

Example notebooks:

  • Repository: PolicyEngine/analysis-notebooks
  • See policyengine-analysis-skill for analysis patterns

Community examples:

  • Blog posts: policyengine.org/us/research
  • GitHub discussions: github.com/PolicyEngine discussions

Getting Help

For usage questions:

For bugs:

  • File issues in appropriate repo (policyengine-us, policyengine.py, etc.)

For collaboration: