SAGE Platform Services - Queue, Storage, and Service Abstractions
Project description
SAGE Platform
Platform Services Layer (L2) - Infrastructure abstractions for SAGE
๐ Overview
SAGE Platform provides core infrastructure abstractions that sit between the foundation layer
(sage-common) and the execution engine (sage-kernel). This Layer-2 platform service offers:
- Queue Abstractions: Unified interface for Python, Ray, and RPC queues
- Storage Abstractions: Pluggable key-value storage backends
- Service Base Classes: Foundation for building SAGE services
- Platform Interfaces: Common patterns for distributed systems
This package enables seamless switching between local and distributed execution modes without changing application code.
โจ Key Features
- Polymorphic Queues: Single API for Python Queue, Ray Queue, and RPC Queue
- Pluggable Storage: In-memory, Redis, and custom storage backends
- Service Framework: Base classes for building platform services
- Type-Safe: Full type hints and runtime validation
- Zero-Overhead: Minimal abstraction cost for local execution
Components
๐ Queue (sage.platform.queue)
Polymorphic queue descriptors supporting multiple backends:
from sage.platform.queue import (
BaseQueueDescriptor,
PythonQueueDescriptor,
RayQueueDescriptor,
RPCQueueDescriptor,
)
# Create a Ray queue
queue_desc = RayQueueDescriptor(maxsize=1000, queue_id="my_queue")
queue = queue_desc.queue_instance
# Use queue operations
queue_desc.put(item)
item = queue_desc.get()
Features:
- Lazy initialization
- Serialization support
- Cross-process communication
- Backend-agnostic API
๐พ Storage (sage.platform.storage)
Key-Value storage abstractions:
from sage.platform.storage.kv_backend import BaseKVBackend, DictKVBackend
# Use in-memory backend
backend = DictKVBackend()
backend.set("key", "value")
value = backend.get("key")
# Extend with custom backends
class RedisKVBackend(BaseKVBackend):
# Implement abstract methods
...
Supported Operations:
get(key),set(key, value),delete(key)has(key),clear(),get_all_keys()- Disk persistence:
store_data_to_disk(),load_data_to_memory()
๐ Service (sage.platform.service)
Base class for SAGE services:
from sage.platform.service import BaseService
class MyService(BaseService):
def __init__(self, config):
super().__init__(name="my_service")
self.config = config
def process(self, request):
# Service logic
return response
๐ฆ Package Structure
sage-platform/
โโโ src/
โ โโโ sage/
โ โโโ platform/
โ โโโ __init__.py
โ โโโ queue/ # Queue abstractions
โ โ โโโ base.py
โ โ โโโ python_queue.py
โ โ โโโ ray_queue.py
โ โ โโโ rpc_queue.py
โ โโโ storage/ # Storage backends
โ โ โโโ kv_backend.py
โ โโโ service/ # Service base classes
โ โโโ base.py
โโโ tests/
โโโ pyproject.toml
โโโ README.md
๐ Installation
Basic Installation
pip install sage-platform
Development Installation
cd packages/sage-platform
pip install -e .
With Optional Dependencies
# With Ray support (distributed queues)
pip install sage-platform[ray]
# With Redis support (distributed storage)
pip install sage-platform[redis]
# Full installation
pip install sage-platform[all]
๐ Quick Start
Using Queues
from sage.platform.queue import RayQueueDescriptor
# Create a distributed queue
queue_desc = RayQueueDescriptor(maxsize=1000, queue_id="my_distributed_queue")
# Producer
queue_desc.put({"task": "process_data", "data": [1, 2, 3]})
# Consumer
task = queue_desc.get()
print(f"Processing: {task}")
# Check queue status
print(f"Queue size: {queue_desc.qsize()}")
print(f"Empty: {queue_desc.empty()}")
Using Storage
from sage.platform.storage.kv_backend import DictKVBackend
# Create storage backend
storage = DictKVBackend()
# Store data
storage.set("user:1", {"name": "Alice", "age": 30})
storage.set("user:2", {"name": "Bob", "age": 25})
# Retrieve data
user = storage.get("user:1")
print(f"User: {user}")
# List all keys
keys = storage.get_all_keys()
print(f"All keys: {keys}")
# Persist to disk
storage.store_data_to_disk("storage.pkl")
Creating a Service
from sage.platform.service import BaseService
class DataProcessingService(BaseService):
def __init__(self, config):
super().__init__(name="data_processing")
self.config = config
self.initialize()
def initialize(self):
"""Initialize service resources"""
self.logger.info(f"Initializing {self.name}")
def process(self, request):
"""Process incoming requests"""
self.logger.debug(f"Processing request: {request}")
result = self._transform_data(request["data"])
return {"status": "success", "result": result}
def _transform_data(self, data):
# Service logic
return [x * 2 for x in data]
# Use service
service = DataProcessingService({"param": "value"})
result = service.process({"data": [1, 2, 3]})
print(result) # {"status": "success", "result": [2, 4, 6]}
๐ง Configuration
Services can be configured through environment variables or configuration files:
# platform_config.yaml
platform:
queue:
backend: ray # or python, rpc
maxsize: 1000
storage:
backend: dict # or redis
persist: true
save_path: ./storage
Architecture Position
L1: sage-common โ Foundation
L2: sage-platform โ YOU ARE HERE
L3: sage-kernel โ Execution Engine
sage-libs
L4: sage-middleware โ Domain Components
L5: sage-apps โ Applications
sage-tools
sage-benchmark
L6: sage-studio โ User Interface
Design Principles
- Generic Infrastructure: Platform services are not SAGE-specific
- Backend Agnostic: Support multiple implementations (Python, Ray, Redis, etc.)
- Minimal Dependencies: Only depends on
sage-common - Extensible: Easy to add new backends
Why L2 Layer?
Originally, these abstractions were scattered:
- Queue Descriptor in
sage-kernel(L3) โ - KV Backend in
sage-middleware(L4) โ - BaseService in
sage-kernel(L3) โ
This caused:
- Architecture confusion (infrastructure mixed with business logic)
- Dependency violations (L1 โ L3)
- Limited reusability
By creating L2:
- โ Clear separation of concerns
- โ Proper dependency direction
- โ Better reusability across components
๐งช Testing
# Run unit tests
pytest tests/unit
# Run integration tests
pytest tests/integration
# Run with coverage
pytest --cov=sage.platform --cov-report=html
๐ Documentation
- User Guide: See docs-public
- API Reference: See package docstrings and type hints
- Architecture: See Platform Layer Design
๐ค Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Related Packages
- sage-common: Foundation layer (L1) - provides basic utilities
- sage-kernel: Execution engine (L3) - uses platform abstractions
- sage-middleware: Service layer (L4) - uses storage and queues
- sage-libs: Library layer (L5) - uses all platform services
๐ฎ Support
- Documentation: https://intellistream.github.io/SAGE-Pub/
- Issues: https://github.com/intellistream/SAGE/issues
- Discussions: https://github.com/intellistream/SAGE/discussions
Part of the SAGE Framework | Main Repository
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file isage_platform-0.2.3-py3-none-any.whl.
File metadata
- Download URL: isage_platform-0.2.3-py3-none-any.whl
- Upload date:
- Size: 121.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5590484093c13320f13e21730936dc710eaf85f0bb27e01ce558b999a344ecc5
|
|
| MD5 |
9f9ae96e0208cf16ecb769d1908fa423
|
|
| BLAKE2b-256 |
c7f0e811e959e3acb189c8d669d57a24349a5f17de1756f9ccd4d210dcb03f9b
|