A modern, modular Python framework built for developers who believe in clean, expressive, zero-boilerplate code.
Arkhe is a modular, batteries-included Python framework that brings together the ergonomics of Spring Boot, Lombok, and Kotlin into a cohesive ecosystem — covering everything from AST-based metaprogramming and enterprise dependency injection to functional error handling, fluent HTTP clients, and a declarative 2D game engine.
Every module is independent and composable — use exactly what you need.
Installation · Ecosystem · Quick Start · Documentation · Contributing
Arkhe is distributed as a set of independent, modular Namespace Packages. Install exactly what you need.
Core & Metaprogramming:
pip install arkhe-core arkhe-metaWeb, Net & Config:
pip install arkhe-web arkhe-net arkhe-configGame Engine & Math:
pip install arkhe-game arkhe-mathEnterprise Utilities:
pip install arkhe-db arkhe-scheduler arkhe-log arkhe-osRequires Python 3.10 or higher. Combine packages freely — they all seamlessly integrate into the
arkhe.*namespace.
Each package is independent. Install only what you need — they all share the
arkhe.*namespace.
Package (pip install) |
Modules | Description |
|---|---|---|
arkhe-core |
types, utils, ensure, result, promise, trying |
Foundation types, functional error handling, utilities |
arkhe-meta |
komodo, oop, decorators, patterns |
AST metaprogramming, interfaces, abstract classes |
arkhe-config |
yaml, json, env |
Configuration management (YAML, JSON, dotenv) |
arkhe-web |
ignite, loom |
Enterprise DI framework, FastAPI integration, config engine |
arkhe-net |
net |
Fluent HTTP client — zero external dependencies |
arkhe-math |
math |
BigDecimal, Money, game-ready math primitives |
arkhe-game |
pyunix |
Declarative 2D game engine built on Pygame |
arkhe-db |
database, collections |
SQLite toolkit, strongly-typed data structures |
arkhe-scheduler |
scheduler, flow |
Cron-style task scheduler, throttling, debouncing |
arkhe-log |
slogger |
Professional logger with colours and formatters |
arkhe-os |
os, console, input, cli |
File utilities, terminal UI, interactive CLI inputs |
from arkhe.komodo import komodo
@komodo.logger
@komodo.copyable
@komodo.builder
@komodo.data
class Product:
id: int
name: str
price: float
active: bool = True
# All generated via AST — native bytecode, zero runtime overhead
p = Product(1, "Widget", 9.99)
p2 = p.copy_with(price=7.99)
Product.logger.info("Price updated")
req = (
Product.builder()
.with_id(1)
.with_name("Widget")
.with_price(9.99)
.build()
)from dataclasses import dataclass
from arkhe.database import DB, db_entity, db_column
DB.connect("app.db")
@db_entity("users")
@dataclass
class User:
id: int = db_column(primary_key=True)
email: str = db_column(unique=True)
name: str = db_column()
DB.create_table(User)
DB.insert_into("users").values(name="Alice", email="alice@example.com").execute()
users: list[User] = DB.select("*").from_table("users").into(User)from arkhe import yaml, env
from arkhe.env import Env
Env.load()
db_host = yaml.database.host # attribute access on any .yml file
db_port = env.db.port.int # → int(DB_PORT)
debug = env.debug.bool # → bool(DEBUG)
secret = env.secret_key.required # raises ConfigError if missingfrom arkhe.ignite import Application
from arkhe.ignite.decorators import Service, Controller, PostConstruct
from arkhe.ignite.web.rest import Get, Post
@Service
class UserService:
def get_users(self) -> list[str]:
return ["Hope", "Alex"]
@Controller("/users")
class UserController:
def __init__(self, user_service: UserService):
self.user_service = user_service
@Get("/")
async def list_users(self):
return self.user_service.get_users()
@PostConstruct
async def on_start(self):
print("UserController ready!")
app = Application.run(web=True, starters=["web"])from arkhe.pyunix import Game, Entity, Rigidbody, BoxCollider, BodyType
from arkhe.pyunix.math import Vector2, Color
@Game(title="My Game", size=(800, 600), fps=60)
class MyGame:
@Game.start
def start(self):
self.player = Player(x=400, y=300)
@Game.update
def update(self, dt: float):
pass
@Game.draw
def draw(self, screen):
screen.fill(Color.BLACK.to_tuple())
@Game.text(x=10, y=10, size=24, color="white")
def score_ui(self):
return "SCORE: 1000"
class Player(Entity):
def __init__(self, x, y):
super().__init__(
x=x, y=y,
rigidbody=Rigidbody(body_type=BodyType.DYNAMIC, mass=1.0),
collider=BoxCollider(width=32, height=32),
)
@Entity.update
def movement(self, dt):
if self.input.is_action_pressed("jump"):
self.rigidbody.add_impulse(Vector2(0, -500))
if __name__ == "__main__":
MyGame().run()A Spring Boot-inspired framework for production Python applications.
Features: IoC container, constructor injection, lifecycle hooks, EventBus, FastAPI integration, cron scheduling, JWT security, profile-aware configuration, and a TestContainer for mocking.
from arkhe.ignite.decorators import Service, Repository
@Repository
class UserRepository:
def find(self, id: int) -> dict:
return {"id": id, "name": "Alice"}
@Service
class UserService:
def __init__(self, repo: UserRepository): # injected automatically by type
self.repo = repo
def get_user(self, id: int):
return self.repo.find(id)# application.yml
server:
port: 8080
database:
url: "postgresql://localhost/myapp"
jwt:
secret: "my-secret"
expiry_minutes: 60from arkhe.ignite.decorators import Value
@Service
class AppConfig:
@Value("server.port")
port: int
@Value("database.url")
db_url: strfrom arkhe.ignite.decorators import EventListener
from arkhe.ignite.events import EventBus
import dataclasses
@dataclasses.dataclass
class UserRegistered:
user_id: int
email: str
@Service
class NotificationService:
@EventListener(UserRegistered)
async def on_user_registered(self, event: UserRegistered):
print(f"Welcome email sent to {event.email}")
await app.context.event_bus.publish(UserRegistered(user_id=1, email="alice@example.com"))from arkhe.ignite.decorators import Scheduled
@Service
class ReportJob:
@Scheduled("0 8 * * 1") # every Monday at 08:00
async def weekly_report(self):
...
@Scheduled("*/5 * * * *") # every 5 minutes
def poll_queue(self):
...from arkhe.ignite.testing import TestContainer
from unittest.mock import MagicMock
def test_user_service():
container = TestContainer()
mock_repo = MagicMock()
mock_repo.find.return_value = {"id": 1, "name": "Alice"}
container.override(UserRepository, mock_repo)
container.register(UserService)
service = container.get(UserService)
assert service.get_user(1)["name"] == "Alice"Installation extras:
pip install arkhe-ignite[web] # FastAPI + uvicorn
pip install arkhe-ignite[jwt] # PyJWT
pip install arkhe-ignite[scheduler] # croniter
pip install arkhe-ignite[all] # everythingLombok-style, annotation-driven metaprogramming via AST. Eliminates class boilerplate with composable decorators — no metaclasses, no runtime proxies, no wrappers. Methods are generated as native bytecode.
| Decorator | Generated __init__ |
Lombok equivalent |
|---|---|---|
@komodo.all_args_constructor |
All annotated fields as parameters | @AllArgsConstructor |
@komodo.required_args_constructor |
Only fields without defaults | @RequiredArgsConstructor |
@komodo.no_args_constructor |
No parameters (uses defaults) | @NoArgsConstructor |
| Decorator | What it generates | Lombok equivalent |
|---|---|---|
@komodo.data |
__init__, __repr__, __eq__, __hash__ |
@Data |
@komodo.value |
Immutable data object — data + immutable |
@Value |
@komodo.record |
data + immutable + full serialization |
@Value + extras |
@komodo.builder |
Fluent .Builder inner class with .build() |
@Builder |
@komodo.immutable |
__setattr__/__delattr__ freeze after construction |
— |
@komodo.logger |
Injects a stdlib logger class attribute |
@Slf4j |
@komodo.copyable |
.copy() and .copy_with(**overrides) |
@With |
@komodo.getter |
get_<field>() methods for all fields |
@Getter |
@komodo.setter |
set_<field>(value) methods for all fields |
@Setter |
@komodo.withers |
with_<field>(value) — returns new instance |
@With |
@komodo.non_null |
ValueError if any arg is None |
@NonNull |
@komodo.validated |
Runtime type-checking from annotations | — |
@komodo.to_dict |
.to_dict() -> dict |
— |
@komodo.json |
.to_json() and .from_json() |
— |
from arkhe.komodo import komodo
# Data class — auto __init__, __repr__, __eq__, __hash__
@komodo.logger
@komodo.copyable
@komodo.data
class Product:
id: int
name: str
price: float
active: bool = True
p = Product(1, "Widget", 9.99)
p2 = p.copy_with(price=7.99)
Product.logger.info("Price updated")
# Fluent builder with validation
@komodo.builder
@komodo.validated
@komodo.all_args_constructor
class CreateUserRequest:
username: str
email: str
role: str = "viewer"
req = (
CreateUserRequest.builder()
.with_username("alice")
.with_email("alice@example.com")
.with_role("admin")
.build()
)
# Immutable value object
@komodo.value
class Money:
amount: float
currency: str
m = Money(9.99, "USD")
m.amount = 0.0 # AttributeError: Money is immutablefrom arkhe.komodo import contract
from arkhe.komodo.contract import requires, ensures, invariant
@komodo.all_args_constructor
class BankAccount:
balance: float
@contract(
requires(lambda self, amount: amount > 0, "amount must be positive"),
invariant(lambda self: self.balance >= 0, "balance must never be negative"),
)
def withdraw(self, amount: float) -> None:
self.balance -= amountfrom arkhe.komodo import KomodoInspector
info = KomodoInspector(Product)
print(info.features) # {'data', 'all_args_constructor', 'to_str', 'eq', ...}
print(info.fields) # {'id': int, 'name': str, 'price': float, 'active': bool}
print(info.summary()) # formatted ASCII tableA fluent, lightweight SQLite query builder with entity mapping, transactions, and safe result types. Zero external dependencies.
from dataclasses import dataclass
from arkhe.database import DB, db_entity, db_column
DB.connect("app.db", wal=True)
@db_entity("users")
@dataclass
class User:
id: int = db_column(primary_key=True)
email: str = db_column(unique=True)
name: str = db_column(nullable=False)
DB.create_table(User)
# INSERT
row_id = DB.insert_into("users").values(name="Alice", email="alice@example.com").execute()
# SELECT — mapped to objects
users: list[User] = DB.select("*").from_table("users").into(User)
# SELECT — fluent filtering
active = (
DB.select("id", "name")
.from_table("users")
.where("active = ?", True)
.order_by("name", "ASC")
.limit(10)
.execute()
)
# UPDATE / DELETE
DB.update("users").set(name="Alice Smith").where("id = ?", 1).execute()
DB.delete_from("users").where("id = ?", 99).execute()
# Transactions — re-entrant safe
with DB.transaction():
DB.update("accounts").set(balance=400).where("id = ?", 1).execute()
DB.update("accounts").set(balance=1100).where("id = ?", 2).execute()
# Safe execution — never raises
result = DB.insert_into("users").values(email="dup@example.com").execute_safe()
if result.is_success:
print(f"rowid: {result.data}")
else:
print(result.error_message)Python → SQLite type mapping: int → INTEGER, float → REAL, str → TEXT, bytes → BLOB, bool → INTEGER.
Explicit interfaces, abstract classes,
@overrideand@finalwith fail-fast validation at class definition time — not at instantiation. Errors are caught when the module is loaded.
from arkhe.oop import interface, implements, abstract_class, abstract_method, override, final
@interface
class ILogger:
def log(self, message: str) -> None:
pass
@interface
class IHealthCheck:
def is_healthy(self) -> bool:
pass
@abstract_class
class BaseService:
def startup(self):
print("Service started")
@abstract_method
def execute(self):
pass
@implements(ILogger, IHealthCheck)
class UserService(BaseService):
def log(self, message: str) -> None:
print(f"[UserService] {message}")
def is_healthy(self) -> bool:
return True
@override
def execute(self):
print("Executing user logic")
@final
class AppConfig:
debug: bool = False
version: str = "1.0.0"Missing implementation → immediate error at class definition:
InterfaceImplementationError
Class UserService does not implement:
- log(message: str) -> None
| Feature | arkhe.oop |
Python abc |
|---|---|---|
| Explicit interfaces | @interface |
No equivalent |
| Implementation validation | @implements — at class definition |
Only at instantiation |
| Descriptive errors with signatures | Yes | Basic |
| Interface inheritance | Yes, accumulative | No equivalent |
| Interface attributes | Yes | No equivalent |
@override with validation |
Yes | No equivalent |
@final |
Yes | No equivalent |
A fully declarative game engine built on top of Pygame — inspired by Unity and Godot. No messy
while Trueloops.
from arkhe.pyunix.app import Game
@Game(title="My Game", size=(800, 600), fps=60, vsync=True)
class MyGame:
@Game.start
def on_start(self):
pass # load resources, create entities
@Game.update
def on_update(self, dt: float):
pass # frame logic
@Game.draw
def on_draw(self, screen):
screen.fill((30, 30, 40))
@Game.text(x=10, y=10, size=20, color="yellow")
def score_label(self):
return f"Score: {self.score}"
MyGame().run()from arkhe.pyunix.sprite import Entity
from arkhe.pyunix.physics import Rigidbody, BoxCollider, BodyType, PhysicsWorld
from arkhe.pyunix.input import Input
from arkhe.pyunix.math import Vector2
PhysicsWorld.set_gravity(0, 900)
class Player(Entity):
def __init__(self):
super().__init__(
x=200, y=300,
rigidbody=Rigidbody(body_type=BodyType.DYNAMIC, gravity_scale=1.0),
collider=BoxCollider(28, 48),
)
@Entity.update
def move(self, dt):
h = Input.get_axis("horizontal")
self.rigidbody.velocity.x = h * 200
if Input.action_just_pressed("jump"):
self.rigidbody.add_impulse(Vector2(0, -450))
@Entity.on_collision_enter
def on_hit(self, info):
if info.normal.y < -0.5:
self.on_ground = True| Hook | When it fires |
|---|---|
@Sprite.ready |
Once, on construction |
@Sprite.update |
Every frame (receives dt) |
@Sprite.fixed_update |
Fixed physics timestep |
@Sprite.draw |
Every frame (receives surface) |
@Sprite.destroy |
Before entity is removed |
@Sprite.on_collision_enter |
First frame of collision |
@Sprite.on_collision_stay |
Each frame while colliding |
@Sprite.on_collision_exit |
When collision ends |
@Sprite.on_trigger_enter |
On entering a trigger zone |
@Sprite.pause / @Sprite.resume |
On game pause/resume |
- Camera — smooth follow, world bounds, shake, offset
- Audio — music streaming, SFX with pitch variation
- Assets — preloading, caching, image/audio/font management
- Animation — spritesheet-based with state machine
- Particles — burst and continuous emitters
- Tween — property animation with easing functions
- TileMap — tile-based map rendering with auto-culling
- Timer —
Timer.after(),Timer.every()callbacks - Scene — scene manager with push/pop stack
- Events — pub/sub event system between entities
Debug: Press
F3at runtime for an overlay showing FPS, physics bodies, camera position, and time scale.
Not just a parser — a runtime configuration engine with O(1) lookup and hot-reload.
# config/database.yml
database:
host: "localhost"
port: 5432
pool:
min_size: 2
max_size: 10from arkhe import yaml
# Zero-boilerplate: auto-scans all .yml files in your project
host = yaml.get("database.host") # string dot-path
max_pool = yaml.database.pool.max_size # Pythonic attribute access
# Watch for changes in long-running processes
yaml.watch(True)
# Explicit scan for a specific directory
from pathlib import Path
yaml.scan(Path("src/config/"))
# Trace where a value comes from
print(yaml.where("database.host")) # "/absolute/path/to/database.yml"How it works: on first access, Arkhe scans your project and generates a .arkhe/yaml_index.json flat index — every dot-path mapped to its source file. Subsequent lookups are O(1). Only changed files are re-parsed.
Add
.arkhe/to your.gitignore.
Modern, typed, chainable
.envvariable management. Inspired by NestJS and Spring Boot.
from arkhe import env
from arkhe.env import Env
Env.load() # or Env.load("config/.env")
# Chainable attribute access — auto-uppercases all segments
host = env.db.host # → DB_HOST
port = env.db.port.int # → int(DB_PORT)
debug = env.debug.bool # → bool(DEBUG)
hosts = env.allowed_hosts.list # → ["localhost", "127.0.0.1"]
# Guards and defaults
secret = env.secret_key.required # raises ConfigError if missing
db_pw = env.db.password.default("root") # fallback valueResolution flow: env.db.pool.max_size.int → int(os.environ["DB_POOL_MAX_SIZE"]).
# Descriptor API
class Config:
host = Env.property("DB_HOST", default="localhost")
port = Env.property("DB_PORT", cast_type=int, default=5432)
# Injection decorator
@Env.inject(api_key="API_KEY", host="DB_HOST")
def connect(api_key=None, host=None):
...A structured alternative to
.env— hierarchical, typed, modular config files. Zero external dependencies.
# app.loom
@module("app")
@server {
host: "localhost"
port: 8080
debug: true
}
@database {
host: "127.0.0.1"
port: 5432
name: "myapp"
pool: { min: 2, max: 10 }
}
from arkhe.loom import Loom, env
Loom.load("app.loom")
host = env.app.server.host # fully qualified
port = env.server.port.int # scope-level flattening
debug = env.debug.bool # global flattening (if unique)
# Schema binding to dataclasses
@Loom.bind("database", scope="database")
@dataclasses.dataclass
class DbConfig:
host: str = "localhost"
port: int = 5432
name: str = "myapp"
# Hot-reload watchers
@Loom.watch("server.port")
def on_port_change(new_value):
restart_http_server(int(new_value))Rust-style diagnostics:
🚨 LoomSyntaxError in 'database.loom' (Line 4)
3 | @db.main {
4 | host = "localhost"
^
5 | }
Error: Property 'host' uses '=' instead of ':'
Hint: Replace with: host: "localhost"
Fluent HTTP client for the Arkhe ecosystem. No external dependencies — pure stdlib (
urllib).
from arkhe.net import request, API
# Before (standard Python)
import urllib.request, json
req = urllib.request.Request(url, headers={"Authorization": "Bearer token"})
with urllib.request.urlopen(req, timeout=5) as r:
data = json.loads(r.read())
# After (Arkhe Net)
r = request(url).auth_bearer(token).timeout(5).get()
if r.success:
print(r.json)result = (
request("https://api.example.com/users/42")
.auth_bearer("my-token")
.timeout(10)
.retry(attempts=3, delay=1, exponential=True)
.cache(minutes=5)
.expect(200)
.on_success(lambda r: print(f"Loaded in {r.elapsed_ms:.0f}ms"))
.get()
)api = (
API("https://api.github.com")
.auth_bearer(token)
.timeout(10)
.retry(3)
)
octocat = api.get("/users/octocat").json
repos = api.get("/users/octocat/repos").json
api.post("/repos", json={"name": "new-repo", "private": False})| Property | Description |
|---|---|
r.status |
HTTP status code |
r.success / r.ok |
True if 200 ≤ status < 300 |
r.json |
Deserialised body |
r.text |
Body as UTF-8 string |
r.bytes |
Body as raw bytes |
r.elapsed_ms |
Execution time in ms |
r.headers |
Response headers dict |
r.cookies |
Cookies from Set-Cookie |
Java-inspired, fluent data structures with type hint support.
from arkhe.collections import (
ArrayList, LinkedList, Stack, Queue,
OrderedSet, HashMap, BiMap, MultiMap,
PriorityQueue, CircularBuffer, Stream, Optional, Result,
)
# Lazy Stream pipeline — functional-style data processing
result = (
Stream.range(1, 11)
.filter(lambda n: n % 2 == 0)
.map(lambda n: n ** 2)
.take(3)
.to_list()
) # [4, 16, 36]
# Fixed-capacity ring buffer — evicts oldest on overflow
logs = CircularBuffer(3)
logs.add("A").add("B").add("C").add("D")
logs.to_list() # ["B", "C", "D"]
# Priority queue — min-heap by default
tasks = PriorityQueue()
tasks.add("High priority", priority=1)
tasks.add("Low priority", priority=10)
tasks.poll() # "High priority"
# BiMap — bidirectional one-to-one mapping
roles = BiMap()
roles.put("ADMIN", 1).put("MOD", 2)
roles.get("ADMIN") # 1
roles.get_key(2) # "MOD"| Structure | Description |
|---|---|
ArrayList |
Dynamic array with fluent API and bounds-checking |
LinkedList |
Doubly-linked list, O(1) insertions at both ends |
Stack |
LIFO — backed by Python list |
Queue |
FIFO — backed by collections.deque |
OrderedSet |
Unique elements preserving insertion order |
HashMap |
Fluent dict wrapper |
BiMap |
Bidirectional one-to-one map |
MultiMap |
One key → many values |
PriorityQueue |
Heap-backed, min or max, custom key function |
CircularBuffer |
Fixed-capacity ring buffer — evicts oldest |
Stream |
Lazy functional pipeline — map, filter, reduce, group, window… |
Optional |
Null-safe container — eliminates if x is not None |
Result |
Discriminated union — Ok(value) / Err(error) |
Asynchronous execution without asyncio, event loops, or futures. Inspired by JavaScript Promises, Java
CompletableFuture, and C# Tasks.
from arkhe.promise import Promise
# Chain transformations
Promise.of(load_user) \
.map(lambda user: user.name) \
.map(str.upper) \
.then(print) \
.catch(log_error) \
.finally_(cleanup)
# Parallel execution — all in parallel, return ordered results
results = Promise.all(load_users, load_orders, load_products).join(timeout=30)
# Race — first to finish wins
Promise.race(server1, server2, server3).then(use_fastest)
# Any — first success wins (only fails if ALL fail)
Promise.any(api1, api2, api3).then(use_first_success)
# Built-in options in .of()
Promise.of(api_request, delay=1, timeout=10, retry=3)Internals: concurrent.futures.ThreadPoolExecutor with a shared global pool. No asyncio exposed.
Functional error handling without
try/exceptscattered across your code. Inspired by KotlinTry, RustResult, and ScalaEither.
from arkhe.trying import Try
# Before
try:
user = load_user()
if not user.active:
raise Exception("Inactive")
print(user.name)
except Exception:
print("Guest")
# After
Try.of(load_user) \
.filter(lambda u: u.active, "Inactive user") \
.map(lambda u: u.name) \
.recover(lambda ex: "Guest") \
.on_success(print)| Method | Success |
Failure |
|---|---|---|
.map(fn) |
Transforms value | Passes through |
.flat_map(fn) |
fn returns Try |
Passes through |
.filter(pred, msg) |
Fails if pred=False | Passes through |
.recover(fn) |
Passes through | Converts to Success |
.recover_if(type, fn) |
Passes through | Recovers only on matching type |
.on_success(fn) |
Executes fn(value) |
Ignored |
.on_failure(fn) |
Ignored | Executes fn(error) |
.tap(fn) |
Side-effect, returns self | Ignored |
.or_else(default) |
Returns value | Returns default |
.to_optional() |
Returns value | Returns None |
.to_promise() |
Promise.resolved(v) |
Promise.rejected(e) |
Fluent cron-style task scheduler — thread-safe, no asyncio, no external dependencies.
from arkhe.scheduler import Scheduler
Scheduler.every(30).seconds(sync_cache)
Scheduler.every(5).minutes(
lambda: request("https://api.example.com/health").get()
).log()
Scheduler.every(1).hours(generate_report) \
.name("daily-report") \
.on_error(lambda ex: log.error(ex))
Scheduler.start()Advanced task scheduling, throttling, concurrency, and rate limiting.
from arkhe.flow import Flow
@Flow.interval(5.0)
def ping_server():
print("Ping!")
@Flow.throttle(1.0)
def on_mouse_move(x, y):
pass
@Flow.retry(times=3, wait=2.0)
def fetch_api():
pass
@Flow.debounce(wait=0.3)
def on_search_input(query):
search(query)
results = Flow.parallel(task_a, task_b, task_c)Available utilities: @Flow.delay, @Flow.repeat, @Flow.interval, @Flow.retry, @Flow.timeout, @Flow.debounce, @Flow.throttle, @Flow.once, @Flow.after, Flow.parallel, @Flow.threaded, Flow.run_async, Flow.schedule, Flow.loop.
Interactive CLI inputs, forms, and validation.
from arkhe.input import Input
name = Input.text("What is your name?", default="Guest")
age = Input.integer("Age?", min=0, max=120)
email = Input.email("Email address?")
tags = Input.multi_select("Topics", ["Python", "Games", "Web"])A comprehensive suite of utility decorators. All preserve function metadata via
functools.wraps.
from arkhe.decorators import benchmark, cache, retry, validate_types, event, emit
@benchmark
@cache
def expensive_calculation(x):
return sum(i * i for i in range(x))
@retry(times=3, delay=2.0)
def fetch_api_data():
pass
@validate_types
def process_user(age: int, name: str):
pass # raises TypeError if types don't match
@event("user_registered")
def send_welcome_email(user_id):
pass
emit("user_registered", 101)| Category | Decorators |
|---|---|
| Execution | @benchmark, @cache, @once, @rate_limit |
| Resiliency | @safe, @trace, @retry |
| Threading | @threaded, @async_task, @delay |
| Validation | @not_null, @validate, @validate_types |
| Architecture | @singleton, @observable, @startup, @shutdown, @event |
| Documentation | @deprecated, @experimental |
A professional, colourised, extensible logger — from
"Hello, World!"to production.
from arkhe.slogger import get_logger, SLogger, LogLevel
log = get_logger("server", level=LogLevel.DEBUG, file="server.log")
log.info("Server starting on port 8080")
log.success("Database connected!")
log.warn("Memory usage above 80%")
log.error("Failed to reach upstream service")
log.fatal("Unrecoverable error — shutting down")
# Decorators
@log.log_calls(show_return=True, show_time=True)
def calculate(x, y):
return x + y
@log.catch_errors(ConnectionError, default=None)
def connect_database(host: str):
...
@log.time_it(label="startup sequence")
def boot():
...| Level | Colour | Use |
|---|---|---|
TRACE |
Dim cyan | Detailed flow tracing |
DEBUG |
Cyan | Internal variables, states |
INFO |
Blue | Normal application events |
SUCCESS |
Bright green | Completed operations |
WARN |
Bright yellow | Unusual, non-critical situations |
ERROR |
Bright red | Recoverable errors |
FATAL |
Red background | Unrecoverable failures |
# Formatters
# Default: [14:32:01] [INFO ] [server] Message
# Simple: [INFO ] Message
# JSON: {"ts": "14:32:01", "level": "INFO", "prefix": "server", "msg": "Message"}
from arkhe.slogger import JSONFormatter
log = get_logger("api", formatter=JSONFormatter())Rich terminal output for modern CLI applications.
from arkhe.console import Console
Console.success("Migration complete!")
Console.error("Failed to connect.")
Console.warn("Memory usage high.")
Console.info("Server starting...")
Console.print("Custom", color="magenta", bold=True)
# Interactive prompts
name = Console.ask("Your name?", default="Guest")
go = Console.confirm("Proceed?", default=True)
env = Console.choose("Environment", ["dev", "staging", "prod"])
# Progress tracking
with Console.progress(total=100, label="Downloading") as bar:
for _ in range(100):
bar.update(1)
# Animated spinner
with Console.spinner("Fetching data..."):
time.sleep(2)
# Structured table
Console.table([
{"ID": 1, "Name": "Alice", "Role": "Admin"},
{"ID": 2, "Name": "Bob", "Role": "User"},
], title="User Directory")Game-ready math primitives — vectors, matrices, easing functions, and geometry utilities.
from arkhe.pyunix.math import Vector2, Vector3, Matrix4, Color
v = Vector2(3, 4)
v2 = v.normalised() # (0.6, 0.8)
d = v.dot(Vector2(1, 0))
red = Color.RED
faded = red.lerp(Color.BLACK, 0.5)Fluent file and directory interaction helpers.
from arkhe.os import File, Dir
content = File("config.json").read()
File("output.txt").write("Hello, World!")
File("data.json").copy_to("backup/data.json")
Dir("src/").list() # list all entries
Dir("logs/").ensure() # create if not exists
Dir("old/").delete()Bootstrap a professional project structure in one command:
arkhe init --name my_appGenerated structure includes pre-configured support for ruff, pytest, and mypy.
- Breaking: Migrated from monolithic
pip install arkheto 11 independent Namespace Packages (arkhe-core,arkhe-meta,arkhe-net, etc.). - Tooling: Adopted
uvworkspaces for monorepo management andhatchlingas the modern build backend. - Architecture: Each package has its own
pyproject.tomlwith explicit dependencies — no more accidental cross-module coupling. - Compatibility: All existing
arkhe.*imports continue to work unchanged thanks to Python Namespace Packages.
- Database: Added
arkhe.database— fluent SQLite toolkit with entity mapping, transactions, andDBResultsafe execution. - OOP: Added
arkhe.oop— interfaces, abstract classes,@override, and@finalwith fail-fast validation at class definition time. - Komodo: Replaced
@komodo.constructorwith three explicit constructors:@komodo.no_args_constructor,@komodo.required_args_constructor,@komodo.all_args_constructor— aligned with Lombok's naming. Updated@komodo.getterand@komodo.setterto generate explicitget_<field>()/set_<field>(value)methods instead of Python properties. - Trying: Added
Trymonad for fluent, functional error handling withouttry/except. - Promise: Implemented modern Promise API for async execution (
then,catch,all,race,any) without asyncio. - Input: Added comprehensive module for interactive CLI inputs, form handling, and data sanitisation.
- SLogger: Upgraded core logger — colours, formatters, decorators, context managers.
- Pyunix: Fixed physics bounding box discrepancies (
rect.topleftvsrect.center) ensuring pixel-perfectBoxColliderinteractions. - FlappyBird Demo: Refactored
examples/flappybird.pyto use Pyunix's modern physics engine, Animator, and Trigger zones. - Ignite Docs: Published comprehensive documentation covering DI, FastAPI, EventBus, Scheduled Tasks, and TestContainers.
- Ignite Core: Rebranded and refactored the legacy
boltcontainer into theigniteapplication framework. - EventBus: Added publish/subscribe event bus.
- Web module: Seamless FastAPI integration.
- Cron Jobs: Introduced
@Scheduleddecorators viacroniter. - Testing: Added
TestContainerfor dependency-isolated integration testing.
Full documentation is available in the docs/ directory:
| Module | Doc |
|---|---|
| 🔥 Ignite Framework | docs/ignite.md |
| 🦎 Komodo Metaprogramming | docs/komodo.md |
| 🗄 Database Toolkit | docs/database.md |
| 🏛 OOP Utilities | docs/oop.md |
| 🎮 Pyunix Game Engine | docs/pyunix.md |
| ⚙️ YAML Intelligent Registry | docs/yaml.md |
| 🔒 Environment Management | docs/env.md |
| 🧵 Loom Configuration | docs/loom.md |
| 🌐 Net HTTP Client | docs/net.md |
| 🗂 Collections | docs/collections.md |
| ✨ Promise | docs/promise.md |
| 🛡 Trying | docs/trying.md |
| 🗓 Scheduler | docs/scheduler.md |
| ⏱ Flow Control | docs/flow.md |
| 🎛 Input | docs/input.md |
| ✨ Decorators | docs/decorators.md |
| 📋 SLogger | docs/slogger.md |
| 🖥 Console Utilities | docs/console.md |
| 🧮 Math | docs/math.md |
| 📁 OS & File Utilities | docs/os.md |
Arkhe uses a monorepo managed by uv workspaces:
arkhe/
├── pyproject.toml # Workspace root
├── packages/
│ ├── arkhe-core/ # Foundation types & utilities
│ ├── arkhe-meta/ # Komodo, OOP, decorators
│ ├── arkhe-config/ # YAML, JSON, Env
│ ├── arkhe-web/ # Ignite, Loom
│ ├── arkhe-net/ # HTTP client
│ ├── arkhe-math/ # BigDecimal, Money
│ ├── arkhe-game/ # Pyunix game engine
│ ├── arkhe-db/ # Database, Collections
│ ├── arkhe-scheduler/ # Scheduler, Flow
│ ├── arkhe-log/ # SLogger
│ └── arkhe-os/ # OS, Console, Input, CLI
└── tests/
Contributions are welcome!
- Clone the repository
- Install
uvif you haven't already - Sync the workspace:
uv sync --all-packages - Run tests:
uv run pytest - Lint code:
ruff check .
Please review our Security Policy for information on reporting vulnerabilities.
This project is licensed under the MIT License.