Skip to content

kaivyy/waton

Repository files navigation

Waton Banner

Waton

Python 3.11+ License: MIT

Waton is a lightweight, standalone Python library for WhatsApp Web Multi-Device. Build WhatsApp bots, automation tools, and messaging applications entirely in Python — no Node.js required.

Why Waton?

  • Pure Python — Native async/await API, integrates seamlessly with your Python stack
  • Blazing Fast Crypto — Signal Protocol encryption powered by Rust (via PyO3)
  • Lightweight — ~30-60MB memory footprint, minimal dependencies
  • Multi-Device Ready — Full support for WhatsApp's multi-device architecture
  • No Node.js — Standalone implementation, zero JavaScript runtime dependency

Features

  • QR Code & Phone Number Pairing
  • Send & Receive Text Messages
  • Multi-Device Message Routing
  • End-to-End Encryption (Signal Protocol)
  • Persistent Session Storage (SQLite)
  • Async/Await Native API

Installation

pip install waton==0.1.4

Prebuilt wheels include the Rust crypto extension — no Rust toolchain needed for installation.

For development:

pip install -e .[dev]
maturin develop

Windows troubleshooting: os error 32 during editable install

If you get:

  • failed to copy ... waton\\_crypto.pyd
  • The process cannot access the file because it is being used by another process. (os error 32)

then _crypto.pyd is locked by another running Python process (usually examples/cli_chat.py or examples/live_connect.py).

Fix:

# from project root
Get-CimInstance Win32_Process -Filter "name='python.exe'" `
  | Where-Object { $_.CommandLine -match 'examples/cli_chat.py|examples/live_connect.py' } `
  | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }

python -m pip install -e .[dashboard]

If you only want the browser dashboard and do not need reinstall, you can skip editable reinstall and just run:

python -m tools.dashboard.server --host 127.0.0.1 --port 8080

Package Footprint (pip install waton==0.1.4)

Published artifacts are intentionally runtime-only:

  • included: waton/, Rust extension module, metadata files
  • excluded from source distribution: docs/, examples/, tests/, tools/

Quick verification commands:

python -m pip wheel . --no-deps -w .tmp-wheel
python -m maturin sdist --manifest-path Cargo.toml --out .tmp-sdist

How To Use

Waton now provides a simple callback API for fastest onboarding, plus the existing high-level App and low-level WAClient interfaces.

AI Agent Fast Path

If you want automation agents to run Waton with minimum prompt/context overhead:

  • Install latest stable: pip install -U waton
  • Or pin reproducible release: pip install waton==0.1.4
  • Start with simple API: from waton import simple
  • Keep one linked WA session active during tests to avoid conflict 440
  • Use quick docs page: docs/source/content/ai-agent-quickstart.rst

0. Simple Callback API (Drop-in Easiest)

If you want the shortest path from import to running bot:

from waton import simple

client = simple(storage_path="my_session.db")

@client.on_message
async def on_message(msg):
    if msg.text:
        await msg.reply(f"Echo: {msg.text}")

@client.on_ready
async def on_ready(bot):
    print("Waton simple client is connected")

if __name__ == "__main__":
    client.run()

msg provides:

  • msg.id
  • msg.text
  • msg.from_jid
  • msg.sender
  • await msg.reply(text)
  • await msg.react(emoji)

Use this mode when you want minimal boilerplate while keeping the same core runtime.

1. Interactive CLI Chat (Easiest Way to Test)

We provide a built-in interactive terminal chat. If you just want to test sending and receiving messages via your terminal, run:

python examples/cli_chat.py
  • When you run this for the first time, it will print a QR code in the terminal. Scan it with your WhatsApp app (Linked Devices).
  • Once connected, any incoming messages to your number will be printed live in the terminal.
  • To send a message, simply type NOMOR_TUJUAN pesan yang ingin dikirim (e.g., 628123456789 Halo dari terminal!) and press Enter.

1.5 One-Command Live Reliability Check

To validate connect/ping/send-ack/reconnect in one command:

python scripts/live_check.py --auth-db waton_live.db --test-jid 628123456789@s.whatsapp.net --test-text "hello from waton"

If --test-jid is omitted, the check still validates connect/ping/reconnect without send-ack.

1.6 One-Command Release Preflight

Run all release gates (tests, parity scan, and optional lint/typecheck/live):

python scripts/preflight_check.py

Fast local run (skip lint/typecheck):

python scripts/preflight_check.py --skip-lint --skip-typecheck

Strict parity release gate (requires evidence, enforces replay_pass_rate >= 0.995 and drift_count == 0 for status=done domains):

python scripts/preflight_check.py --parity-strict --parity-evidence docs/parity/artifacts/strict-evidence-sample.json --skip-lint --skip-typecheck

CI strict gate (fresh CI-generated evidence + expected commit SHA enforcement):

python scripts/preflight_check.py --parity-strict --parity-evidence docs/parity/artifacts/strict-evidence-ci.json --expected-commit-sha <commit-sha> --skip-lint --skip-typecheck

Note: sample evidence files are for local/dev smoke usage only.

1.7 Parity Evidence Smoke

Run parity scan + replay smoke in one command:

python scripts/parity_evidence_smoke.py

Run hybrid strict parity smoke (includes differential wire/behavior checks + strict evidence gate):

python scripts/parity_evidence_smoke.py --parity-evidence docs/parity/artifacts/strict-evidence-sample.json

This command is intended as a fast parity confidence smoke gate for development/release checks.

1.8 Baileys V7 Compatibility Tracking

Waton tracks Baileys v7/rc11 capability drift without changing default runtime behavior:

python -m tools.parity.scan_baileys_parity --waton waton --baileys ../Baileys/src --out docs/parity/baileys-parity-latest.json
python -m tools.parity.wa_version_tracker --baileys ../Baileys --out docs/parity/wa-version-drift-latest.json

The scanner writes a baileys_v7 section covering LID mapping, tctoken, retry/resend, app-state resilience, offline batching, media robustness, notification coverage, and WA Web version drift. All Baileys v7 power-mode behavior is disabled by default in DEFAULT_CONNECTION_CONFIG; these flags are scaffolding for future parity work, not runtime behavior changes.

1.9 Browser Dashboard for Quick Testing

If you want a browser UI instead of terminal-only testing:

pip install -e .[dashboard]
export WATON_DASHBOARD_API_TOKEN="change-this-token"
python -m tools.dashboard.server --host 127.0.0.1 --port 8080

Open http://127.0.0.1:8080.

  • Security note: dashboard API is now strict-by-default. You must provide WATON_DASHBOARD_API_TOKEN and send Authorization: Bearer <token> for all /api/* calls.
  • Keep dashboard bound to local host (127.0.0.1) unless protected by a trusted reverse proxy/auth layer.
  • Remote API access is blocked by default; only enable with WATON_DASHBOARD_ALLOW_REMOTE=1 when you intentionally expose it.
  • The dashboard is isolated in tools/dashboard/ and does not modify core runtime modules.
  • It uses real WhatsApp connection flow (QR pairing + real send API).
  • Status will show:
    • connected when WA session is open and authenticated
    • connecting while waiting QR/pairing
    • disconnected when socket is not connected
  • In disconnected state, you must connect and scan QR first before sending.
  • UI follows WhatsApp Web style:
    • left panel: chat list (auto-populates from real incoming/outgoing chats)
    • right panel: active chat thread
    • if new message arrives from another number, it appears in left list and can be opened in right thread
    • footer composer is WhatsApp-like (attach/emoji placeholders + autosize text input + send button)
  • Debug endpoint for root-cause tracing:
    • open http://127.0.0.1:8080/api/debug/summary
    • check chat_count, chats, and events_tail to verify whether incoming nodes are reaching dashboard runtime.

2. High-Level API (App)

For building bots or automated tools, use the App class. It manages the connection, storage, and message parsing automatically, providing a simple decorator-based router.

import asyncio
from waton.app.app import App
from waton.app.context import Context

# 1. Initialize App (creates SQLite session DB)
app = App(storage_path="my_session.db")

# 2. Listen for incoming messages
@app.message()
async def on_message(ctx: Context):
    msg = ctx.message
    print(f"Message received from {msg.from_jid}: {msg.text}")
    
    # Auto-reply if there is text
    if msg.text:
        reply_text = f"Hello! You said: {msg.text}"
        await ctx.app.messages.send_text(to_jid=msg.from_jid, text=reply_text)

# 3. Connection ready callback
@app.on_ready
async def on_ready(app_instance: App):
    print("Bot is connected and ready to receive messages!")

# 4. Run the loop
if __name__ == "__main__":
    app.run()

3. Low-Level API (WAClient)

If you want direct control over the WebSocket or need to build custom wrappers, you can use the WAClient directly. See examples/live_connect.py for a full example.

Architecture

┌─────────────────────────────────────────────────┐
│                   Your App                       │
├─────────────────────────────────────────────────┤
│  MessagesAPI  │  ChatsAPI  │  GroupsAPI  │ ...  │
├─────────────────────────────────────────────────┤
│                   WAClient                       │
│         (WebSocket + Noise Protocol)             │
├─────────────────────────────────────────────────┤
│              Signal Protocol (E2EE)              │
│           ┌─────────────────────┐                │
│           │   Rust Crypto Core  │                │
│           │  (Curve25519, AES)  │                │
│           └─────────────────────┘                │
├─────────────────────────────────────────────────┤
│           SQLiteStorage (Sessions)               │
└─────────────────────────────────────────────────┘

Waton vs Baileys

Aspect Waton (Python) Baileys (Node.js)
Runtime Python (~30-50MB) Node.js (~50-100MB)
Package Size ~500KB + deps ~2MB + node_modules
Crypto Engine Rust native (PyO3) JS/WASM
Memory Usage ~30-60MB ~80-150MB
Startup Time Faster Slower (JIT)
Encryption Speed Faster (native) Slower (WASM)
Maturity New Mature
Community Growing Large

Choose Waton when:

  • Building Python-native applications
  • Running on resource-constrained environments (VPS, Raspberry Pi, Docker)
  • Need minimal memory footprint
  • Want native async/await integration with FastAPI, Django, etc.

Choose Baileys when:

  • Already invested in Node.js ecosystem
  • Need battle-tested stability for production
  • Require extensive community support and plugins

Requirements

  • Python 3.11+
  • WhatsApp account (phone number)
  • Internet connection

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

# Setup development environment
git clone https://github.com/kaivyy/waton.git
cd waton
pip install -e .[dev]
maturin develop

# Run tests
pytest tests/

Documentation (Read the Docs)

Sphinx docs source is in docs/source/ with RTD config in .readthedocs.yaml. This release targets docs for Waton v0.1.4.

Local docs build:

pip install -e .[docs]
python -m sphinx -b html docs/source docs/build/html

License

MIT License — feel free to use in personal and commercial projects.

Disclaimer

This project is not affiliated with WhatsApp or Meta. Use responsibly and in accordance with WhatsApp's Terms of Service.

About

Socket-based Python for WhatsApp Web. Waton provides a native async/await API, persistent SQLite sessions, and fast end-to-end encryption powered by a Rust extension via PyO3 no Node.js required.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors