Planet‐API‐Reference - Black-Lights/planetscope-py GitHub Wiki

PlanetScopeQuery

Class: PlanetScopeQuery

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 geometry
  • start_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 angle
  • asset_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 objects
  • start_date (str|datetime): Start date
  • end_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 interest
  • start_date (str|datetime): Start date
  • end_date (str|datetime): End date
  • interval (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 features
  • min_quality (float, optional): Minimum overall quality score
  • max_cloud_cover (float, optional): Maximum cloud cover
  • exclude_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

Class: MetadataProcessor

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 features
  • target_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 features
  • criteria (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 fraction
  • quality_category (str): Required quality category
  • min_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

Class: RateLimiter

Intelligent rate limiting for Planet API requests.

Constructor

RateLimiter(rates=None, session=None)

Parameters:

  • rates (dict, optional): Rate limits per endpoint type
  • session (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 method
  • url (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 check
  • required_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

Class: RetryableSession

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 instance
  • circuit_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 method
  • url (str): Request URL
  • **kwargs: Request parameters

Returns:

  • requests.Response: HTTP response

Raises:

  • APIError: Request failed after all retries
  • RateLimitError: 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

Class: CircuitBreaker

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 opening
  • recovery_timeout (int): Seconds before attempting recovery
  • expected_exception (Exception): Exception type to handle

States

  • CLOSED: Normal operation, requests pass through
  • OPEN: Failures detected, requests fail fast
  • HALF_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 coordinate
  • latitude (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 longitude
  • south (float): Southern latitude
  • east (float): Eastern longitude
  • north (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 date
  • end_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 message
  • details (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 code
  • response_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 retry
  • endpoint_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 identifier
  • item_type: Planet item type ("PSScene")
  • satellite_id: Satellite identifier
  • provider: Data provider ("planet")
  • acquired: Acquisition timestamp (ISO 8601)
  • published: Publication timestamp
  • updated: 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 coordinates
  • centroid: Geographic center point
  • perimeter_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

  1. Use appropriate geometries: Points for single locations, polygons for regions
  2. Limit date ranges: Shorter ranges = faster queries
  3. Set reasonable filters: Balance completeness with performance
  4. Cache results: Store results for repeated analysis
  5. Monitor rate limits: Use status methods to track usage

Quality Assessment

  1. Use suitability classification: Excellent > Good > Fair > Poor
  2. Consider application requirements: Different apps need different quality
  3. Combine multiple metrics: Don't rely on single quality indicator
  4. Filter progressively: Apply basic filters first, then advanced
  5. Validate results: Always check filter statistics

Error Resilience

  1. Handle all exception types: Specific handling for each error type
  2. Implement retry logic: With exponential backoff for transient errors
  3. Monitor circuit breaker: Check for system-wide issues
  4. Log errors appropriately: Different levels for different error types
  5. Graceful degradation: Provide fallbacks when possible

Rate Limiting

  1. Use built-in rate limiting: Don't implement your own delays
  2. Monitor capacity: Check status before large operations
  3. Batch similar requests: Group related API calls
  4. Respect retry-after: Always honor API-provided delays
  5. Plan for peak usage: Consider time zones and usage patterns