Skip to main content
Neonize

Neonize

WhatsApp Automation for Python

Python Go License Release WhatsApp

A Python library for WhatsApp automation. A native Go core built on whatsmeow is compiled into a shared library and exposed to Python through a zero-copy FFI layer.

Getting Started | Features | Examples | Documentation | Contributing


Why Neonize?

Go core performance The WhatsApp multidevice protocol runs in Go, called directly through ctypes. No subprocesses, no HTTP bridges.
Python native Fully typed, idiomatic API. Sync and async clients with identical surfaces.
Persistent sessions SQLite or PostgreSQL. Pair once, reconnect forever.
Enterprise ready Structured error hierarchy, FFmpeg diagnostics, robust FFI with retry logic.

Features

Messaging

  • Send and receive text, images, videos, documents, audio, voice notes, stickers
  • Message replies, reactions, polls, interactive buttons and lists
  • Receipt and presence tracking

Groups and Channels

  • Create, update, and manage groups (name, description, photo, participants)
  • Newsletter/channel operations: fetch messages, update profile, send media

Contacts and Presence

  • Profile picture retrieval, push name updates
  • Typing and recording indicators
  • Contact sync and blocklist management

Architecture

  • Sync (NewClient) and async (NewAClient) with identical APIs
  • Multi-session support via ClientFactory
  • Event-driven with 37+ typed event classes
  • QR code and phone-number pairing

Getting Started

Prerequisites

  • Python 3.10 or newer
  • FFmpeg (required for media operations: stickers, audio, video, thumbnails)

Installation

pip install neonize

Quick Start

from neonize.client import NewClient
from neonize.events import ConnectedEv, MessageEv

client = NewClient("session.db")


@client.event(ConnectedEv)
def on_connected(client: NewClient, _: ConnectedEv) -> None:
    print("Connected")


@client.event(MessageEv)
def on_message(client: NewClient, message: MessageEv) -> None:
    text = message.Message.conversation or message.Message.extendedTextMessage.text
    if text == "ping":
        client.reply_message("pong", message)


client.connect()

Async Quick Start

import asyncio
from neonize.aioze.client import NewAClient
from neonize.aioze.events import ConnectedEv, MessageEv

client = NewAClient("async_session.db")


@client.event(ConnectedEv)
async def on_connected(client: NewAClient, _: ConnectedEv) -> None:
    print("Connected")


@client.event(MessageEv)
async def on_message(client: NewAClient, message: MessageEv) -> None:
    text = message.Message.conversation or message.Message.extendedTextMessage.text
    if text == "ping":
        await client.reply_message("pong", message)


async def main():
    await client.connect()
    await client.idle()


asyncio.run(main())

Examples

Sending Media

from neonize.utils.jid import build_jid

jid = build_jid("1234567890", "s.whatsapp.net")

# Text
client.send_message(jid, "Hello from Neonize")

# Image with caption
with open("photo.jpg", "rb") as f:
    msg = client.build_image_message(f.read(), caption="Photo", mime_type="image/jpeg")
    client.send_message(jid, message=msg)

# Document
with open("report.pdf", "rb") as f:
    msg = client.build_document_message(
        f.read(), filename="report.pdf", mime_type="application/pdf"
    )
    client.send_message(jid, message=msg)

Handling Incoming Messages

from neonize.events import MessageEv, ReceiptEv, PresenceEv
from neonize.utils.message import extract_text


@client.event(MessageEv)
def on_message(client: NewClient, event: MessageEv) -> None:
    text = extract_text(event.Message)
    sender = event.Info.MessageSource.Sender

    if text == "help":
        client.reply_message("Available commands: help, time", event)


@client.event(ReceiptEv)
def on_receipt(client: NewClient, event: ReceiptEv) -> None:
    print(f"Receipt: {event.Receipt.Type} for {event.MessageIDs}")


@client.event(PresenceEv)
def on_presence(client: NewClient, event: PresenceEv) -> None:
    print(f"{event.MessageSource.Sender} is {event.Presence}")

Group Management

from neonize.utils.jid import build_jid

# Create group
participants = [build_jid("1234567890"), build_jid("0987654321")]
info = client.create_group("Project Team", participants)
print(f"Group created: {info.JID}")

# Update settings
client.set_group_name(info.JID, "New Name")
client.set_group_description(info.JID, "Updated description")

# Manage participants
client.update_group_participants(info.JID, [build_jid("5555555555")], "add")

Multi-Session (Async)

import asyncio
from neonize.aioze.client import ClientFactory, NewAClient
from neonize.aioze.events import MessageEv, ConnectedEv

factory = ClientFactory("multisession.db")

# Load existing sessions
for device in factory.get_all_devices():
    factory.new_client(device.JID)

# Pair a new account
factory.new_client(uuid="second-account", new_device=True)


@factory.event(ConnectedEv)
async def on_connected(client: NewAClient, event: ConnectedEv) -> None:
    print("Client connected")


@factory.event(MessageEv)
async def on_message(client: NewAClient, event: MessageEv) -> None:
    if event.Message.conversation == "ping":
        await client.reply_message("pong", event)


async def main():
    await factory.run()
    await factory.idle_all()


asyncio.run(main())

Integration with FastAPI

from contextlib import asynccontextmanager
from fastapi import FastAPI
from neonize.aioze.client import NewAClient
from neonize.aioze.events import MessageEv
from neonize.utils.jid import build_jid

client = NewAClient("fastapi_bot")


@client.event(MessageEv)
async def on_message(client: NewAClient, event: MessageEv) -> None:
    if event.Message.conversation == "/status":
        await client.reply_message("API is running", event)


@asynccontextmanager
async def lifespan(app: FastAPI):
    await client.connect()
    yield
    await client.disconnect()


app = FastAPI(lifespan=lifespan)


@app.get("/send")
async def send(phone: str, message: str):
    await client.send_message(build_jid(phone), message)
    return {"status": "sent"}

Database Configuration

Neonize stores session data in a database. The default is SQLite, which works well for development and single-instance deployments.

# SQLite (default)
client = NewClient("bot", database="./session.db")

# PostgreSQL (recommended for production)
client = NewClient("bot", database="postgres://user:pass@localhost:5432/neonize")

# Connection pooling
client = NewClient(
    "bot", database="postgres://user:pass@localhost/neonize?pool_min_conns=5&pool_max_conns=20"
)

# In-memory (testing only)
client = NewClient("bot", database=":memory:")

Project Structure

neonize/
├── examples/               # Runnable example bots
│   ├── basic.py
│   ├── async_basic.py
│   ├── multisession.py
│   ├── multisession_async.py
│   └── paircode.py
├── goneonize/              # Go shared library (FFI core)
│   ├── main.go
│   ├── defproto/           # Generated protobuf definitions
│   └── utils/              # Go encoder helpers
├── neonize/                # Python package
│   ├── __init__.py
│   ├── client.py           # Sync client (NewClient)
│   ├── aioze/              # Async client (NewAClient)
│   ├── events.py           # Event types and dispatcher
│   ├── exc.py              # Exception hierarchy
│   ├── ext/                # Extensions (interactive messages)
│   ├── proto/              # Python protobuf bindings
│   └── utils/              # Helpers (JID, media, FFmpeg, etc.)
├── docs/                   # Zensical documentation source
├── tools/                  # Build, release, and dev scripts
└── pyproject.toml          # Project metadata and dependencies

Contributing

We welcome contributions. See CONTRIBUTING.md for the branching model, conventional-commit standards, and release process.

# Clone and setup
git clone https://github.com/krypton-byte/neonize.git
cd neonize
uv sync --dev

# Build the Go shared library
CGO_ENABLED=1 uv run task build goneonize

# Run tests
uv run --with pytest python -m pytest

# Lint
uv run ruff check .
uv run ruff format --check .

Workflow: feature branches target dev, merges to master trigger the automated release pipeline.


Documentation

Full documentation is available at neonize.readthedocs.io


Project Description
Thundra High-level bot framework built on Neonize
Tryx Rust-powered Python SDK for WhatsApp automation
Neonize Dart Dart/Flutter wrapper for Neonize
Whatsmeow Go WhatsApp Web API library that powers Neonize

License

This project is licensed under the Apache License 2.0. See LICENSE for details.


Built by krypton-byte and contributors

Metadata

Release files for neonize 0.5.2

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

Built distributions (wheels)

Table of built distributions (wheels) for neonize 0.5.2
File
neonize-0.5.2-py310-none-win_arm64.whl Python 3.10 none Windows ARM64 Details
neonize-0.5.2-py310-none-win_amd64.whl Python 3.10 none Windows x86-64 Details
neonize-0.5.2-py310-none-win32.whl Python 3.10 none Windows x86-32 Details
neonize-0.5.2-py310-none-manylinux2014_x86_64.whl Python 3.10 none Linux glibc 2.17+ x86-64 Details
neonize-0.5.2-py310-none-manylinux2014_s390x.whl Python 3.10 none Linux glibc 2.17+ IBM System/390x Details
neonize-0.5.2-py310-none-manylinux2014_i686.whl Python 3.10 none Linux glibc 2.17+ x86-32 Details
neonize-0.5.2-py310-none-manylinux2014_aarch64.whl Python 3.10 none Linux glibc 2.17+ ARM64 Details
neonize-0.5.2-py310-none-macosx_12_0_x86_64.whl Python 3.10 none macOS 12.0+ x86-64 Details
neonize-0.5.2-py310-none-macosx_12_0_arm64.whl Python 3.10 none macOS 12.0+ ARM64 Details

Total release size: 64.3 MB

Release files / neonize-0.5.2-py310-none-win_arm64.whl

Download URL neonize-0.5.2-py310-none-win_arm64.whl
Size 6.4 MB
Tags Python 3.10 Windows ARM64
SHA-256 checksum
How to use checksums
9baeac04b085aa8e47a2c866fad9908a185097246a49ddac288d2825b2d08d2e
BLAKE2b-256 checksum
How to use checksums
0488a643ca2cbc18100d5b5495d57b8b7a3b584a8ce52cb3f15317380ca26569
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / neonize-0.5.2-py310-none-win_amd64.whl

Download URL neonize-0.5.2-py310-none-win_amd64.whl
Size 7.0 MB
Tags Python 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
08fa22aac7b8b6b66f2f53195cb12fa990685c89bd99a0ff17f346a0b4f4710a
BLAKE2b-256 checksum
How to use checksums
1fd66d63715700c0cb5ea4525c8328ae58700bfa7723f8b57212301fae5835a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / neonize-0.5.2-py310-none-win32.whl

Download URL neonize-0.5.2-py310-none-win32.whl
Size 7.0 MB
Tags Python 3.10 Windows x86-32
SHA-256 checksum
How to use checksums
a4630048fe0e13a8d460bf128e46ae10845a4ae8ce4fafa2a0bf5669db696a87
BLAKE2b-256 checksum
How to use checksums
8c7602fe7ce9b734b1fe015d0973c3c0153d0555fe86b3fcd46020eb6e56ccc8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / neonize-0.5.2-py310-none-manylinux2014_x86_64.whl

Download URL neonize-0.5.2-py310-none-manylinux2014_x86_64.whl
Size 7.1 MB
Tags Linux glibc 2.17+ x86-64 Python 3.10
SHA-256 checksum
How to use checksums
d737efc03d3a4db0a89d1efac3b55199472eb57acda041927ca8efc797872b69
BLAKE2b-256 checksum
How to use checksums
9d215230e201176c1d405bb291dda66bb31efe85f78ac02ef60bc2a6f634990b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / neonize-0.5.2-py310-none-manylinux2014_s390x.whl

Download URL neonize-0.5.2-py310-none-manylinux2014_s390x.whl
Size 7.1 MB
Tags Linux glibc 2.17+ IBM System/390x Python 3.10
SHA-256 checksum
How to use checksums
bc0874e3abaab520433b9456b020c973885353af1caa2a73c0c71e866973e3ce
BLAKE2b-256 checksum
How to use checksums
50c0db72411b2fb31cc4db7393287696ae38e3c1f4a076140a13ff09b453750a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / neonize-0.5.2-py310-none-manylinux2014_i686.whl

Download URL neonize-0.5.2-py310-none-manylinux2014_i686.whl
Size 9.7 MB
Tags Linux glibc 2.17+ x86-32 Python 3.10
SHA-256 checksum
How to use checksums
96ea2eb144064a5ae7667709021f4b9515e1206f163c267349ecbc531369ecdc
BLAKE2b-256 checksum
How to use checksums
b98d1924d19e45ec54528fd5d7223e8319cecf944d50cd8e617ba711af31a543
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / neonize-0.5.2-py310-none-manylinux2014_aarch64.whl

Download URL neonize-0.5.2-py310-none-manylinux2014_aarch64.whl
Size 6.6 MB
Tags Linux glibc 2.17+ ARM64 Python 3.10
SHA-256 checksum
How to use checksums
258fc41a72b60854255815c697ea24db14d96d6205d10e9524db3318615e3ca3
BLAKE2b-256 checksum
How to use checksums
ec54be02d1f3eabdb8f7659f16d0ac7c28b75f78bd36fdf151117b33dd49dd7e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / neonize-0.5.2-py310-none-macosx_12_0_x86_64.whl

Download URL neonize-0.5.2-py310-none-macosx_12_0_x86_64.whl
Size 6.8 MB
Tags Python 3.10 macOS 12.0+ x86-64
SHA-256 checksum
How to use checksums
7065552a7d4acfb7327f845ba176f887125a20578d5bfafb683ecb870d12c41b
BLAKE2b-256 checksum
How to use checksums
74fbee1011d67def59535feb15b92d21a66f113af3a6c77a51567ef2390c7f74
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / neonize-0.5.2-py310-none-macosx_12_0_arm64.whl

Download URL neonize-0.5.2-py310-none-macosx_12_0_arm64.whl
Size 6.4 MB
Tags Python 3.10 macOS 12.0+ ARM64
SHA-256 checksum
How to use checksums
670376f5479c56da35fce80ba3c0f98540a46d77364b04f4a6405f6dda783617
BLAKE2b-256 checksum
How to use checksums
93a5316bdcd25baf2300c34ab88efb13def89ba4f0b828d965f5df74fdbb57af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.5.2 This release

9 release files

0.3.10

9 release files

0.3.9

11 release files

0.3.8

11 release files

0.3.6

4 release files

0.3.5

9 release files

0.3.4

11 release files

0.3.3

11 release files

0.3.2

11 release files

0.3.1

11 release files

0.3.0

5 release files

0.2.1

11 release files

0.1.13

8 release files

0.1.12

8 release files

0.1.11

7 release files

0.1.10

3 release files

0.1.8

6 release files

0.1.7

5 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.2

4 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

8 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