Skip to main content

ZewSFS

ZewSFS is a Python-based implementation of the SmartFoxServer 2X (SFS2X) protocol, offering both client and server-side capabilities. This library provides fundamental data types, transport abstractions (TCP/WebSocket in the future), message encoding/decoding, and extensibility for custom encryption and compression.

Table of Contents


Features

  • Core: Rich, low-level data structures (e.g., SFSObject, SFSArray) mirroring SmartFoxServer object models.
  • Protocol: Easy-to-use encoding/decoding functions to convert between raw bytes and high-level Message objects.
  • Transport: Ready-made TCP server (via TCPAcceptor) and client (TCPTransport) for sending and receiving SFS2X messages.
  • Encryption: Optional AES-128-CBC support via PyCryptodome.

Installation

Install module with pip or uv

uv pip install sfs2x

If you plan to use encrypted packets, install PyCryptodome:

pip install pycryptodome

Quick Start

Note: These examples describe the server-client for the low-Level transport module. High-level server and client modules are currently under development.

Transport Client Example

import asyncio
from sfs2x.transport.factory import client_from_url
from sfs2x.protocol import Message, ControllerID, SysAction
from sfs2x.core import SFSObject


async def run_client():
    async with client_from_url("tcp://localhost:9933") as client:
        payload = SFSObject()
        payload.put_utf_string("message", "Hello from ZewSFS client!")

        await client.send(Message(
            controller=ControllerID.SYSTEM,
            action=SysAction.PUBLIC_MESSAGE,
            payload=payload
        ))

        response = await client.recv()
        print("Response:", response)


if __name__ == "__main__":
    asyncio.run(run_client())

Server Example

import asyncio
from sfs2x.transport import server_from_url, TCPTransport
from sfs2x.protocol import Message, ControllerID, SysAction
from sfs2x.core import SFSObject


async def handle_client(client: TCPTransport):
    async for message in client.listen():
        response_payload = SFSObject(message="Hello back from server!")
        
        await client.send(Message(
            controller=ControllerID.SYSTEM,
            action=SysAction.PUBLIC_MESSAGE,
            payload=response_payload
        ))


async def run_server():
    async for client in server_from_url("tcp://localhost:9933"):
        print(f"New client connected: {client.host}:{client.port}")
        asyncio.create_task(handle_client(client))


if __name__ == "__main__":
    asyncio.run(run_server())

Modules Overview

Core

The core package provides fundamental data structures and serialization logic:

  1. Fields and Arrays:

    • Bool, Byte, Short, Int, Long, Float, Double, UtfString, Text
    • BoolArray, ByteArray, ShortArray, IntArray, LongArray, FloatArray, DoubleArray, UtfStringArray
  2. Containers:

    • SFSObject for key-value pairs
    • SFSArray for sequential lists
  3. Utility Classes:

    • Buffer for reading raw bytes
    • Field as a base for packable items
    • registry, decode, and encode for bridging raw bytes ↔ SFS data types

Protocol

The protocol package focuses on reading/writing SFS2X-compliant packets:

  • Message: High-level class representing a single SFS2X message with controller, action, and payload.
  • Flag: Enum for packet flags (binary, compressed, encrypted, etc.).
  • encode / decode: Convert Message ↔ binary packets, optionally using compression and AES encryption.
  • AESCipher: AES-128-CBC encryption/decryption for securing packets (requires PyCryptodome).

Transport

The transport package provides abstractions for client-server communication:

  • Transport (abstract): Defines the required methods (open, send, recv, close) for any transport.
  • TCPTransport: Client-side implementation using asyncio streams (TCP).
  • TCPAcceptor: Server-side implementation using asyncio start_server (TCP).
  • client_from_url / server_from_url: Factory methods to instantiate a transport from a URL (e.g., tcp://localhost:9933).

Usage Examples

Working with SFSObject and SFSArray

Imperative style:

from sfs2x.core import SFSObject, SFSArray

obj = SFSObject()
obj.put_int("score", 1200)
obj.put_double_array("history", [3.14, -4.5, 2.7]) \
    .put_bool("isAdmin", True)

arr = SFSArray()
arr.add_utf_string("item1")
arr.add_utf_string("item2")

obj["myArray"] = arr

Declarative style:

from sfs2x.core import UtfString, Int, SFSObject, SFSArray

obj = SFSObject({
    "name": UtfString("Zewsic"),
    "score": Int(2022),
    "items": [
        UtfString("Sword"),
        UtfString("Shield"),
        SFSObject({"key": UtfString("value")})
    ], # SFSArray
    "object": {
        "some": UtfString("Thing")
    } # SFSObject
})

Argument style:

Note: Added as experiment, unstable.

from sfs2x.core import UtfString, Int, SFSObject, SFSArray

obj = SFSObject(
    username=UtfString("Zewsic"),
    coins=Int(1200)
)

Serialization / Deserialization

from sfs2x.core import decode, SFSObject, Int

# Serialize
obj = SFSObject({"example": Int(42)})
raw_bytes = obj.to_bytes()

# Deserialize
deserialized_obj: SFSObject = decode(raw_bytes)
print(deserialized_obj.get("example"))  # 42

Encrypted or Compressed Packets

When creating or decoding messages, you can specify a threshold for compression and a key for encryption:

from sfs2x.protocol import Message, encode, decode, SysAction, ControllerID
from sfs2x.core import SFSObject, UtfString

encryption_key = b"my_secret_16byte"

# Compress if payload > 512 bytes, encrypt with a 16-byte key
msg = Message(controller=ControllerID.EXTENSION, action=18, payload={"secret": UtfString("HideMe")})
packet = encode(msg, compress_threshold=512, encryption_key=encryption_key)

# Decoding
decoded_msg = decode(packet, encryption_key=encryption_key)

Metadata

Release files for sfs2x 0.1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sfs2x 0.1.0.1
File Size Uploaded
sfs2x-0.1.0.1.tar.gz 21.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sfs2x 0.1.0.1
File Interpreter ABI Platform
sfs2x-0.1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 42.3 kB

Release files / sfs2x-0.1.0.1.tar.gz

Download URL sfs2x-0.1.0.1.tar.gz
Size 21.0 kB
Tags Source
SHA-256 checksum
How to use checksums
4b0a66fdc57d5c2e960e85166696ed5afd5078aef3bbbedcfea51102937e12ba
BLAKE2b-256 checksum
How to use checksums
ceb659aa4794598ec30cf36ef35c5c77368c61d4c59c2d15f1553b98d3b78d8f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.1

Release files / sfs2x-0.1.0.1-py3-none-any.whl

Download URL sfs2x-0.1.0.1-py3-none-any.whl
Size 21.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bddcecb9fc0aa7aba1c7c64f4f074c1b21f85c731c65dfb28e9de24e1ddc865e
BLAKE2b-256 checksum
How to use checksums
d17efe54c3a5a26767cff886876f19005ef6f06daebc9b48d1fa8e8f811019ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.1

Release history Release notifications | RSS feed

This release

0.1.0.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page