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.1.tar.gz (204.1 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.1-py3-none-any.whl (206.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: saterys-0.4.1.tar.gz
  • Upload date:
  • Size: 204.1 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.1.tar.gz
Algorithm Hash digest
SHA256 895553b7ade06e7d8dc063892f5824d6daa6307809e17094050c5e51e36d65b3
MD5 89fb27d479ebe7331645c2d2c241f41b
BLAKE2b-256 fbe55a1484c98093652636c6742be8fcc7a28e6c2b17a339154852422d06a6f7

See more details on using hashes here.

File details

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

File metadata

  • Download URL: saterys-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 206.5 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9864f2d9932896cee119093b59dcc1b1871b55dcc322b6311a88996df581603e
MD5 7fe1c69ea056fb27298b2597f9e51822
BLAKE2b-256 d3b2ea0969b2ee579e73297229ebeb66d10f6e1e08144ff75c8b14a1201e4c72

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