Skip to main content

Async TCP in-memory datastore with secure client-server protocol, supporting real-time multi-client CRUD operations.

Project description

Nemoria

PyPI version Python Versions License: MIT

Nemoria is a lightweight, asynchronous, in-memory datastore with secure client-server protocol, supporting real-time multi-client CRUD operations.

With Nemoria, you can read and write data in real time from any process, thread, or program, using multiple clients simultaneously.

✨ Think of it as a tiny Redis-like system built entirely in Python.


Features

  • 🚀 Asynchronous I/O powered by asyncio
  • 🔑 Password-based authentication
  • 🧩 Nested routes with hierarchical Route objects
  • Simple CRUD API (get, all, set, delete, drop, purge, save, ping)
  • 🔄 Multi-client access – read and write data in real time across any process, thread, or external program
  • 🛠 Minimalistic & extensible design for custom protocols

Installation

A) Install from PyPI

pip install nemoria -U

B) Local source install

git clone https://github.com/moh-dehghan/nemoria.git
cd nemoria
pip install -e .

Verification

Check if the package is installed correctly:

python -c "import nemoria; print(nemoria.__version__)"

Quick Start

1. Run the Server

# server.py
import asyncio
from nemoria import Server

async def main():
    server = Server(
        host="localhost",
        port=1234,
        namespace="Nemoria",
        password="12345678",
        file="output.yaml",
        file_format="YAML",
    )

    # Run server
    await server.run_forever(raise_on_error=False)

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        pass

Run it in one terminal:

python server.py

2. Connect a Client

# client.py
import asyncio
from nemoria import Client, Route
# Also you can import Route from pyroute module -> from pyroute import Route

async def main():
    client = Client(host="localhost", port=1234, password="12345678")
    
    # Connect
    if not await client.connect():
        return

    # Create data
    await client.set(Route("user", "profile", "name"), "Alice")

    # Set data & Save on disk
    await client.set(Route("user", "profile", "age"), 30, save=True)

    # Read data
    print(await client.get(Route("user", "profile", "name")))  # -> "Alice"
    print(await client.all())  # -> {'user': {'profile': {'name': 'Alice', 'age': 30}}}

    # Update data
    await client.set(Route("user", "profile", "age"), 31)
    print(await client.get(Route("user", "profile", "age")))  # -> 31

    # Delete part of a route
    await client.delete(Route("user", "profile", "age"))
    print(await client.all())

    # Drop the entire top-level route & Save on disk
    await client.drop(Route("user"), save=True)
    print(await client.all())  # -> {}

    await asyncio.Future()

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        pass

Run it in another terminal:

python client.py

More Examples

Storing Nested Data

await client.set(Route("blog", "posts", "1", "title"), "Hello World")
await client.set(Route("blog", "posts", "1", "tags"), ["intro", "nemoria"])
await client.set(Route("blog", "posts", "2", "title"), "Async Rocks")

print(await client.all())
# {
#   "blog": {
#     "posts": {
#       "1": {"title": "Hello World", "tags": ["intro", "nemoria"]},
#       "2": {"title": "Async Rocks"}
#     }
#   }
# }

Deleting & Dropping & Purging & Saving

# Delete just one nested field
await client.delete(Route("blog", "posts", "1", "tags"))

# Drop entire "posts" subtree
await client.drop(Route("blog", "posts"))

# Clear entire datastore
await client.purge()

# Save on disk
await client.save()

Ping & Healthcheck

# Ping
print(await client.ping()) # -> Latency in milliseconds, or `None` on timeout/connection error.

# Healthcheck
print(await client.is_alive()) # -> True or False

Close Client & Shutdown Server

# Close Client
await client.close()

# Shutdown Server
await client.shutdown()

Development Notes

Nemoria is intentionally designed to be minimalistic yet extensible, with a focus on clarity.

  • 🧩 Architecture:
    The system follows a clear client–server separation.

    • Server: manages connections, authentication, and route-based storage.
    • Client: provides a high-level API for CRUD operations and route traversal.
    • Route: represents nested hierarchical keys for structured data access.
  • ⚙️ Technology Stack:

    • Implemented in Python 3.10+ using asyncio for fully asynchronous I/O.
    • Built around standard Python libraries to keep dependencies minimal.
    • Supports multiple concurrent clients with real-time access guarantees.
  • 🎯 Design Goals:

    • Prioritize readability and hackability over heavy optimizations.
    • Provide a safe playground for learning about async networking and protocol design.
    • Allow easy extension for advanced features like persistence, clustering, and pub/sub.

Roadmap

  • Persistent storage (save/load to disk)
  • Pub/Sub messaging
  • Cluster mode (multi-server)
  • Advanced query language

Educational Use

Nemoria is not only a functional datastore, but also an educational resource.
It is particularly valuable for:

  • 📚 Students & Learners: Understanding how asynchronous servers and clients communicate.
  • 🧑‍💻 Developers: Experimenting with custom protocols, networking, and route-based data models.
  • 🏫 Educators: Demonstrating practical concepts of asyncio, event loops, and concurrency in Python.

License

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

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

nemoria-1.0.6.tar.gz (22.1 kB view details)

Uploaded Source

Built Distribution

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

nemoria-1.0.6-py3-none-any.whl (26.4 kB view details)

Uploaded Python 3

File details

Details for the file nemoria-1.0.6.tar.gz.

File metadata

  • Download URL: nemoria-1.0.6.tar.gz
  • Upload date:
  • Size: 22.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for nemoria-1.0.6.tar.gz
Algorithm Hash digest
SHA256 c230280d0f008ec30301b1b89cd4ac7287c21e55fbf46ed477ac0fcf5b742aac
MD5 cb862815b592ccdb394b8bf72bc5f804
BLAKE2b-256 502d0a9a7eb6dff25d8b1bfc3bb6c6c412ff1567f5295211d2ccf0cd65d3c0d4

See more details on using hashes here.

File details

Details for the file nemoria-1.0.6-py3-none-any.whl.

File metadata

  • Download URL: nemoria-1.0.6-py3-none-any.whl
  • Upload date:
  • Size: 26.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for nemoria-1.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 f9ebba0acba50122be9c3595dc7fde4567624f5e634f8a027830c02a5ee5c85b
MD5 112d83441053371accec1ca6b098ee51
BLAKE2b-256 1ed4e1e4fbfa2d002212c4c3ebc60268f73022b7dac475867c7220a498b19f36

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