mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-23 23:46:41 +00:00
simplex-chat-python: add python library (#6954)
* docs: simplex-chat-python design and implementation plan * bots: Python wire types codegen * simplex-chat-python: package scaffold * simplex-chat-python: native libsimplex loader * simplex-chat-python: async FFI wrappers * simplex-chat-python: ChatApi with 49 api methods * simplex-chat-python: Bot class with decorators and dispatch * simplex-chat-python: install CLI, example bot, README * simplex-chat-python: audit fixes * bots: regenerate API docs and types Catches up the markdown, TypeScript and Python codegen outputs with two upstream schema changes: - APIConnectPlan.connectionLink became optional (from sh/python-lib audit fixes); cmdString and EBNF syntax now reflect optional parameter. - APIAddGroupRelays command and CRGroupRelaysAdded/CRGroupRelaysAddFailed responses added in #6917 (relay management). The TS and markdown outputs were regenerated when #6917 landed but the Python types module only got the new entries with this regeneration. * core: refresh SQLite query plans after relay_inactive_at migration The M20260507_relay_inactive_at migration (#6917 / #6952) shifted the query plans that 'Save query plans' verifies. Regenerated via the test that owns those snapshots; no behavioral change. * bots: keep APIConnectPlan connectionLink as required parameter The prior audit-fixes commit changed the syntax expression to `Optional ...` because the Haskell field is `connectionLink :: Maybe AConnectionLink`. That misrepresents the API contract: the `Maybe` is purely an internal signal for link-parsing failure (the handler returns `CEInvalidConnReq` on `Nothing`), not API-level optionality. Callers MUST always pass a connection link. Revert the syntax expression to `Param "connectionLink"` and add a comment so the intent is preserved next time someone audits. Regenerates COMMANDS.md, commands.ts and _commands.py to match.
This commit is contained in:
38 files changed
+12051
-49
No files matched your search
@@ -0,0 +1,70 @@
|
||||
# SimpleX Chat Python library
|
||||
|
||||
Python 3.11+ client for [SimpleX Chat](https://simplex.chat) bots. Equivalent to the [Node.js library](https://www.npmjs.com/package/simplex-chat).
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
pip install simplex-chat
|
||||
```
|
||||
|
||||
The native `libsimplex` is downloaded lazily on first use. To pre-fetch:
|
||||
|
||||
```bash
|
||||
python -m simplex_chat install # sqlite (default)
|
||||
python -m simplex_chat install --backend postgres # linux-x86_64 only
|
||||
```
|
||||
|
||||
## Quick start
|
||||
|
||||
```python
|
||||
import re
|
||||
from simplex_chat import Bot, BotProfile, Message, SqliteDb, TextMessage
|
||||
|
||||
bot = Bot(
|
||||
profile=BotProfile(display_name="Squaring bot"),
|
||||
db=SqliteDb(file_prefix="./squaring_bot"),
|
||||
welcome="Send me a number, I'll square it.",
|
||||
)
|
||||
|
||||
@bot.on_message(content_type="text", text=re.compile(r"^-?\d+(\.\d+)?$"))
|
||||
async def square(msg: TextMessage) -> None:
|
||||
n = float(msg.text or "0")
|
||||
await msg.reply(f"{n} * {n} = {n * n}")
|
||||
|
||||
@bot.on_message(content_type="text")
|
||||
async def fallback(msg: Message) -> None:
|
||||
await msg.reply("Send me a number, like 7 or 3.14.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
bot.run()
|
||||
```
|
||||
|
||||
`bot.run()` blocks. The connection address is logged on startup — paste it into a SimpleX client to talk to the bot. `Ctrl+C` to stop.
|
||||
|
||||
Three decorators: `@bot.on_message(...)`, `@bot.on_command(name)`, `@bot.on_event(tag)`. Message handlers are first-match-wins in registration order, so register specific filters first and catch-alls last.
|
||||
|
||||
See [`examples/squaring_bot.py`](./examples/squaring_bot.py) for the full example.
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
uv venv && source .venv/bin/activate
|
||||
uv pip install -e '.[dev]'
|
||||
ruff check && pyright && pytest tests/
|
||||
```
|
||||
|
||||
Wire types under `src/simplex_chat/types/_*.py` are generated. Regenerate with `cabal test simplex-chat-test --test-options='--match Python'`.
|
||||
|
||||
## Release
|
||||
|
||||
Manual for now. Bump `_version.py:__version__`, build a wheel, upload to PyPI:
|
||||
|
||||
```bash
|
||||
uv build --wheel
|
||||
uv publish --token "$PYPI_TOKEN"
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[AGPL-3.0](./LICENSE)
|
||||
Reference in new issue
Block a user