Metadata-Version: 2.4
Name: spluspy
Version: 2.0.2
Summary: A modern async Python library for interacting with Soroush Plus
Project-URL: Homepage, https://github.com/Itskillmaster/spluspy
Project-URL: Documentation, https://github.com/Itskillmaster/spluspy#readme
Project-URL: Repository, https://github.com/Itskillmaster/spluspy
Project-URL: Issues, https://github.com/Itskillmaster/spluspy/issues
Author: Ali Mirshekari
License-Expression: MIT
License-File: LICENSE
Keywords: async,bot,mtproto,soroush,splus,userbot
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Communications :: Chat
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: aiosqlite>=0.19.0
Provides-Extra: all
Requires-Dist: black>=23.0; extra == 'all'
Requires-Dist: cryptg; extra == 'all'
Requires-Dist: mypy>=1.0; extra == 'all'
Requires-Dist: pytest-asyncio>=0.21; extra == 'all'
Requires-Dist: pytest-cov>=4.0; extra == 'all'
Requires-Dist: pytest>=7.0; extra == 'all'
Requires-Dist: ruff>=0.1.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: black>=23.0; extra == 'dev'
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Provides-Extra: speed
Requires-Dist: cryptg; extra == 'speed'
Description-Content-Type: text/markdown

# SplusPy

<p align="center">
  <strong>A modern async Python library for Soroush Plus</strong>
</p>

<p align="center">
  <a href="https://github.com/Itskillmaster/spluspy/blob/main/LICENSE">
    <img src="https://img.shields.io/badge/License-MIT-green" alt="License">
  </a>
  <a href="https://pypi.org/project/spluspy/">
    <img src="https://img.shields.io/pypi/v/spluspy" alt="PyPI">
  </a>
  <a href="https://pypi.org/project/spluspy/">
    <img src="https://img.shields.io/pypi/pyversions/spluspy" alt="Python">
  </a>
</p>

---

## What is SplusPy?

**SplusPy** is a modern, asynchronous Python library for interacting with [Soroush Plus](https://web.splus.ir) — both as a user account and a bot account.

Built from the ground up with clean architecture, it's designed to feel like [Telethon](https://github.com/LonamiWebs/Telethon) or [Pyrogram](https://github.com/pyrogram/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

```bash
pip install spluspy
```

For faster encryption:

```bash
pip install spluspy[speed]
```

## Quick Start

### Simplest Bot

```python
from spluspy import Client

bot = Client("my_session")

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

bot.run()
```

### User Account

```python
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)

```python
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

```python
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

```python
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

```python
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)

```python
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

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

```python
# main.py
from spluspy import Client

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

## Chat Management

```python
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](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**
