Planet‐API‐Reference - Black-Lights/planetscope-py GitHub Wiki
PlanetScopeQuery
PlanetScopeQuery
Class: Advanced Planet API query system for scene discovery and filtering.
Constructor
PlanetScopeQuery(api_key=None, config=None)
Parameters:
api_key
(str, optional): Planet API key. If not provided, uses authentication hierarchy.config
(dict, optional): Custom configuration settings.
Example:
query = PlanetScopeQuery()
query = PlanetScopeQuery(api_key="your_api_key")
Methods
search_scenes()
search_scenes(geometry, start_date, end_date, item_types=None, cloud_cover_max=0.2, **kwargs)
Search for Planet scenes with spatiotemporal filtering.
Parameters:
geometry
(dict|Polygon|str): Area of interest geometrystart_date
(str|datetime): Start date (inclusive)end_date
(str|datetime): End date (inclusive)item_types
(list, optional): Planet item types (default: ["PSScene"])cloud_cover_max
(float, optional): Maximum cloud cover (0.0-1.0, default: 0.2)sun_elevation_min
(float, optional): Minimum sun elevation angleasset_types
(list, optional): Specific asset types to include
Returns:
dict
: Search results with features, stats, and search parameters
Example:
results = query.search_scenes(
geometry={"type": "Point", "coordinates": [9.19, 45.46]},
start_date="2024-01-01",
end_date="2024-01-31",
cloud_cover_max=0.15,
sun_elevation_min=30
)
batch_search()
batch_search(geometries, start_date, end_date, **kwargs)
Process multiple geometries in batch.
Parameters:
geometries
(list): List of geometry objectsstart_date
(str|datetime): Start dateend_date
(str|datetime): End date**kwargs
: Additional search parameters
Returns:
list
: List of results for each geometry
Example:
geometries = [geom1, geom2, geom3]
batch_results = query.batch_search(geometries, "2024-01-01", "2024-01-31")
get_scene_stats()
get_scene_stats(geometry, start_date, end_date, interval="month")
Get statistical overview without downloading full scenes.
Parameters:
geometry
(dict): Area of intereststart_date
(str|datetime): Start dateend_date
(str|datetime): End dateinterval
(str, optional): Temporal grouping ("month", "day", "year")
Returns:
dict
: Statistical summary
filter_scenes_by_quality()
filter_scenes_by_quality(scenes, min_quality=0.7, max_cloud_cover=0.15, exclude_night=True)
Filter scenes by quality criteria.
Parameters:
scenes
(list): List of scene featuresmin_quality
(float, optional): Minimum overall quality scoremax_cloud_cover
(float, optional): Maximum cloud coverexclude_night
(bool, optional): Exclude night-time scenes
Returns:
list
: Filtered scene list
get_scene_previews()
get_scene_previews(scene_ids)
Get preview URLs for scenes.
Parameters:
scene_ids
(list): List of scene identifiers
Returns:
dict
: Mapping of scene_id to preview URL
MetadataProcessor
MetadataProcessor
Class: Advanced metadata processing and analysis for Planet scenes.
Constructor
MetadataProcessor(config=None)
Parameters:
config
(dict, optional): Custom configuration settings
Quality Thresholds
QUALITY_THRESHOLDS = {
"cloud_cover": {
"excellent": 0.05, "good": 0.15, "fair": 0.30, "poor": 1.0
},
"sun_elevation": {
"excellent": 45.0, "good": 30.0, "fair": 15.0, "poor": 0.0
},
"usable_data": {
"excellent": 0.95, "good": 0.85, "fair": 0.70, "poor": 0.0
}
}
Methods
extract_scene_metadata()
extract_scene_metadata(scene)
Extract comprehensive metadata from a Planet scene.
Parameters:
scene
(dict): Planet scene feature from search results
Returns:
dict
: Comprehensive metadata dictionary
Extracted Fields:
- Basic: scene_id, item_type, satellite_id, provider, acquired, published
- Temporal: acquisition_date, acquisition_time, year, month, day_of_year
- Quality: cloud_cover, sun_elevation, usable_data, ground_control
- Geometric: geometry_type, area_km2, bounds, centroid, perimeter_km
- Derived: season, solar_conditions, suitability, overall_quality
Example:
metadata = processor.extract_scene_metadata(scene)
print(f"Quality: {metadata['suitability']}")
print(f"Cloud cover: {metadata['cloud_cover']:.1%}")
assess_coverage_quality()
assess_coverage_quality(scenes, target_geometry=None)
Assess coverage quality for a collection of scenes.
Parameters:
scenes
(list): List of Planet scene featurestarget_geometry
(dict, optional): Target area for coverage analysis
Returns:
dict
: Comprehensive coverage assessment
Assessment Structure:
{
"total_scenes": int,
"coverage_statistics": {
"total_area_km2": float,
"unique_coverage_km2": float,
"overlap_factor": float,
"coverage_efficiency": float
},
"temporal_analysis": {
"date_range": {"start": str, "end": str},
"span_days": int,
"monthly_distribution": dict,
"seasonal_distribution": dict
},
"quality_analysis": {
"suitability_distribution": dict,
"cloud_cover": {"mean": float, "median": float, "min": float, "max": float},
"sun_elevation": {"mean": float, "median": float, "min": float, "max": float},
"overall_quality": {"mean": float, "median": float, "min": float, "max": float}
},
"recommendations": list
}
filter_by_metadata_criteria()
filter_by_metadata_criteria(scenes, criteria)
Filter scenes based on metadata criteria with comprehensive statistics.
Parameters:
scenes
(list): List of Planet scene featurescriteria
(dict): Filtering criteria
Criteria Options:
max_cloud_cover
(float): Maximum cloud cover (0.0-1.0)min_sun_elevation
(float): Minimum sun elevation (degrees)min_usable_data
(float): Minimum usable data fractionquality_category
(str): Required quality categorymin_overall_quality
(float): Minimum overall quality score
Returns:
tuple
: (filtered_scenes, filter_statistics)
Example:
criteria = {
"max_cloud_cover": 0.1,
"min_sun_elevation": 40.0,
"min_overall_quality": 0.8
}
filtered_scenes, stats = processor.filter_by_metadata_criteria(scenes, criteria)
generate_metadata_summary()
generate_metadata_summary(scenes)
Generate comprehensive metadata summary for scene collection.
Parameters:
scenes
(list): List of Planet scene features
Returns:
dict
: Detailed metadata summary
RateLimiter
RateLimiter
Class: Intelligent rate limiting for Planet API requests.
Constructor
RateLimiter(rates=None, session=None)
Parameters:
rates
(dict, optional): Rate limits per endpoint typesession
(requests.Session, optional): HTTP session
Default Rates:
{
"search": 10, # requests per minute
"activate": 5,
"download": 15,
"general": 10
}
Methods
make_request()
make_request(method, url, **kwargs)
Make HTTP request with rate limiting.
Parameters:
method
(str): HTTP methodurl
(str): Request URL**kwargs
: Request parameters
Returns:
requests.Response
: HTTP response
get_current_rate_status()
get_current_rate_status()
Get current rate limiting status for all endpoints.
Returns:
{
"search": {
"limit": 10,
"current_rate": 5.2,
"capacity_used": 0.52,
"requests_remaining": 5
},
# ... other endpoints
}
wait_for_capacity()
wait_for_capacity(endpoint_type, required_capacity=0.8)
Wait until endpoint has sufficient capacity.
Parameters:
endpoint_type
(str): Endpoint type to checkrequired_capacity
(float): Required free capacity (0.0-1.0)
get_performance_metrics()
get_performance_metrics()
Get performance metrics for rate limiting.
Returns:
{
"total_requests": int,
"average_response_time": float,
"endpoint_metrics": {
"search": {
"request_count": int,
"average_response_time": float,
"min_response_time": float,
"max_response_time": float
}
}
}
RetryableSession
RetryableSession
Class: Advanced session with circuit breaker pattern and intelligent retry logic.
Constructor
RetryableSession(rate_limiter=None, circuit_breaker_config=None)
Parameters:
rate_limiter
(RateLimiter, optional): Rate limiter instancecircuit_breaker_config
(dict, optional): Circuit breaker configuration
Circuit Breaker Config:
{
"failure_threshold": 5, # Failures before opening
"recovery_timeout": 60 # Seconds before retry attempt
}
Methods
request()
request(method, url, **kwargs)
Make HTTP request with advanced retry logic and circuit breaker protection.
Parameters:
method
(str): HTTP methodurl
(str): Request URL**kwargs
: Request parameters
Returns:
requests.Response
: HTTP response
Raises:
APIError
: Request failed after all retriesRateLimitError
: Rate limiting issues
Retry Configuration:
- Max retries: 3
- Backoff factor: 2.0
- Retry statuses: [408, 429, 500, 502, 503, 504]
- Retry methods: All HTTP methods
CircuitBreaker
CircuitBreaker
Class: Circuit breaker pattern for preventing cascading failures.
Constructor
CircuitBreaker(failure_threshold=5, recovery_timeout=60, expected_exception=APIError)
Parameters:
failure_threshold
(int): Number of failures before openingrecovery_timeout
(int): Seconds before attempting recoveryexpected_exception
(Exception): Exception type to handle
States
CLOSED
: Normal operation, requests pass throughOPEN
: Failures detected, requests fail fastHALF_OPEN
: Testing if service recovered
Methods
call()
call(func, *args, **kwargs)
Execute function with circuit breaker protection.
Parameters:
func
(callable): Function to execute*args
: Function arguments**kwargs
: Function keyword arguments
Returns:
- Function result
Raises:
APIError
: If circuit breaker is open or function fails
reset()
reset()
Manually reset circuit breaker to CLOSED state.
Utility Functions
Geometry Utilities
validate_geometry()
validate_geometry(geometry)
Validate and normalize GeoJSON geometry.
Parameters:
geometry
(dict|str|Polygon): Input geometry
Returns:
dict
: Validated GeoJSON geometry
Supported Formats:
- GeoJSON dict
- Shapely Polygon/Point
- WKT string
calculate_area_km2()
calculate_area_km2(geometry)
Calculate area of geometry in square kilometers.
Parameters:
geometry
(dict): GeoJSON geometry
Returns:
float
: Area in km²
create_point_geometry()
create_point_geometry(longitude, latitude)
Create point geometry from coordinates.
Parameters:
longitude
(float): Longitude coordinatelatitude
(float): Latitude coordinate
Returns:
dict
: GeoJSON Point geometry
create_bbox_geometry()
create_bbox_geometry(west, south, east, north)
Create bounding box polygon geometry.
Parameters:
west
(float): Western longitudesouth
(float): Southern latitudeeast
(float): Eastern longitudenorth
(float): Northern latitude
Returns:
dict
: GeoJSON Polygon geometry
Date Utilities
validate_date_range()
validate_date_range(start_date, end_date)
Validate and format date range for Planet API.
Parameters:
start_date
(str|datetime): Start dateend_date
(str|datetime): End date
Returns:
tuple
: (formatted_start_date, formatted_end_date)
Supported Formats:
- "YYYY-MM-DD"
- "YYYY-MM-DDTHH:MM:SS"
- datetime objects
Exception Classes
Base Exceptions
PlanetScopeError
Base exception for all PlanetScope-py errors.
Attributes:
message
(str): Error messagedetails
(dict): Additional error details
ValidationError
Validation and input parameter errors.
Usage:
try:
validate_geometry(invalid_geom)
except ValidationError as e:
print(f"Validation failed: {e.message}")
print(f"Suggestions: {e.details.get('suggestions', [])}")
APIError
Planet API communication errors.
Attributes:
status_code
(int): HTTP status coderesponse_data
(dict): API response data
Usage:
try:
results = query.search_scenes(...)
except APIError as e:
print(f"API Error: {e.message}")
print(f"Status: {e.status_code}")
RateLimitError
Rate limiting errors with retry information.
Attributes:
retry_after
(int): Seconds to wait before retryendpoint_type
(str): Affected endpoint type
Usage:
try:
response = rate_limiter.make_request(...)
except RateLimitError as e:
print(f"Rate limited: wait {e.retry_after}s")
time.sleep(e.retry_after)
AuthenticationError
Authentication and credential errors.
Attributes:
auth_methods
(list): Available authentication methods
ConfigurationError
Configuration and setup errors.
Configuration
Default Configuration
default_config = {
# API settings
"base_url": "https://api.planet.com/data/v1",
"auth_url": "https://api.planet.com/auth/v1",
# Rate limiting
"rate_limits": {
"search": 10,
"activate": 5,
"download": 15,
"general": 10
},
# Timeouts
"timeouts": {
"connect": 10,
"read": 30
},
# Retry settings
"max_retries": 3,
"backoff_factor": 2.0,
# Validation
"max_roi_area_km2": 25000,
"max_date_range_days": 366
}
Custom Configuration
from planetscope_py import PlanetScopeConfig
config = PlanetScopeConfig()
config.set('max_retries', 5)
config.set('rate_limits.search', 15)
# Use with components
query = PlanetScopeQuery(config=config.to_dict())
Search Response Format
Scene Search Results
{
"features": [
{
"id": "20240115_143000_82_251c",
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[lon, lat], ...](/Black-Lights/planetscope-py/wiki/[lon,-lat],-...)
},
"properties": {
"acquired": "2024-01-15T14:30:00.123456Z",
"cloud_cover": 0.05,
"sun_elevation": 45.2,
"sun_azimuth": 180.5,
"item_type": "PSScene",
"satellite_id": "2251c",
"provider": "planet",
"pixel_resolution": 3.0,
"ground_control": True,
"quality_category": "standard"
}
}
],
"stats": {
"total_scenes": 42,
"date_range": {
"start": "2024-01-01T00:00:00Z",
"end": "2024-01-31T23:59:59Z"
}
},
"search_params": {
"geometry": {...},
"filters": {...}
}
}
Metadata Fields
Basic Information
scene_id
: Unique scene identifieritem_type
: Planet item type ("PSScene")satellite_id
: Satellite identifierprovider
: Data provider ("planet")acquired
: Acquisition timestamp (ISO 8601)published
: Publication timestampupdated
: Last update timestamp
Quality Metrics
cloud_cover
: Cloud coverage (0.0-1.0)sun_elevation
: Sun elevation angle (degrees)sun_azimuth
: Sun azimuth angle (degrees)usable_data
: Usable data fraction (0.0-1.0, when available)quality_category
: Quality category ("standard", "test")pixel_resolution
: Pixel resolution (meters)ground_control
: Ground control availability (boolean)
Derived Metrics (from MetadataProcessor)
season
: Seasonal classification ("winter", "spring", "summer", "autumn")solar_conditions
: Solar quality ("optimal", "good", "marginal", "poor")suitability
: Overall suitability ("excellent", "good", "fair", "poor")overall_quality
: Composite quality score (0.0-1.0)
Geometric Properties
geometry_type
: Geometry type ("Polygon", "Point")area_km2
: Scene area (square kilometers)bounds
: Bounding box coordinatescentroid
: Geographic center pointperimeter_km
: Perimeter length (kilometers)aspect_ratio
: Width/height ratio
Error Handling Patterns
Basic Error Handling
from planetscope_py.exceptions import *
try:
results = query.search_scenes(geometry, start_date, end_date)
except ValidationError as e:
print(f"Invalid input: {e.message}")
print(f"Details: {e.details}")
except RateLimitError as e:
print(f"Rate limited: wait {e.retry_after}s")
time.sleep(e.retry_after)
except APIError as e:
print(f"API error [{e.status_code}]: {e.message}")
except PlanetScopeError as e:
print(f"General error: {e.message}")
Robust Retry Pattern
def robust_search(query, geometry, start_date, end_date, max_attempts=3):
"""Search with comprehensive error handling."""
for attempt in range(max_attempts):
try:
return query.search_scenes(geometry, start_date, end_date)
except RateLimitError as e:
if attempt < max_attempts - 1:
print(f"Rate limited, waiting {e.retry_after}s...")
time.sleep(e.retry_after)
continue
raise
except APIError as e:
if e.status_code >= 500 and attempt < max_attempts - 1:
delay = 2 ** attempt # Exponential backoff
print(f"Server error, retrying in {delay}s...")
time.sleep(delay)
continue
raise
except ValidationError:
# Don't retry validation errors
raise
raise APIError("Failed after all retry attempts")
Best Practices
Performance Optimization
- Use appropriate geometries: Points for single locations, polygons for regions
- Limit date ranges: Shorter ranges = faster queries
- Set reasonable filters: Balance completeness with performance
- Cache results: Store results for repeated analysis
- Monitor rate limits: Use status methods to track usage
Quality Assessment
- Use suitability classification: Excellent > Good > Fair > Poor
- Consider application requirements: Different apps need different quality
- Combine multiple metrics: Don't rely on single quality indicator
- Filter progressively: Apply basic filters first, then advanced
- Validate results: Always check filter statistics
Error Resilience
- Handle all exception types: Specific handling for each error type
- Implement retry logic: With exponential backoff for transient errors
- Monitor circuit breaker: Check for system-wide issues
- Log errors appropriately: Different levels for different error types
- Graceful degradation: Provide fallbacks when possible
Rate Limiting
- Use built-in rate limiting: Don't implement your own delays
- Monitor capacity: Check status before large operations
- Batch similar requests: Group related API calls
- Respect retry-after: Always honor API-provided delays
- Plan for peak usage: Consider time zones and usage patterns