Initial commit
This commit is contained in:
356
skills/tools-and-apis/policyengine-python-client-skill/SKILL.md
Normal file
356
skills/tools-and-apis/policyengine-python-client-skill/SKILL.md
Normal file
@@ -0,0 +1,356 @@
|
||||
---
|
||||
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
|
||||
|
||||
```bash
|
||||
# Install the Python client
|
||||
pip install policyengine
|
||||
|
||||
# Or for local development
|
||||
pip install policyengine-us # Just the US model (offline)
|
||||
```
|
||||
|
||||
## Quick Start: Python Client
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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:**
|
||||
- 1,000 requests per minute
|
||||
- Contact hello@policyengine.org for API key
|
||||
|
||||
### Key Endpoints
|
||||
|
||||
**Calculate household impact:**
|
||||
```python
|
||||
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:**
|
||||
```python
|
||||
# Get policy metadata
|
||||
response = requests.get("https://api.policyengine.org/us/policy/12345")
|
||||
policy = response.json()
|
||||
```
|
||||
|
||||
**Get parameter values:**
|
||||
```python
|
||||
# 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:**
|
||||
```bash
|
||||
# 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:**
|
||||
```bash
|
||||
pip install policyengine-us # US only
|
||||
pip install policyengine-uk # UK only
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```python
|
||||
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:**
|
||||
```python
|
||||
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:**
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```python
|
||||
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:**
|
||||
- US: https://policyengine.org/us/docs
|
||||
- UK: https://policyengine.org/uk/docs
|
||||
|
||||
**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:**
|
||||
- GitHub Discussions: https://github.com/PolicyEngine/policyengine-us/discussions
|
||||
|
||||
**For bugs:**
|
||||
- File issues in appropriate repo (policyengine-us, policyengine.py, etc.)
|
||||
|
||||
**For collaboration:**
|
||||
- Email: hello@policyengine.org
|
||||
Reference in New Issue
Block a user