Modern python framework
Project description
Snakia is a modern Python framework for creating applications with Entity-Component-System (ECS) architecture, event system, and reactive programming. Built with performance (maybe) and modularity in mind, Snakia provides a clean API for developing complex applications ranging from games to terminal user interfaces.
๐ Table of Contents
โจ Key Features
- ๐๏ธ ECS Architecture - Flexible entity-component-system for scalable game/app logic
- ๐ก Event System - Asynchronous event handling with filters and priorities
- ๐ Plugin System - Modular plugin architecture for extensibility
- ๐จ TUI Framework - Rich terminal user interface with reactive widgets
- โก Reactive Programming - Observable data streams and reactive bindings
- ๐ ๏ธ Rich Utilities - Decorators, properties, platform abstraction, and more
- ๐ฏ Type Safety - Full type hints and Pydantic integration
โ ๏ธ Experimental Framework
This framework is currently in beta/experimental stage. Not all features are fully implemented, there might be bugs, and the API is subject to change. Use at your own risk! ๐ง
๐ Installation
Prerequisites
- Python >= 3.12
- pip or uv (recommended) package manager
Install from PyPi (recommended)
pip install snakia
Install from Source
git clone https://github.com/RuJect/Snakia.git
cd Snakia
pip install -e .
๐ฏ Roadmap & TODO
Here's what we're working on to make Snakia even better:
- Plugin Isolation: restrict plugin access to only events and components statically defined in manifest
- Async & Multithreading: implement proper async/await support and multithreading capabilities
- Platform Support: expand platform abstraction to support more operating systems
- Random Implementations: add various random generations implementations
- TUI Widgets: create more ready-to-use TUI widgets and components
- Code Documentation: add comprehensive docstrings and inline comments
- Documentation: create detailed API documentation and tutorials
๐ Quick Start
from snakia.core.engine import Engine
from snakia.core.loader import Meta, Plugin, PluginProcessor
from snakia.core.ecs import Component
from snakia.types import Version
# Creating a component
class HealthComponent(Component):
value: int = 100
max_value: int = 100
# Creating a processor
class HealthProcessor(PluginProcessor):
def process(self, system):
for entity, (health,) in system.get_components(HealthComponent):
if health.value <= 0:
print(f"Entity {entity} died!")
# Creating a plugin
class HealthPlugin(Plugin, meta=Meta(
name="health",
version=Version.from_args(1, 0, 0),
processors=(HealthProcessor,)
)):
def on_load(self): pass
def on_unload(self): pass
# Starting the engine
engine = Engine()
engine.loader.register(HealthPlugin)
engine.loader.load_all()
engine.start()
๐๏ธ Architecture
Snakia is built on a modular architecture with clear separation of concerns:
Snakia/
โโโ core/ # Framework core
โ โโโ engine.py # Main engine
โ โโโ ecs/ # Entity-Component-System
โ โโโ es/ # Event System
โ โโโ loader/ # Plugin loading system
โ โโโ rx/ # Reactive programming
โ โโโ tui/ # Terminal User Interface
โโโ decorators/ # Decorators
โโโ property/ # Property system
โโโ platform/ # Platform abstraction
โโโ utils/ # Utilities
โโโ random/ # Random number generation
โโโ field/ # Typed fields
โโโ types/ # Special types
๐ฆ Examples
Health System
from snakia.core.engine import Engine
from snakia.core.ecs import Component
from snakia.core.es import Event
from snakia.core.loader import Meta, Plugin, PluginProcessor
from snakia.types import Version
from pydantic import Field
class HealthComponent(Component):
max_value: int = Field(default=100, ge=0)
value: int = Field(default=100, ge=0)
class DamageComponent(Component):
damage: int = Field(ge=0)
ticks: int = Field(default=1, ge=0)
class DeathEvent(Event):
entity: int = Field()
class HealthProcessor(PluginProcessor):
def process(self, system):
# Processing damage
for entity, (damage, health) in system.get_components(
DamageComponent, HealthComponent
):
health.value -= damage.damage
damage.ticks -= 1
if damage.ticks <= 0:
system.remove_component(entity, DamageComponent)
if health.value <= 0:
system.remove_component(entity, HealthComponent)
self.plugin.dispatcher.publish(DeathEvent(entity=entity))
class HealthPlugin(Plugin, meta=Meta(
name="health",
version=Version.from_args(1, 0, 0),
processors=(HealthProcessor,)
)):
def on_load(self): pass
def on_unload(self): pass
# Usage
engine = Engine()
engine.loader.register(HealthPlugin)
engine.loader.load_all()
# Creating a player
player = engine.system.create_entity(
HealthComponent(value=100, max_value=100)
)
# Dealing damage
engine.system.add_component(player, DamageComponent(damage=25, ticks=1))
engine.start()
TUI Application
from snakia.core.tui import CanvasChar, RenderContext
from snakia.core.tui.render import ANSIRenderer
from snakia.core.tui.widgets import TextWidget, BoxWidget, VerticalSplitWidget
import sys
class StdoutTarget:
def write(self, text: str): sys.stdout.write(text)
def flush(self): sys.stdout.flush()
def main():
# Creating widgets
title = TextWidget("Snakia TUI", CanvasChar(fg_color="cyan", bold=True))
content = TextWidget("Welcome to Snakia!", CanvasChar(fg_color="white"))
box = BoxWidget(20, 5, CanvasChar("โ", fg_color="green"))
# Layout
layout = VerticalSplitWidget([title, content, box], "-")
# Rendering
renderer = ANSIRenderer(StdoutTarget())
with RenderContext(renderer) as ctx:
ctx.render(layout.render())
if __name__ == "__main__":
main()
๐ค Contributing
We welcome contributions to Snakia development! Whether you're fixing bugs, adding features, or improving documentation, your help is appreciated.
How to Contribute
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests if applicable
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Guidelines
- Add type hints to all new code
- Write clear commit messages
- Update documentation for new features
- Test your changes thoroughly
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
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 snakia-0.5.0.tar.gz.
File metadata
- Download URL: snakia-0.5.0.tar.gz
- Upload date:
- Size: 28.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7771da4a76be4591ac43073ec73aecd73866487bf6746c435b82fb2c2fd4f61d
|
|
| MD5 |
16268f45577406784bd5a4f635f03ccc
|
|
| BLAKE2b-256 |
5d9dd06f192538be83484b18353d34e5b214502a90bf1fc7413ee486e4c94269
|
Provenance
The following attestation bundles were made for snakia-0.5.0.tar.gz:
Publisher:
pypi-publish.yml on RuJect/snakia
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
snakia-0.5.0.tar.gz -
Subject digest:
7771da4a76be4591ac43073ec73aecd73866487bf6746c435b82fb2c2fd4f61d - Sigstore transparency entry: 720798280
- Sigstore integration time:
-
Permalink:
RuJect/snakia@ae0427ec754ed812eafda100d94125c0c98dd720 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/RuJect
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@ae0427ec754ed812eafda100d94125c0c98dd720 -
Trigger Event:
release
-
Statement type:
File details
Details for the file snakia-0.5.0-py3-none-any.whl.
File metadata
- Download URL: snakia-0.5.0-py3-none-any.whl
- Upload date:
- Size: 58.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6655397fec486b14acd7f6fd9ba84347bb6b7a03539b1d7e276e44d4bcf1b46d
|
|
| MD5 |
a702c7011621ac228af47269f061b88a
|
|
| BLAKE2b-256 |
401bd48733550f81fe263cc8b35a206a619bbe7f638881f137fab560c93a408b
|
Provenance
The following attestation bundles were made for snakia-0.5.0-py3-none-any.whl:
Publisher:
pypi-publish.yml on RuJect/snakia
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
snakia-0.5.0-py3-none-any.whl -
Subject digest:
6655397fec486b14acd7f6fd9ba84347bb6b7a03539b1d7e276e44d4bcf1b46d - Sigstore transparency entry: 720798286
- Sigstore integration time:
-
Permalink:
RuJect/snakia@ae0427ec754ed812eafda100d94125c0c98dd720 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/RuJect
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@ae0427ec754ed812eafda100d94125c0c98dd720 -
Trigger Event:
release
-
Statement type: