Skip to main content

A modern async Python library for interacting with Soroush Plus

Project description

SplusPy

A modern async Python library for Soroush Plus

License PyPI Python


What is SplusPy?

SplusPy is a modern, asynchronous Python library for interacting with Soroush Plus — both as a user account and a bot account.

Built from the ground up with clean architecture, it's designed to feel like Telethon or Pyrogram, but specifically for the Soroush Plus ecosystem.

Features

  • No API Key Required — Built-in Soroush Plus credentials
  • Fully Asynchronous — Built with Python's asyncio
  • Sync Support — Use without async/await via spluspy.sync
  • Bot & User Support — Both account types
  • Event-Driven Handlers — Powerful event system with decorators
  • Filter System — Composable filters (&, |, ~)
  • Inline & Reply Buttons — Interactive keyboards
  • Conversation API — For interactive bot flows
  • FSM (Finite State Machine) — Built-in state management for bots
  • Plugin System — Dynamic plugin loading
  • Middleware — Pre/post processing of updates
  • Scheduler — Built-in task scheduler
  • Multiple Storage Backends — Memory, SQLite
  • Professional Logging — Structured, namespaced loggers
  • Type Hints Everywhere — Full type safety
  • Clean Architecture — SOLID principles, modular design

Installation

pip install spluspy

For faster encryption:

pip install spluspy[speed]

Quick Start

Simplest Bot

from spluspy import Client

bot = Client("my_session")

@bot.on_message()
async def handler(m):
    await m.reply("Hello!")

bot.run()

User Account

from spluspy import Client

client = Client("session_name")

@client.on_message()
async def handler(m):
    await m.reply("Hey there!")

async def main():
    await client.start(phone="+98XXXXXXXXXX")
    await client.run_until_disconnected()

import asyncio
asyncio.run(main())

Sync Usage (No Async/Await)

from spluspy.sync import Client

bot = Client("session")

@bot.on_message()
def handler(m):
    m.reply("Hello!")

bot.run()

Events

Decorator Event
@bot.on_message() New message
@bot.on_edited() Message edited
@bot.on_callback_query() Inline button clicked
@bot.on_inline_query() Inline query
@bot.on_chat_action() Join/leave/pin
@bot.on_user_update() Status change
@bot.on_message_deleted() Message deleted
@bot.on_message_read() Read receipt

Filters

from spluspy import filters

@bot.on_message(filters.text)           # Text only
@bot.on_message(filters.private)        # Private chats
@bot.on_message(filters.group)          # Groups
@bot.on_message(filters.command("start"))  # /start command
@bot.on_message(filters.regex(r"\d+"))  # Regex match
@bot.on_message(filters.user(123))      # Specific user
@bot.on_message(filters.text & filters.private)  # Combined
@bot.on_message(filters.photo | filters.video)   # Photo OR video

Message Methods

await m.reply("Hello")              # Reply
await m.edit("New text")            # Edit
await m.delete()                    # Delete
await m.forward(chat_id)            # Forward
await m.copy(chat_id)               # Copy (no forward header)
await m.pin()                       # Pin
await m.react("❤️")                 # React
await m.mark_read()                 # Mark as read
await m.download()                  # Download media
await m.reply_photo("photo.jpg")    # Reply with photo
await m.reply_video("video.mp4")    # Reply with video
await m.reply_document("file.pdf")  # Reply with document

Buttons

from spluspy import Button

# Inline keyboard
keyboard = Button.build_inline(
    [Button.inline("Option 1", b"opt1"), Button.inline("Option 2", b"opt2")]
)
await bot.send_message(chat_id, "Choose:", buttons=keyboard)

# Reply keyboard
kb = Button.build_reply(
    [Button.text("Menu"), Button.text("Settings")]
)
await bot.send_message(chat_id, "Pick:", buttons=kb)

# Clear keyboard
await bot.send_message(chat_id, "Done", buttons=Button.clear())

FSM (State Machine)

from spluspy.fsm import State, StateMachine
from spluspy.storage import MemoryStorage

storage = MemoryStorage()
fsm = StateMachine(storage)

class Form:
    name = State()
    age = State()

@bot.on_message(filters.command("register"))
async def start_register(m):
    ctx = fsm.context(m.sender_id)
    await ctx.set_state(Form.name)
    await m.reply("What is your name?")

@bot.on_message(filters.private)
async def process_form(m):
    ctx = fsm.context(m.sender_id)
    state = await ctx.get_state()

    if state == Form.name:
        await ctx.set_data(name=m.text)
        await ctx.set_state(Form.age)
        await m.reply("How old are you?")
    elif state == Form.age:
        await ctx.set_data(age=m.text)
        await ctx.reset()
        await m.reply(f"Registered! Name: {(await ctx.get_data()).get('name')}")

Plugin System

# plugins/hello.py
def register(client):
    @client.on_message(filters.command("hello"))
    async def hello_handler(m):
        await m.reply("Hello from plugin!")
# main.py
from spluspy import Client

bot = Client("session")
bot.plugins.load("plugins")
bot.run()

Chat Management

await bot.ban_user(chat_id, user_id)
await bot.unban_user(chat_id, user_id)
await bot.mute_user(chat_id, user_id)
await bot.unmute_user(chat_id, user_id)
await bot.pin_message(chat_id, message)
await bot.unpin_message(chat_id, message)
await bot.join_chat(chat_id)
await bot.leave_chat(chat_id)

Project Structure

spluspy/
├── __init__.py          # Public API
├── __version__.py       # Version info
├── client/              # Client and conversation API
├── types/               # Domain models (Message, User, Chat, Media, etc.)
├── events/              # Event types and builders
├── filters/             # Composable message filters
├── errors/              # Custom exception hierarchy
├── session/             # Session backends (SQLite, Memory, String)
├── network/             # TCP connections and connection pool
├── storage/             # Key-value storage backends
├── plugins/             # Plugin loader
├── middleware/          # Middleware system
├── fsm/                 # Finite state machine
├── scheduler/           # Task scheduler
├── utils/               # Logger, cache, helpers
└── sync/                # Synchronous client wrapper

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests: pytest
  5. Submit a pull request

License

MIT License — see LICENSE for details.

Disclaimer

SPlusPy is an unofficial third-party library. Use it responsibly and ensure your applications comply with Soroush Plus's Terms of Service.


Made with ❤️ for the Soroush Plus community

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

spluspy-2.0.2.tar.gz (70.7 kB view details)

Uploaded Source

Built Distribution

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

spluspy-2.0.2-py3-none-any.whl (74.5 kB view details)

Uploaded Python 3

File details

Details for the file spluspy-2.0.2.tar.gz.

File metadata

  • Download URL: spluspy-2.0.2.tar.gz
  • Upload date:
  • Size: 70.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for spluspy-2.0.2.tar.gz
Algorithm Hash digest
SHA256 0dd183244279142b3db08156c4bdb306b81458a4a00c1250aebbab031fabcf03
MD5 93928572f1b1282bc42d093d66523cf5
BLAKE2b-256 6c2b505bb709714b9c6ca2ef942d7ea6f71556e2277b6d4668b5a49806c84bdd

See more details on using hashes here.

File details

Details for the file spluspy-2.0.2-py3-none-any.whl.

File metadata

  • Download URL: spluspy-2.0.2-py3-none-any.whl
  • Upload date:
  • Size: 74.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for spluspy-2.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a37bca3b7c5263500050b77db6329a87ee9b22f0c972f4042a6583a1fc421584
MD5 9f2e3fdd71f00370ffcd18584efac8d2
BLAKE2b-256 d71360b173713d51aef41beb4bb3c79ed7393bb70fd1514036ea055a730f22b3

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