Skip to main content

Saterys — Scalable Analysis Toolkit for Earth Remote sYStemS

Project description

SATERYS_Icon SATERYS

Scalable Analysis Toolkit for Earth Remote sYStemS

PyPI version Python versions License: MIT Build

A modern geospatial pipeline builder with interactive node-based workflows

📖 Documentation🚀 Quick Start🎯 Examples🧩 Plugins


🌟 Overview

SATERYS is a powerful geospatial analysis platform that combines the best of modern web technologies with robust geospatial processing capabilities. Build complex Earth observation workflows using an intuitive drag-and-drop interface, execute Python-based analysis nodes, and visualize results on interactive maps.

SATERYS Interface

✨ Key Features

🎨 Visual Pipeline Builder

  • Interactive, node-based workflow canvas powered by Svelvet
  • Drag-and-drop creation and editing of geospatial analysis pipelines
  • Real-time connection validation and error highlighting
  • Dark/Light theme support for comfortable use in any environment
  • Visual grouping and annotation of workflow components

High-Performance Backend

  • FastAPI-powered REST API for rapid, scalable processing
  • Asynchronous execution for efficient resource use
  • Hot-reloadable plugin system for instant extension and customization
  • Automatic error handling and detailed logging
  • Built-in job queue for batch and long-running tasks

🛰️ Geospatial Native

  • Native support for GeoTIFF, COG, and other raster formats
  • Interactive map preview with Leaflet and tile-based raster visualization via rio-tiler
  • Coordinate system handling and automatic reprojection
  • Raster statistics, band math, and index calculation (NDVI, NDWI, PCA, etc.)
  • Vector data support (GeoJSON, SHP, GPKG) for overlays and analysis

🔌 Extensible & Modular Architecture

  • Plugin-based node system: add your own analysis nodes in Python
  • Custom analysis functions and reusable workflow components
  • Easy integration with existing Python geospatial tools (NumPy, Rasterio, Shapely, etc.)
  • Modular design for rapid prototyping and extension
  • Built-in and user-defined nodes auto-discovered at startup

🧩 Plugin Ecosystem

  • Simple plugin API for adding new node types
  • Hot-reload support for rapid development
  • Community-contributed plugins for specialized tasks

🖥️ Modern Web UI

  • Responsive, single-page application built with Svelte
  • Real-time workflow editing and execution feedback
  • Integrated documentation and example workflows
  • User authentication and role-based access (optional)

🚀 Quick Start

Installation

# Install SATERYS
pip install saterys
# Verify installation
saterys --help

Launch the Application

# Start SATERYS server
saterys

# Access the web interface at http://localhost:8000

The application will automatically:

  • 🔍 Discover all available plugins
  • 🌐 Start the FastAPI backend
  • 🎨 Serve the Svelte frontend
  • 📊 Open your default browser

Development Mode

For development with hot-reload:

# Start with auto-reload
saterys --dev

🎯 Examples

Basic Workflow: Hello World

  1. Add a Node: Click "Add Node" and select "hello"
  2. Configure: Set the name parameter to "SATERYS"
  3. Execute: Click the "Run" button
  4. View Results: Check the output in the logs panel
# This runs automatically when you execute the hello node
def run(args, inputs, context):
    name = args.get("name", "world")
    return {"text": f"hello {name}"}

Geospatial Workflow: NDVI Calculation

Create a vegetation index from satellite imagery:

# 1. Add a raster input node
# 2. Set path to your multispectral image (e.g., Landsat, Sentinel)
# 3. Add NDVI calculation node
# 4. Configure band indices (e.g., red=4, nir=5 for Landsat 8)
# 5. Connect nodes and execute

Example NDVI Node Configuration:

{
  "red_band": 4,
  "nir_band": 5,
  "output_path": "./results/ndvi_output.tif",
  "dtype": "float32"
}

Custom Processing with Script Node

Write inline Python for custom analysis:

# Script node example - band math
import numpy as np
import rasterio

def process_raster(input_raster):
    with rasterio.open(input_raster["path"]) as src:
        # Read bands
        red = src.read(4).astype(float)
        nir = src.read(5).astype(float)
        
        # Custom vegetation index
        evi = 2.5 * ((nir - red) / (nir + 6 * red - 7.5 * blue + 1))
        
        return {"custom_index": evi}

📚 Documentation

Built-in Nodes

Node Type Description Use Case
🔢 raster.input Load GeoTIFF/COG files Data ingestion
🌿 raster.ndvi Calculate NDVI Vegetation analysis
🌊 raster.ndwi Calculate NDWI Water body detection
📊 raster.pca Principal Component Analysis Dimensionality reduction
sum Sum numeric values Basic arithmetic
👋 hello Hello world example Testing/demos
📝 script Custom Python code Flexible processing

API Endpoints

The FastAPI backend provides REST endpoints for integration:

# Get available node types
GET /node_types

# Execute a node
POST /run_node
{
  "nodeId": "unique-id",
  "type": "raster.ndvi", 
  "args": {"red_band": 4, "nir_band": 5},
  "inputs": {...}
}

# Register raster for preview
POST /preview/register
{
  "id": "my-raster",
  "path": "/path/to/file.tif"
}

# Get map tiles
GET /preview/tile/{id}/{z}/{x}/{y}.png

🧩 Creating Plugins

SATERYS uses a simple plugin architecture. Create custom nodes by adding Python files to a nodes/ directory:

Basic Plugin Structure

# nodes/my_custom_node.py

NAME = "my.custom.node"  # Unique identifier
DEFAULT_ARGS = {         # Default configuration
    "param1": "default_value",
    "param2": 42
}

def run(args, inputs, context):
    """
    Execute the node logic
    
    Args:
        args: Node configuration parameters
        inputs: Data from connected upstream nodes  
        context: Runtime context (nodeId, etc.)
        
    Returns:
        Dictionary with output data
    """
    # Your processing logic here
    result = process_data(args, inputs)
    
    return {
        "type": "custom",
        "data": result,
        "metadata": {...}
    }

Raster Processing Plugin Example

# nodes/custom_filter.py

NAME = "raster.custom_filter"
DEFAULT_ARGS = {
    "filter_size": 3,
    "operation": "gaussian"
}

def run(args, inputs, context):
    import rasterio
    import numpy as np
    from scipy import ndimage
    
    # Get input raster
    raster_input = next(
        (inp for inp in inputs.values() 
         if inp.get("type") == "raster"), 
        None
    )
    
    if not raster_input:
        raise ValueError("No raster input found")
    
    # Process the raster
    with rasterio.open(raster_input["path"]) as src:
        data = src.read(1)
        
        # Apply filter
        if args["operation"] == "gaussian":
            filtered = ndimage.gaussian_filter(
                data, 
                sigma=args["filter_size"]
            )
        
        # Save result...
        output_path = "/tmp/filtered_result.tif"
        # ... saving logic here ...
        
    return {
        "type": "raster",
        "path": output_path,
        "operation": "custom_filter"
    }

Plugin Discovery

SATERYS automatically discovers plugins from:

  1. Built-in nodes: saterys/nodes/ (package installation)
  2. User nodes: ./nodes/ (current working directory)

Simply restart the application after adding new plugins!


🛠️ Advanced Usage

Environment Configuration

# Custom host and port
export SATERYS_HOST=0.0.0.0  
export SATERYS_PORT=8080

# Raster cache directory
export RASTER_CACHE=./my_cache

# Development frontend origin (for CORS)
export SATERYS_DEV_ORIGIN=http://localhost:5173

Docker Usage

FROM python:3.10-slim

RUN pip install saterys

# Add your custom nodes
COPY nodes/ /app/nodes/

WORKDIR /app

EXPOSE 8000

CMD ["saterys", "--host", "0.0.0.0"]

Programmatic Usage

import uvicorn
from saterys.app import app

# Customize the FastAPI app
@app.get("/custom")  
def custom_endpoint():
    return {"message": "Custom endpoint"}

# Run programmatically
if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

🤝 Contributing

We welcome contributions! Here's how to get started:

Development Setup

# Clone the repository
git clone https://github.com/bastian6666/SATERYS.git
cd SATERYS

# Install in development mode
pip install -e .

# Install frontend dependencies (if modifying UI)
cd saterys/web
npm install

# Start development server
npm run dev

Code Style

  • Follow PEP 8 for Python code
  • Use type hints where possible
  • Add docstrings for public functions
  • Test your changes before submitting

Submitting Changes

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.


🙏 Acknowledgments

  • FastAPI: For building modern, high-performance APIs with ease.
  • Uvicorn: An ASGI server for lightning-fast application deployment.
  • Pydantic: Ensuring data validation and management is smooth and reliable.
  • NumPy: The foundation for numerical computing in Python.
  • rio-tiler: Efficient raster tiling and preview generation.
  • Rasterio: Simplifying geospatial raster data I/O.
  • Fiona: A powerful library for vector data handling (GPKG/SHP).
  • PyProj: For seamless coordinate reference system transformations.
  • Shapely: Geometry manipulation made easy.
  • APScheduler: A flexible scheduling library for background jobs.
  • SQLAlchemy: The go-to library for database interaction and ORM functionality.
  • pytz: Comprehensive timezone support.
  • tzlocal: Simplifies local timezone detection.

📞 Support


Made with ❤️ for the geospatial community

GitHub stars Twitter Follow

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

saterys-0.4.tar.gz (178.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

saterys-0.4-py3-none-any.whl (180.7 kB view details)

Uploaded Python 3

File details

Details for the file saterys-0.4.tar.gz.

File metadata

  • Download URL: saterys-0.4.tar.gz
  • Upload date:
  • Size: 178.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for saterys-0.4.tar.gz
Algorithm Hash digest
SHA256 2f3e07d16fac08be2691fd2dc149f14d8558314c39ffc9004e9031a0dfc5025e
MD5 24df0f707b01475cf906233675252cfe
BLAKE2b-256 c591b35ecbb1ce63e576d86fdaba4caed8718bf60638f2a3bbb9e174bce3700b

See more details on using hashes here.

File details

Details for the file saterys-0.4-py3-none-any.whl.

File metadata

  • Download URL: saterys-0.4-py3-none-any.whl
  • Upload date:
  • Size: 180.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for saterys-0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 09beb493d1401d63b49727098dbb290e2e1473628a73fb4372261a5215aa19ae
MD5 ed5f0ce765a71fd615a61ba7a785848a
BLAKE2b-256 5cd2e3185e307a30b17365362a670191109fd831cd3b290a7ff7316ea0ded844

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page