The Problem

Automating WhatsApp interactions from Python requires bridging a high‑performance Go backend (Whatsmeow) with a Python‑friendly API. Existing solutions either expose raw Go bindings, which are cumbersome for Python developers, or provide thin wrappers that lack async support and robust media handling. Teams need a single library that hides the Go complexity while offering a clean, async‑first interface for sending, receiving, and managing messages, groups, and media.

What This Does

neonize/ implements the public Python API. Core client logic lives in neonize/aioze/client.py (132 functions, 5 classes) and neonize/client.py (126 functions, 4 classes). Media utilities such as neonize/utils/ffmpeg.py and neonize/utils/sticker.py wrap external tools for conversion. The Go side (goneonize/) contains the compiled protobuf definitions and a thin wrapper (goneonize/main.go) that builds the Go binary used by the Python extension. Helper scripts in tools/ (e.g., tools/goneonize.py, tools/version.py) automate proto generation and version bumps.

How It Is Wired

Execution starts from the Python examples (e.g., examples/async_basic.py). The script imports neonize.client.NewClient, which instantiates neonize/aioze/client.Client. During initialization the client loads the compiled Go library (built from goneonize/Neonize.proto via goneonize/build_python_proto.py).

Key call chain for sending a message:

  1. handler (examples/async_basic.py:56) → neonize/aioze/client.send_message (called 13 times).
  2. send_message → neonize/aioze/client.get_bytes / free_bytes (both invoked from 51 places, the widest blast radius).
  3. get_bytes reads a file or URL via neonize/utils/iofile.get_bytes_from_name_or_url (network I/O).
  4. The byte payload is passed to the Go layer (neonize/aioze/client.call) which ultimately invokes the Whatsmeow‑backed RPC to deliver the message.

Media paths add a filesystem hop: handler → build_sticker_message → neonize/utils/sticker.convert_to_sticker → external ffmpeg command (neonize/utils/ffmpeg.py).

The most connected modules are neonize/aioze/client (21 outgoing imports, part of a circular dependency) and neonize/client (19 outgoing imports, also in a cycle). These cycles inflate the cognitive load when refactoring because changes ripple through both modules.

File‑level responsibilities (selected):

FilePrimary RoleExternal Effect
neonize/aioze/client.pyAsync client core, request routingCalls external commands, reads/writes files
neonize/utils/ffmpeg.pyMedia conversion wrapperExecutes ffmpeg, writes temporary files
neonize/utils/iofile.pyUnified byte‑source loaderPerforms network fetches
tools/goneonize.pyProto generation & Go build orchestrationRuns protoc, writes compiled Go files
goneonize/main.goGo entry point (binary)Provides low‑level WhatsApp RPCs

Because the import graph shows 4 modules in circular dependencies, any change to shared types (e.g., neonize/types) must consider both sides of the cycle to avoid import errors.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/neonize
cd neonize

# Install Python dependencies (uses the pyproject.toml)
pip install -e .        # editable install pulls in all required packages

# Build the Go protobuf layer (requires Go 1.19+)
cd goneonize
go run build_python_proto.py   # generates the Go bindings used by the Python package

Run an example to verify the stack:

python ../examples/async_basic.py

The example creates a NewClient, registers event callbacks, and calls handler which ultimately invokes send_message as described above.

Real‑World Use

A support desk could embed the library in a Flask service that receives HTTP tickets, creates a NewClient, and forwards the ticket text as a WhatsApp message:

from neonize.client import NewClient

client = NewClient("my_bot")
client.send_message(to_jid="12345@s.whatsapp.net", text=ticket.body)

The call traverses the same async client → byte loader → Go RPC path, guaranteeing that media handling and encryption are performed by the underlying Whatsmeow backend.

Code Health & Issues

  • HIGH – Pin third‑party GitHub Actions to commit SHA (.github/workflows/*).
  • HIGH – No test suite present (109 source files, 0 test files).
  • HIGH – Missing Python lockfile beside pyproject.toml.
  • HIGH – continue-on-error on correctness step in release.yml.
  • MEDIUM – Declare least‑privilege GITHUB_TOKEN permissions (autobump.yml).
  • MEDIUM – Enable Dependabot or Renovate for automated updates.
  • MEDIUM – Add a dependency‑vulnerability scan step in CI.
  • MEDIUM – Set persist-credentials: false on checkout (autobump.yml).
  • LOW – Add timeout-minutes to workflow jobs.
  • LOW – Add repository convention files (.editorconfig, formatter config, etc.).

Additional static findings: oversized files (neonize/aioze/client.py, neonize/client.py, neonize/utils/ffmpeg.py), broad exception handling, deep nesting, an import cycle involving neonize/aioze/client.py and neonize/events.py, and duplicated example code blocks.

The Bottom Line

Neonize delivers a functional Python wrapper around a performant Go WhatsApp core, with clear async APIs and media utilities. However, the codebase suffers from high cognitive load, circular imports, and a lack of automated testing and dependency lockfiles. It is suitable for teams comfortable navigating a mixed Python/Go stack and willing to invest in refactoring and test coverage before production use.