SnowEx/snowexsql: snowexsql-v1.1.0-rc1
Authors/Creators
- 1. @M3Works @AdventureData
- 2. Boise State University
- 3. University of Washington
- 4. M3 Works
- 5. Micron Technology
- 6. Cryosphere Geophysics And Remote Sensing (CryoGARS) group, Boise State University
- 7. @joby
Description
Release Notes: v1.1.0-rc1
Release Date: TBD
Previous Release: v1.0.0
Overview
This release candidate adds comprehensive AWS Lambda support for serverless database access, enabling users to query SnowEx data without direct database connections or heavy geospatial dependencies.
New Features
Lambda Client (snowexsql.lambda_client)
SnowExLambdaClient: New client class for accessing SnowEx database via AWS Lambda- Automatically discovers and exposes all measurement classes (PointMeasurements, LayerMeasurements)
- Provides serverless access without requiring database credentials locally
Measurement Class Accessors: Direct access to measurement classes via attributes
client = SnowExLambdaClient() classes = client.get_measurement_classes() PointMeasurements = classes['PointMeasurements'] LayerMeasurements = classes['LayerMeasurements'] df = client.PointMeasurements.from_filter(instrument='camera', limit=10) instruments = client.LayerMeasurements.all_instrumentsDynamic Method Discovery: Automatically mirrors all API methods and properties without manual synchronization
- Supports
from_filter(),from_area(),from_unique_entries() - Supports all property accessors:
all_instruments,all_campaigns,all_types, etc.
- Supports
Server-Side Spatial Queries:
from_area()uses PostGIS for efficient database-side spatial filtering- Supports point + buffer and polygon geometries
- Handles WKT string input or shapely geometry objects
- Automatic CRS transformation
Smart DataFrame Conversion:
- Returns GeoDataFrame when geometry data is available (requires geopandas)
- Falls back to pandas DataFrame when geopandas not installed
- Handles multiple geometry formats (WKB hex, WKT, GeoJSON)
Lambda Handler (snowexsql.lambda_handler)
Auto-Discovery System: Automatically discovers measurement classes based on naming conventions
- Classes ending in 'Measurements' with a MODEL attribute are automatically exposed
- No manual registration required for new measurement classes
AWS Secrets Manager Integration: Secure credential management
- Retrieves database credentials from AWS Secrets Manager
- Writes temporary credentials file for API compatibility
Action Routing: Handles multiple request types:
test_connection: Database connectivity verificationquery: Raw SQL query execution{ClassName}.{method}: Class-based API calls (e.g.,PointMeasurements.from_filter)- Property access:
{ClassName}.all_{property}(e.g.,PointMeasurements.all_instruments)
Response Standardization: Consistent JSON response format
- Success:
{action, data, count} - Error:
{error, action}
- Success:
API Enhancements (snowexsql.api)
PostGIS Spatial Queries
from_area()Improvements: Now uses pure PostGIS for spatial filtering- Eliminates dependency on geoalchemy2.functions for spatial operations
- Automatic SRID detection from database
- Smart CRS transformation (transforms search geometry to match database SRID for index usage)
- Supports WKT string input in addition to shapely geometries
- Works in both local and Lambda environments
Verbose Mode Support
New
verboseParameter: Added tofrom_filter()andfrom_area()verbose=False(default): Returns minimal columns from primary tableverbose=True: Returns denormalized data with related table information- Includes explicit join management to avoid cartesian products
Denormalized Columns (when
verbose=True):- PointMeasurements: observation details, instrument specs, measurement types
- LayerMeasurements: site details, instrument specs, measurement types, weather conditions
New Class Methods
_build_select_clause(verbose): Customizable column selection per class_add_base_joins(): Minimal joins for non-verbose queries_add_verbose_joins(): Explicit joins for verbose mode
GeoDataFrame Compatibility
query_to_geopandas(): Updated to handle both local and Lambda environments- Returns GeoDataFrame when geopandas available (local)
- Returns pandas DataFrame with WKB/WKT geometry when geopandas not available (Lambda)
- Client-side conversion to GeoDataFrame handled by lambda_client
Deployment Infrastructure
Docker Configuration (deployment/docker/)
- Lambda-Optimized Dockerfile: AWS Lambda Python 3.12 base image
- Minimal Dependencies:
requirements-lambda.txtwith lightweight packages- Excludes heavy dependencies (geopandas, rasterio, fiona)
- Includes core requirements: sqlalchemy, psycopg2-binary, pandas, shapely, geoalchemy2
Deployment Scripts (deployment/scripts/)
deploy.sh: Automated deployment pipeline- Builds Docker image
- Pushes to AWS ECR
- Updates Lambda function code
- Optional function testing
test_lambda.sh: Comprehensive testing script- Tests database connectivity
- Verifies response format
- Checks CloudWatch logs
update_lambda_config.sh: Configuration management- Updates timeout (default: 90s)
- Updates memory allocation (default: 1024MB)
AWS Policies (deployment/aws/)
ecr_policy.json: ECR repository permissions for Lambdasecrets_policy.json: Secrets Manager access policy
Breaking Changes
RasterMeasurements
- Lambda Limitation:
RasterMeasurementsnot fully supported in Lambda environment- Raises
ImportErrorwith helpful message directing users to local API - Requires rasterio which is too heavy for Lambda deployment
- Raises
Performance Improvements
Optimized Database Queries
- SRID Detection: Automatically detects database SRID to avoid unnecessary transformations
- Index-Aware Queries: Transforms search geometry (not database geometry) for optimal index usage
- EXISTS Clauses: Uses EXISTS instead of joins for large table counts (29GB+ tables)
Spatial Query Optimization
- PostGIS Server-Side: All spatial filtering happens in database
- Significantly reduces data transfer
- Leverages PostGIS spatial indexes (GIST)
- Eliminates client-side geometry processing
Testing
New Test Suites
tests/deployment/test_lambda_handler.py: Handler/server-side logic tests- Tests direct handler function calls with local credentials
- Validates action routing, error handling, response formats
- Includes PostGIS spatial query tests
tests/deployment/test_lambda_client.py: Client/end-to-end tests- Tests deployed Lambda function via client
- Validates full round-trip: client → Lambda → database → client
- Tests GeoDataFrame conversion
Test Markers
@pytest.mark.handler: Handler-only tests (no Lambda deployment required)@pytest.mark.integration: Full integration tests (requires deployed Lambda)
Requirements
Local Development
- Python 3.8+
- geopandas (optional, for GeoDataFrame support)
- shapely (required for spatial queries)
Lambda Deployment
- AWS CLI configured
- Docker installed
- ECR repository:
snowexsql - Lambda function:
lambda-snowex-sql - Secrets Manager secret with database credentials
Lambda Runtime
- Python 3.12
- Minimal dependencies (no geopandas, no rasterio)
- Secrets Manager access for credentials
Developer Notes
Adding New Measurement Classes
To make a new measurement class available via Lambda:
Class name MUST end with 'Measurements'
class WeatherMeasurements(BaseDataset):Class MUST have a MODEL attribute
MODEL = WeatherData # Required!Class MUST inherit from BaseDataset
class WeatherMeasurements(BaseDataset):
The Lambda handler will automatically discover and expose your class:
client.weather_measurements.from_filter()
client.weather_measurements.all_instruments
Validation Function
Use validate_measurement_class() to verify your class follows conventions:
from snowexsql.lambda_handler import validate_measurement_class
validate_measurement_class(WeatherMeasurements, 'WeatherMeasurements')
Documentation
New Documentation Files
deployment/README.md: Deployment structure and quick start guide- Inline documentation in all new modules
- Comprehensive docstrings following NumPy style
Updated Examples
All existing examples continue to work without modification. Lambda client provides alternative access method without changing local API behavior.
Migration Guide
For Existing Users
No changes required! All existing code continues to work:
from snowexsql.api import PointMeasurements
df = PointMeasurements.from_filter(instrument='camera', limit=10)
For New Lambda Users
# Instead of direct database connection
from snowexsql.lambda_client import SnowExLambdaClient
client = SnowExLambdaClient()
df = client.point_measurements.from_filter(instrument='camera', limit=10)
Known Limitations
- Raster Operations: Not supported in Lambda (use local API)
- Large Queries: Lambda has 15-minute timeout limit
- Memory: Lambda configured with 1024MB (adjustable via
update_lambda_config.sh) - Cold Starts: First request may take 5-10 seconds
Note: This is a release candidate (RC). Please test thoroughly before using in production environments.
Files
SnowEx/snowexsql-v1.1.0rc1.zip
Files
(18.3 MB)
| Name | Size | Download all |
|---|---|---|
|
md5:0b731c6241a83d12d0d04fe4ffc7b723
|
18.3 MB | Preview Download |
Additional details
Related works
- Is supplement to
- Software: https://github.com/SnowEx/snowexsql/tree/v1.1.0rc1 (URL)
Software
- Repository URL
- https://github.com/SnowEx/snowexsql