This example project demonstrates how to use the EPP Screening Model package as an external dependency in your own Python projects.
This example shows how an external team or scientist can:
- Install the EPP Screening Model package from GitHub
- Use the goal seek API with custom ACCU volumes
- Run batch sensitivity analyses
- Execute full model calculations programmatically
- NEW: Run interactive dashboard for goal seeking and visualization
- Python 3.12+
- UV package manager (recommended) or pip
- GitHub authentication (one of):
- GitHub Personal Access Token (PAT)
- SSH keys configured with GitHub
- GitHub CLI (gh) authenticated
-
Create a GitHub Personal Access Token:
- Go to: https://github.com/settings/tokens
- Click "Generate new token (classic)"
- Select scopes:
repo(full control of private repositories) - Copy the token (you'll only see it once!)
-
Set up authentication:
# Copy the example environment file cp .env.example .env # Edit .env and add your GitHub token # GITHUB_TOKEN=ghp_your_token_here
-
Install the EPP package:
# Using UV (recommended) - specify v1.1.1 or later uv add "git+https://${GITHUB_TOKEN}@github.com/MullionGroup/epp_screening_model_v3.git@v1.1.1" # Or using pip pip install "git+https://${GITHUB_TOKEN}@github.com/MullionGroup/epp_screening_model_v3.git@v1.1.1"
Important: Version 1.1.1 or later is required for the Jupyter helper functions.
If you have SSH keys configured with GitHub:
# Using UV - specify v1.1.1 or later
uv add "git+ssh://git@github.com/MullionGroup/epp_screening_model_v3.git@v1.1.1"
# Or using pip
pip install "git+ssh://git@github.com/MullionGroup/epp_screening_model_v3.git@v1.1.1"If you have GitHub CLI installed and authenticated:
# Authenticate first (uses 1Password/Keychain)
gh auth login
# Install package - specify v1.1.1 or later
uv add "git+https://github.com/MullionGroup/epp_screening_model_v3.git@v1.1.1"If you prefer to install from a pre-built wheel file without Git authentication:
Download from GitHub Releases:
- Visit the releases page: https://github.com/MullionGroup/epp_screening_model_v3/releases
- Download the
.whlfile from the desired release (e.g., v1.2.3) - Install the downloaded wheel:
# Install from local wheel file
uv add epp_screening_model_v3-1.2.3-py3-none-any.whl
# Or specify the full path
uv add /path/to/epp_screening_model_v3-1.2.3-py3-none-any.whlInstall directly from GitHub release URL:
# Install v1.2.3 directly from GitHub
uv add https://github.com/MullionGroup/epp_screening_model_v3/releases/download/v1.2.3/epp_screening_model_v3-1.2.3-py3-none-any.whlBenefits of wheel installation:
- ✅ No Git authentication required
- ✅ Faster installation (no cloning/building)
- ✅ Explicit version control
- ✅ Works in air-gapped environments (if wheel is downloaded)
Latest releases:
- v1.4.0 (2025-11-28): ⭐ RECOMMENDED - Complete CSV removal, validation framework, CLI enhancements
- v1.3.1 (2025-11-10): Critical bug fix (missing excel_mappings in v1.3.0)
- v1.3.0 (2025-11-09): Excel Version Mapping Enhancement (use v1.4.0 instead)
- v1.2.3 (2025-10-31): Full chart generation feature parity with notebook
- v1.2.2 (2025-10-31): Fixed external project export generation
- v1.2.1 (2025-10-31): Added --template option to analyze-gr-projects
- v1.2.0 (2025-10-31): Added comparison tools CLI
See all releases: https://github.com/MullionGroup/epp_screening_model_v3/releases
# Using UV (recommended)
uv sync
# Or using pip
pip install -r requirements.txtCopy the base configuration from the EPP package or create your own:
# Create a config directory
mkdir -p config
# You'll need a config.toml file - see examples/01_basic_goal_seek.py# Install dashboard dependencies
uv sync --extra dashboard
# Launch the dashboard
./launch_dashboard.sh
# Or manually:
uv run streamlit run dashboard/app.pyThe dashboard provides:
- Quick Goal Seek: Run preset optimizations with one click
- Interactive Charts: Explore results with Plotly visualizations
- Multiple Configs: Support for v1_epp and v2_sfm versions
- Export Results: Download results in JSON format
- Modern UI: Clean, professional interface
See dashboard/README.md for full documentation.
# Install notebook dependencies
uv sync --extra notebook
# Launch Jupyter notebook (from project root or examples directory)
uv run jupyter notebook examples/EPP_Examples.ipynbThe notebooks:
- Automatically adjust the working directory to find config files
- Provide step-by-step explanations with interactive code cells
- Generate professional visualizations and charts
- Include comprehensive examples and use cases
- Export results in multiple formats (CSV, Excel, PNG)
# Example 1: Basic goal seek
uv run python examples/01_basic_goal_seek.py
# Example 2: Custom ACCU volumes
uv run python examples/02_custom_accu_volumes.py
# Example 3: Batch sensitivity analysis
uv run python examples/03_batch_analysis.py
# Example 4: Full model execution
uv run python examples/04_full_model_run.py
# Example 5: v2_sfm Excel version (v1.3.0+)
uv run python examples/05_v2_sfm_example.py
# Example 6: Programmatic goal seek (standalone, no helpers)
uv run python examples/06_programmatic_goal_seek.pyThe EPP Screening Model package includes several command-line tools that can be run directly with uv run:
| Command | Description |
|---|---|
epp-model |
Main CLI with subcommands for running model, goal seek, exports |
analyze-gr-projects |
Batch analyze projects from TSV file |
epp-export |
Generate full 9-sheet Excel export |
epp-template |
Write config to Excel template (v1) |
epp-template-v2 |
Write config to Excel template (version-aware) |
epp-compare-quarterly |
Compare quarterly data between Excel and Python |
epp-compare-annual |
Compare annual data (Summary_A sheet) |
The main entry point with multiple subcommands:
# Show available commands
uv run epp-model --help
# Run the complete model calculation
uv run epp-model --config config/config.toml run
# Run goal seek with presets (recommended)
uv run epp-model --config config/config.toml goal-seek --preset debt-ratio-60
uv run epp-model --config config/config.toml goal-seek --preset levered-return-15
# List available presets
uv run epp-model goal-seek --list-presets
# Run goal seek with custom parameters
uv run epp-model --config config/config.toml goal-seek \
--input-cell "Ass_Static!H197" \
--target-cell "Ass_Static!H200" \
--target-value 0.60 \
--min 0.3 --max 0.95
# Goal seek with scenario overrides
uv run epp-model --config config/config.toml goal-seek \
--preset levered-return-15 \
--scenario scenarios/high_market.toml
# Export model results
uv run epp-model --config config/config.toml export --output-format json
# Batch export to multiple formats
uv run epp-model --config config/config.toml batch-export
# Display model info
uv run epp-model info
# Create a template configuration file
uv run epp-model create-config --output my_config.tomlAnalyze multiple projects from a TSV file and generate comprehensive reports:
# Full analysis (all features)
uv run analyze-gr-projects --input sample_batch_projects.tsv
# Custom output location
uv run analyze-gr-projects -i data.tsv -o results/my_analysis.zip
# Quick analysis (skip goal seek and exports)
uv run analyze-gr-projects -i data.tsv --no-goal-seek --no-exports
# Template-only mode (fastest, no calculations)
uv run analyze-gr-projects -i data.tsv --template-only
# With v2_sfm Excel version
uv run analyze-gr-projects -i data.tsv --excel-version v2_sfm
# Custom goal seek bounds
uv run analyze-gr-projects -i data.tsv \
--gs-lower-multiplier 0.1 \
--gs-upper-multiplier 3.0Options:
-i, --input PATH- Input TSV file with project data (required)-o, --output PATH- Output ZIP file path-p, --prefix TEXT- Prefix for output files (default:epp_screening_results_)--no-goal-seek- Skip goal seek analysis (faster)--no-charts- Skip chart generation (faster)--no-exports- Skip full Excel exports (faster)--template-only- Only generate template exports (fastest)--excel-version- Excel version:v1_epp,v2_sfm, orauto
Generate full 9-sheet Excel export from configuration:
# Default export
uv run epp-export --config config/config.toml
# Custom output path
uv run epp-export --config config/config.toml --output results/my_export.xlsx
# With scenario overrides
uv run epp-export --config config/config.toml \
--scenario scenarios/high_market.toml \
--output results/high_market_export.xlsxWrite Python configuration data into an Excel template file:
# Basic usage
uv run epp-template \
--config config/config.toml \
--template "data/Environmental Plantings Projects - Screening Model.xlsx" \
--output "results/config_in_excel.xlsx"
# With scenario overrides
uv run epp-template \
--config config/config.toml \
--scenario "scenarios/high_land_price.toml" \
--template "data/Environmental Plantings Projects - Screening Model.xlsx" \
--output "results/high_land_price_in_excel.xlsx"Write configuration to Excel template with explicit version support:
# With v1_epp version
uv run epp-template-v2 \
--config config/config.toml \
--template "data/Environmental Plantings Projects - Screening Model.xlsx" \
--output "results/config_in_excel.xlsx" \
--excel-version v1_epp
# With v2_sfm version
uv run epp-template-v2 \
--config config/config_v2_sfm.toml \
--template "data/Screening Model - Update for SFM.xlsx" \
--output "results/config_in_excel_v2.xlsx" \
--excel-version v2_sfmCompare quarterly data between original Excel and Python model output:
# Basic comparison
uv run epp-compare-quarterly \
--original "data/Original_Excel.xlsx" \
--output "results/full_9_sheet_export.xlsx"
# With verbose output showing top differences
uv run epp-compare-quarterly \
--original "data/Original_Excel.xlsx" \
--output "results/full_9_sheet_export.xlsx" \
--verbose --top 20
# Filter by threshold (only show >1% differences)
uv run epp-compare-quarterly \
--original "data/Original_Excel.xlsx" \
--output "results/full_9_sheet_export.xlsx" \
--threshold 1.0
# Ignore specific rows
uv run epp-compare-quarterly \
--original "data/Original_Excel.xlsx" \
--output "results/full_9_sheet_export.xlsx" \
--ignore "Financing_Qtr,50" --ignore "Acc_Qtr,30"Compare annual data (Summary_A sheet) between Excel and Python:
# Basic comparison
uv run epp-compare-annual \
--original "data/Original_Excel.xlsx" \
--output "results/full_9_sheet_export.xlsx"
# With verbose output
uv run epp-compare-annual \
--original "data/Original_Excel.xlsx" \
--output "results/full_9_sheet_export.xlsx" \
--verbose --top 10
# Custom report path
uv run epp-compare-annual \
--original "data/Original_Excel.xlsx" \
--output "results/full_9_sheet_export.xlsx" \
--report "results/my_annual_comparison.csv"EPP_Examples.ipynb - Goal Seek & Scenarios
Interactive notebook covering goal seek and scenario analysis:
- Basic goal seek with presets
- Custom ACCU volumes
- Batch sensitivity analysis
- Visualizations and exports
- Step-by-step explanations
EPP_Metrics_Examples.ipynb - Metrics Extraction (v1.1.1+) ⭐ NEW
Comprehensive metrics extraction and analysis:
- 50+ metrics across 6 categories
- Automatic extraction from all 9 sheets
- Financial performance dashboards
- Scenario-based metrics comparison
- Professional reporting and exports
To use the notebooks:
# Install Jupyter dependencies
uv sync --extra notebook
# Start Jupyter (from project root or examples directory)
uv run jupyter notebook examples/
# The notebooks automatically adjust the working directoryDemonstrates basic goal seek using presets:
- Find LVR for target debt ratio
- Find property price for target IRR
- Access financial metrics from results
Shows how to use custom ACCU volumes:
- Pass ACCU volumes as Python lists
- No TOML files required
- Combine with parameter overrides
Performs sensitivity analysis:
- Compare multiple ACCU scenarios
- Generate summary DataFrame
- Export results to CSV
Demonstrates full model execution:
- Run complete 9-sheet model (v1_epp version)
- Access individual sheet results
- Export to multiple formats
Demonstrates v2_sfm Excel version support:
- Use alternative Excel format (Screening Financial Model)
- Different parameter configurations (LVR 50%, WACC 11%, extended exit date)
- Additional v2_sfm-specific parameters
- Compare results between v1_epp and v2_sfm versions
epp-example-external-usage/
├── README.md # This file
├── pyproject.toml # UV project configuration
├── .env.example # GitHub token template
├── .gitignore # Git ignore rules
├── examples/
│ ├── EPP_Examples.ipynb # Goal seek & scenarios (recommended)
│ ├── EPP_Metrics_Examples.ipynb # Metrics extraction (v1.1.1+) ⭐ NEW
│ ├── 01_basic_goal_seek.py # Basic goal seek with presets
│ ├── 02_custom_accu_volumes.py # Custom ACCU volumes
│ ├── 03_batch_analysis.py # Batch sensitivity analysis
│ ├── 04_full_model_run.py # Full model (v1_epp)
│ └── 05_v2_sfm_example.py # v2_sfm Excel version (v1.3.0+)
├── config/
│ ├── config.toml # Default v1_epp configuration
│ ├── config_v1_epp.toml # Explicit v1_epp configuration
│ ├── config_v2_sfm.toml # v2_sfm configuration (v1.3.0+)
│ └── config.toml.example # Configuration template
├── data/
│ └── scenarios/ # Custom scenario files
└── results/ # Output directory
The EPP Screening Model requires a config.toml file with model parameters. See the main EPP repository for configuration templates and examples.
The model now supports two Excel formats:
-
v1_epp (Environmental Plantings Projects) - Original format
- Config:
config/config.tomlorconfig/config_v1_epp.toml - Default LVR: 96%, Exit: 2031, WACC: 9%
- Config:
-
v2_sfm (Screening Financial Model) - Alternative format
- Config:
config/config_v2_sfm.toml - Default LVR: 50%, Exit: 2036, WACC: 11%
- Additional parameters: annual_net_revenue, annual_opex_per_ha
- Config:
- [static] - Static model parameters (property price, hectares, dates, financial assumptions)
- [accu_pricing] - ACCU pricing mode (constant or curve)
- [escalation_rates] - Quarterly escalation rates (CPI, labor, materials)
- [csv_data_paths] - Paths to CSV data files (if used)
- devx_allocations - Development expenditure allocation by quarter
from epp_screening_model_v3.models.goal_seek import GoalSeekSolver, get_preset
# v1_epp (default)
solver = GoalSeekSolver('config/config.toml')
preset = get_preset('debt-ratio-60')
result = solver.solve(
input_cell=preset.input_cell,
target_cell=preset.target_cell,
target_value=preset.target_value,
bounds=(preset.min_value, preset.max_value)
)
print(f"Optimal LVR: {result.solution:.2%}")
print(f"Levered Return: {result.levered_return:.2%}")from epp_screening_model_v3.models.goal_seek import GoalSeekSolver, get_preset
# Use v2_sfm configuration (Excel version auto-detected from config)
solver = GoalSeekSolver('config/config_v2_sfm.toml')
preset = get_preset('debt-ratio-60')
result = solver.solve(
input_cell=preset.input_cell,
target_cell=preset.target_cell,
target_value=preset.target_value,
bounds=(preset.min_value, preset.max_value)
)
print(f"Optimal LVR: {result.solution:.2%}")
print(f"Levered Return: {result.levered_return:.2%}")Recommended Method - Using Jupyter helpers:
from epp_screening_model_v3.notebooks.epp_jupyter_helpers import goal_seek_with_accu_volumes
# Pass ACCU volumes as Python list - no TOML files needed!
result = goal_seek_with_accu_volumes(
preset_name='debt-ratio-60',
accu_volumes=[0.0, 6750.0, 24605.5, ..., 0.0, 0.0], # 27 values
config_path='config/config.toml'
)
print(f"Optimal LVR: {result.solution:.2%}")
print(f"Levered Return: {result.levered_return:.2%}")from epp_screening_model_v3.notebooks.epp_jupyter_helpers import batch_goal_seek_analysis
scenarios = {
'Conservative': [0.0, 4500.0, ...], # 27 values
'Baseline': [0.0, 6000.0, ...], # 27 values
'Aggressive': [0.0, 6750.0, ...], # 27 values
}
df = batch_goal_seek_analysis(
preset_name='debt-ratio-60',
accu_scenarios=scenarios,
config_path='config/config.toml'
)
print(df[['scenario', 'lvr', 'unlevered_return', 'levered_return']])from epp_screening_model_v3.models import ACCUModel
# v1_epp (default)
model = ACCUModel('config/config.toml')
results = model.calculate_full_model()
print(f"Unlevered IRR: {results.unlevered_irr:.2%}")
print(f"Levered IRR: {results.levered_irr:.2%}")
# Access individual sheets
returns_data = results.get_sheet_result('Returns_Prj')from epp_screening_model_v3.models import ACCUModel
# Explicitly use v2_sfm Excel version
model = ACCUModel('config/config_v2_sfm.toml', excel_version='v2_sfm')
results = model.calculate_full_model()
print(f"Unlevered IRR: {results.unlevered_irr:.2%}")
print(f"Levered IRR: {results.levered_irr:.2%}")Debt Ratios (adjust LVR):
debt-ratio-50- Target 50% debt-to-capexdebt-ratio-60- Target 60% debt-to-capexdebt-ratio-70- Target 70% debt-to-capex
Levered Returns (adjust Property Price):
levered-return-12- Target 12% levered IRRlevered-return-15- Target 15% levered IRRlevered-return-18- Target 18% levered IRRlevered-return-20- Target 20% levered IRR
Unlevered Returns (adjust Property Price):
unlevered-return-10- Target 10% unlevered IRRunlevered-return-12- Target 12% unlevered IRRunlevered-return-15- Target 15% unlevered IRR
Problem: fatal: could not read Username for 'https://github.com'
Solution: Make sure you've set up authentication using one of the three methods above.
Problem: ModuleNotFoundError: No module named 'epp_screening_model_v3'
Solution:
# Verify installation
uv pip list | grep epp-screening-model
# Reinstall if needed
uv add git+https://github.com/MullionGroup/epp_screening_model_v3.git --force-reinstallProblem: Package imports not working
Solution: Make sure you're using the correct import paths:
# Correct
from epp_screening_model_v3.models import ACCUModel
from epp_screening_model_v3.models.goal_seek import GoalSeekSolver
# Incorrect
from epp_screening_model import ACCUModel # Wrong package nameFor issues, questions, or feature requests:
- Main Repository: https://github.com/MullionGroup/epp_screening_model_v3
- Documentation: See
docs/in the main repository - Issues: https://github.com/MullionGroup/epp_screening_model_v3/issues
This example project is for demonstration purposes. The EPP Screening Model package is subject to its own license terms.
This example project requires:
- EPP Screening Model v1.4.0 or later ⭐ RECOMMENDED
- Python 3.12+
- UV 0.5.0+ (recommended) or pip
Version History:
- v1.0.6: Package build was broken (skip this version)
- v1.0.7: Fixed package imports
- v1.0.8: Added scenario class exports
- v1.0.9: Includes Jupyter helpers for convenient API
- v1.1.0: Metrics system and advanced notebooks
- v1.1.1: ACCU pricing config migration, parametric scenarios, Excel enhancements
- v1.1.5-1.1.6: Added analyze-gr-projects CLI command
- v1.1.7: Added epp-export and epp-template CLI commands
- v1.2.0: Added comparison tools CLI (epp-compare-quarterly, epp-compare-annual)
- v1.2.1: Added --template option to analyze-gr-projects
- v1.2.2: Fixed external project export generation bug
- v1.2.3: Full chart generation feature parity with notebook
- v1.3.0: Excel Version Mapping Enhancement (skip - use v1.4.0 due to packaging bug)
- v1.3.1: Critical bug fix (missing excel_mappings)
- v1.4.0: CURRENT RECOMMENDED - Complete CSV removal, validation framework, CLI enhancements
Latest v1.4.0 Changes (2025-11-28):
- ✅ Complete CSV Removal - Pure TOML configuration architecture
- Removed all CSV file dependencies
- Scenario system fully migrated to TOML
- ✅ Comprehensive Validation Framework - Phase 2 validation complete
- ✅ CLI Enhancements - All 7 CLI commands fully documented
- ✅ Bug Fixes - Fixed csv_paths references in scenario loading
- ✅ Test Updates - Goal seek tests updated with achievable target values
v1.3.x Features (included in v1.4.0):
- ✅ Dual Excel Version Support - v1_epp and v2_sfm formats
- ✅ Centralized Configuration Module (
src/config/)- PathConfig - Single source of truth for file paths
- ValidationConfig - Centralized validation settings
- SheetNames - TOML ↔ Excel name mapping
- ColumnLayout - Sheet-specific column configurations
- ✅ Metadata Provider System - 14,900% performance improvement
- ✅ Enhanced TOML Mappings - 4,500+ field definitions with metadata
- ✅ Golden Baselines - 124,427 entries for regression testing
- ✅ Production-Ready Architecture - Comprehensive error handling
Breaking Changes (v1.1.1+):
- BREAKING: ACCU pricing migrated from CSV to config-only architecture
- Removed
accu_price_curve_quarterly.csv- now configured inconfig.toml - Two modes:
constant(single price) orcurve(109 quarterly prices) - See
config/config.toml[accu_pricing]section for details
- Removed
Upgrade to v1.4.0:
# Remove old wheel
rm epp_screening_model_v3-*.whl
# Download v1.4.0 from GitHub releases or copy from main project
cp /path/to/epp_screening_model_v3-1.4.0-py3-none-any.whl .
# Install and sync
uv syncLast updated: 2025-11-28