A web application that helps open water swimmers make informed decisions about swim conditions.
shallweswim.today provides real-time tide, current, and temperature data for popular open water swimming locations including:
- Coney Island / Brighton Beach (NYC)
- La Jolla Cove (San Diego)
- Additional locations are being added regularly
- Real-time conditions from NOAA CO-OPS and USGS NWIS APIs
- Tide predictions with high/low tide times and heights
- Current velocity data with flood/ebb direction
- Water temperature trends (48-hour, 2-month, and multi-year)
- Transit information for NYC locations (subway status and alerts)
- Mobile-friendly interface for on-the-go swimmers
- JSON API for programmatic access to swim conditions
Shall We Swim is a FastAPI application with a modular architecture:
- Feed Framework (
feeds.py
): Modular data feed system for different data types- Base
Feed
class with expiration tracking and status reporting - Specialized feed types (NoaaTempFeed, NoaaTidesFeed, etc.) for different data sources
- Composite feeds for combining multiple data sources
- Base
- Data Management (
data.py
): Coordinates feeds and processes data from various sources- Manages feed lifecycle and data freshness
- Provides status monitoring and ready-state tracking
- Handles data processing and transformation
- Formats temperature data with appropriate precision
- API Layer (
api.py
): JSON endpoints for swim conditions and status- Location-specific endpoints for conditions data
- Status endpoints for monitoring system health
- Current prediction and tide visualization endpoints
- Web UI (
main.py
): HTML templates and web interface- Responsive design with modern UI components
- Conditional display of data based on feed availability
- Transit information for NYC locations
- NOAA CO-OPS Client (
coops.py
): Interacts with NOAA's Center for Operational Oceanographic Products and Services API - USGS NWIS Client (
nwis.py
): Interacts with the USGS National Water Information System API- Handles both Celsius and Fahrenheit temperature parameters
- Performs necessary unit conversions
- Configuration (
config.py
): Location settings and station IDs - Utilities (
util.py
): Common utilities for time handling and data processing
- Data Fetching: Specialized Feed classes fetch data (tides, currents, temperatures) from NOAA CO-OPS, USGS NWIS, and other sources for configured locations
- Data Processing: Raw data is processed with appropriate timezone conversions and unit transformations
- Status Monitoring: Feed and DataManager status is tracked and exposed via API endpoints
- Plot Generation: Visualizations are asynchronously generated for different time spans:
- 48-hour tide/current predictions
- 2-month historical temperature data
- Multi-year temperature trends
- API Endpoints: Processed data and system status are available via JSON endpoints
- Web UI: Templates display the data with visualizations and location-specific information (like transit status)
- Python 3.12
- Poetry for dependency management
- Docker (optional, for containerized deployment)
# Clone the repository
git clone https://github.com/jeremywhelchel/shallweswim.git
cd shallweswim
# Install dependencies
poetry install
# Run the development server
poetry run python -m shallweswim.main --port=12345
Then visit http://localhost:12345 in your browser.
# Build the Docker image
docker build -t shallweswim .
# Run the container
docker run -e PORT=80 -p 12345:80 shallweswim
Then visit http://localhost:12345 in your browser.
The application is hosted on Google Cloud Run:
# Deploy to Google Cloud Run
./build_and_deploy.sh
# Install Poetry (recommended method)
curl -sSL https://install.python-poetry.org | python3 -
# Install dependencies
poetry install
# Set up pre-commit hooks
poetry run pre-commit install
The project uses pytest for tests and several tools to maintain code quality. These checks are configured as pre-commit hooks:
# Run unit tests (excluding integration tests)
poetry run pytest -v -k "not integration"
# Run integration tests (connects to external APIs)
poetry run pytest -v -m integration --run-integration
# Run type checking
poetry run mypy --config-file=pyproject.toml .
# Run linting to detect unused code
poetry run pylint shallweswim/ tests/
# Format code with Black
poetry run black .
# Run all pre-commit hooks
poetry run pre-commit run --all-files
# Run with code coverage
poetry run pytest --cov=shallweswim
# Run with code coverage and generate HTML report
poetry run pytest --cov=shallweswim --cov-report=html
Note: Integration tests connect to live NOAA CO-OPS API and may occasionally fail if external services are experiencing issues or if the expected data is temporarily unavailable.
When running locally, API documentation is available at:
- Swagger UI: http://localhost:12345/docs
- ReDoc: http://localhost:12345/redoc
This project is licensed under the MIT License - see the LICENSE file for details.
- NOAA CO-OPS API (Center for Operational Oceanographic Products and Services) for tide, current, and temperature data
- USGS NWIS API (National Water Information System) for water temperature data
- FastAPI for the web framework
- Matplotlib for data visualization
- Feather Icons for UI icons
- GoodService.io for NYC subway information
GitHub Actions workflows automatically verify the following on every push:
- Unit Tests: All unit tests pass
- Type Checking: No type errors are found by mypy
- Code Formatting: All Python code follows Black style
- Linting: No unused imports, variables, or arguments are detected by pylint
Additionally, a separate integration test workflow runs daily to ensure compatibility with external APIs.