Route Researcher Tools
Python CLI tools for gathering current conditions data for North American mountain route research.
Overview
Route Researcher Tools
Python CLI tools for gathering current conditions data for North American mountain route research.
Overview
These tools are invoked by the route-researcher skill to fetch real-time data that supplements web-scraped route information. Each tool outputs structured JSON to stdout for easy parsing.
Design Philosophy:
- Tools focus on computation and API calls, not web scraping
- All tools handle API/network errors gracefully (exit 0 with JSON error output)
- JSON output includes helpful fallback info when data unavailable
- Timeout-friendly (30s default)
Tools
cloudscrape.py
Fetches HTML content from Cloudflare-protected websites using cloudscraper.
Usage:
uv run python cloudscrape.py "https://www.peakbagger.com/peak.aspx?pid=1798"
Parameters:
url(required): URL to fetch--timeout(optional): Request timeout in seconds (default: 30)
Output: Returns the full HTML content to stdout.
Purpose:
- Bypasses Cloudflare bot protection on PeakBagger and SummitPost
- Uses cloudscraper library which solves Cloudflare's JavaScript challenges
- No browser required - pure HTTP with smart request mimicking
Behavior:
- Creates scraper instance with Chrome browser profile
- Mimics macOS desktop Chrome browser
- Automatically solves Cloudflare challenges
- Returns raw HTML for parsing by the skill
Dependencies:
- cloudscraper (Cloudflare bypass)
- click (CLI)
- rich (console output)
Use Cases:
- Fetching PeakBagger peak pages
- Fetching SummitPost route descriptions
- Any Cloudflare-protected climbing/hiking resource
Example:
# Fetch Mount Pilchuck page from PeakBagger
uv run python cloudscrape.py "https://www.peakbagger.com/peak.aspx?pid=1798" | grep -i "elevation"
fetch_conditions.py
Unified conditions fetcher — weather, air quality, daylight, avalanche region, and PeakBagger statistics.
Usage:
uv run python fetch_conditions.py \\
--coordinates "48.7767,-121.8144" \\
--elevation 3286 \\
--peak-name "Mt Baker" \\
--peak-id 1798
Parameters:
--coordinates(required): Lat/lon as "lat,lon"--elevation(required): Elevation in meters--peak-name(required): Peak name--peak-id(optional): PeakBagger peak ID for stats/ascents--date(optional): Date as YYYY-MM-DD (default: today)
Output:
Returns unified JSON with keys: weather, air_quality, daylight, avalanche, peakbagger, gaps.
Data Sources:
- Open-Meteo Weather API (7-day forecast, freezing levels)
- Open-Meteo Air Quality API (US AQI)
- astral library (sunrise, sunset, civil twilight)
- NWAC region detection by coordinates
- peakbagger-cli (ascent statistics and recent ascents)
Testing:
RUN_INTEGRATION_TESTS=1 uv run pytest test_fetch_conditions.py -v
Installation
All tools are managed via uv with dependencies in pyproject.toml.
Setup:
cd skills/route-researcher/tools
uv sync
This creates a virtual environment and installs all dependencies.
Python Version:
Python 3.11+ (specified in .python-version)
Common Issues
Dependencies not installing
- Check if
uvis installed:uv --version - Try
uv sync --reinstallin the tools directory - The skill will still work, just without some Python tools
Cloudflare Blocking Requests
The cloudscrape.py tool handles Cloudflare protection, but may occasionally fail:
- Skill automatically falls back to available sources
- Check "Information Gaps" section in generated reports
- Use manual verification links provided
No Route Beta Generated
Ensure you're in a directory where you have write permissions. Reports are created in your current working directory, not in the plugin installation directory.
Development
Adding a New Tool
- Create
new_tool.pywith Click CLI:
#!/usr/bin/env python3
@click.command()
@click.option('--param', required=True)
def cli(param: str):
"""Tool description"""
try:
# Tool logic here
output = {"result": "data"}
click.echo(json.dumps(output, indent=2))
except Exception as e:
# Graceful error handling
output = {"error": str(e), "note": "Fallback message"}
click.echo(json.dumps(output, indent=2))
sys.exit(0) # Don't hard-fail
if __name__ == '__main__':
cli()
- Create
test_new_tool.py:
from click.testing import CliRunner
from new_tool import cli
def test_basic_functionality():
runner = CliRunner()
result = runner.invoke(cli, ['--param', 'value'])
assert result.exit_code == 0
data = json.loads(result.output)
assert 'result' in data
-
Add dependencies to
pyproject.tomlif needed -
Test:
uv run pytest test_new_tool.py -v
Error Handling Guidelines
All tools follow these principles:
- Never hard-fail on API errors - Exit 0 on network/API failures; exit 1 only on invalid arguments
- Always return JSON - Structured output for parsing
- Include helpful context - URLs, notes, suggestions
- Timeout gracefully - 30s default, degrade if exceeded
- Log to stderr - Use
click.echo(..., err=True)orrich.Console(stderr=True)for warnings
Example error output:
{
"source": "Service Name",
"error": "Connection timeout",
"note": "Check service.com manually for current data",
"url": "https://service.com/relevant-page"
}
This ensures the skill can continue even if individual tools fail.
Testing Best Practices
- Test with real coordinates when possible
- Mock HTTP requests for reliability
- Test both success and failure paths
- Verify JSON structure and required fields
- Check graceful error handling
Running All Tests
cd skills/route-researcher/tools
uv run pytest -v
Expected output: All tests passing
Integration with Skill
Tools are invoked by the skill via Bash commands:
cd skills/route-researcher/tools
uv run python fetch_conditions.py --coordinates "48.7767,-121.8144" --elevation 3286 --peak-name "Mt Baker"
The skill:
- Parses JSON output from stdout
- Handles errors gracefully (checks for "error" field)
- Includes data in report or notes gap
- Provides manual check links from tool output
Performance
Typical execution times:
fetch_conditions.py: 2-5s without --peak-id; 30-120s with --peak-id (peakbagger-cli is slow)cloudscrape.py: 1-3s (HTTP with Cloudflare bypass)
Timeouts:
- Individual tools: 30s
- Total skill execution: 3-5 minutes target
Troubleshooting
Tool returns error JSON
Check:
- Network connectivity
- Service website availability (Open-Meteo, NWAC)
- Coordinate format (must be "lat,lon" with comma, no spaces)
- Date format (must be YYYY-MM-DD)
Dependencies not found
cd skills/route-researcher/tools
uv sync --reinstall
Tests failing
Check Python version:
python --version # Should be 3.11+
Reinstall dependencies:
uv sync
uv run pytest -v
Future Enhancements
Potential tool additions:
fetch_road_conditions.py- WSDOT or forest service road statusfetch_permit_info.py- Recreation.gov availabilityaggregate_gps_tracks.py- Combine tracks from multiple sourcesanalyze_historical_conditions.py- Seasonal patterns from trip reportsfetch_noaa_forecast.py- Alternative weather source
Contributing
These tools are part of a personal experimental skill. Code is provided as-is for reference.
Dependencies
Managed in pyproject.toml:
- click - CLI framework
- httpx - Modern HTTP client
- rich - Rich terminal output
- astral - Astronomy calculations (daylight)
- cloudscraper - Cloudflare bypass
Dev dependencies: pytest