Martix - Simplified Matrix Library for Python
Martix is a high-level Python library that simplifies working with the Matrix protocol. It provides an intuitive, telegram-bot-like API for creating Matrix bots and clients.
Features
- Simple API: Easy-to-use decorators and methods inspired by python-telegram-bot
- Event Handling: Comprehensive event system for messages, commands, invites, and more
- File Support: Built-in support for sending and receiving files, images, audio, and documents
- Persistent State: Automatic sync token management to resume from last position
- Type Safety: Full type hints and dataclass-based objects
- Async/Await: Built on asyncio for high performance
- Error Handling: Comprehensive exception system
Installation
pip install martix
Or install from source:
git clone https://github.com/daradege/martix.git
cd martix
pip install -e .
Quick Start
import martix
# Initialize client
user = "@mybot:example.com"
password = "my_password"
host = "https://matrix.example.com"
client = martix.Client(user, password, host)
client.command_prefix = "!" # Default is "/"
@client.on_ready()
async def ready():
print(f"Logged in as {client.user.username}")
@client.on_message()
async def on_message(message: martix.Message):
print(f"Message from {message.user.display_name}: {message.text}")
# Handle different message types
if message.photo:
await message.reply("Nice photo!")
elif message.document:
content = await message.document.download(client.client)
await message.reply(f"Downloaded {len(content)} bytes")
@client.on_command("start")
async def start_command(command: martix.Command):
await command.reply(f"Hello {command.user.display_name}!")
@client.on_command("echo")
async def echo_command(command: martix.Command):
if command.args:
await command.reply(f"You said: {command.args_string}")
# Start the bot
client.run()
Message Types
Martix supports all Matrix message types:
@client.on_message()
async def handle_message(message: martix.Message):
# Text messages
print(message.text)
# Images
if message.photo:
await message.photo.download(client.client, "image.jpg")
# Documents
if message.document:
content = await message.document.download(client.client)
# Audio files
if message.audio:
print(f"Audio duration: {message.audio.duration}ms")
# Message metadata
print(f"From: {message.user.display_name}")
print(f"Room: {message.room.name}")
print(f"Time: {message.time}")
Sending Messages
# Send text message
await client.send_message(room_id, "Hello World!")
# Send with reply
await message.reply("This is a reply")
# Send files
await client.send_file(room_id, "document.pdf")
await client.send_image(room_id, "photo.jpg", "Caption here")
# React to messages
await message.react("👍")
Room Management
# Join/leave rooms
await client.join_room("!room:example.com")
await client.leave_room("!room:example.com")
# Get room list
rooms = await client.get_rooms()
for room in rooms:
print(f"Room: {room.name} ({room.member_count} members)")
# Handle invites
@client.on_invite()
async def on_invite(room, event):
await client.join_room(room.room_id)
await client.send_message(room.room_id, "Thanks for inviting me!")
Event Handlers
Martix supports various event types:
@client.on_ready()
async def ready():
"""Called when bot is ready"""
pass
@client.on_message()
async def on_message(message: martix.Message):
"""Handle all messages"""
pass
@client.on_command("commandname")
async def command_handler(command: martix.Command):
"""Handle specific commands"""
pass
@client.on_invite()
async def on_invite(room, event):
"""Handle room invitations"""
pass
@client.on_member_join()
async def on_member_join(room, event):
"""Handle member joins"""
pass
@client.on_member_leave()
async def on_member_leave(room, event):
"""Handle member leaves"""
pass
Configuration
client = martix.Client(
user_id="@bot:example.com",
password="password",
homeserver="https://matrix.example.com",
device_name="My Bot" # Optional
)
# Set command prefix
client.command_prefix = "!" # Default is "/"
Error Handling
from martix import MartixError, AuthenticationError, NetworkError
try:
await client.start()
except AuthenticationError:
print("Login failed - check credentials")
except NetworkError:
print("Connection failed - check homeserver URL")
except MartixError as e:
print(f"Martix error: {e}")
Advanced Usage
File Downloads
@client.on_message()
async def handle_files(message: martix.Message):
if message.document:
# Download to memory
content = await message.document.download(client.client)
# Download to file
await message.document.download(client.client, "downloaded_file.pdf")
# Access file metadata
print(f"Filename: {message.document.filename}")
print(f"Size: {message.document.size} bytes")
print(f"MIME type: {message.document.mimetype}")
Custom Event Handling
# Multiple handlers for the same event
@client.on_message()
async def log_message(message: martix.Message):
print(f"Logged: {message.text}")
@client.on_message()
async def process_message(message: martix.Message):
# Process the message
pass
# Multiple command handlers
@client.on_command("help")
async def help_command(command: martix.Command):
await command.reply("Help text here")
@client.on_command("help")
async def log_help_usage(command: martix.Command):
print(f"Help command used by {command.user.username}")
Examples
Check the examples/ directory for complete bot examples:
basic_bot.py- Simple message and command handlingfile_bot.py- File upload/download handling
Requirements
- Python 3.8+
- matrix-nio
- aiofiles
- Pillow (for image handling)
License
MIT License - see LICENSE file for details.
Contributing
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.
Support
- GitHub Issues: https://github.com/daradege/martix/issues
Metadata
Release files for martix 1.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| martix-1.2.2.tar.gz | 13.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| martix-1.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.4 kB
Release files / martix-1.2.2.tar.gz
| Download URL | martix-1.2.2.tar.gz |
|---|---|
| Size | 13.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
22d9dfd508d01636e4ea23a88a8b1fc9bbffe8b1357aba8640aecf5172dc193b
|
|
BLAKE2b-256 checksum How to use checksums |
8fb357025e6ed8f86c567d5208814c06de891868daec825371534140258c9f6e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / martix-1.2.2-py3-none-any.whl
| Download URL | martix-1.2.2-py3-none-any.whl |
|---|---|
| Size | 14.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9624dd8c854a432007a7787845479735913faf0fdb4491dba1c5306bfe4bdfb6
|
|
BLAKE2b-256 checksum How to use checksums |
4dde65ab27e73d8306a4e49cf27068b567277ec167eeaa061d1f24ce2533245f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Security for martix 1.2.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.