Skip to main content

evolution-whatsapp

A modern Python client for Evolution API v2 — send and receive WhatsApp messages from Python.

PyPI Python Docs CI License: MIT

evolution-whatsapp is the Python twin of the R package evolution (source). It keeps the same mental model — a preconfigured client, snake_case send_* helpers, jid() — and adds a modern Python stack:

  • httpx with sync and async clients (EvoClient / AsyncEvoClient)
  • pydantic v2 models for webhook events + parse_webhook()
  • structlog structured, timed logging via verbose=True
  • local-file → base64 auto-encoding, automatic retries, typed errors
  • optional FastAPI webhook router and pandas as_dataframe() for pipelines

This package is an independent wrapper for the Evolution API and is not affiliated with WhatsApp or Meta.

Installation

pip install evolution-whatsapp
# with extras:
pip install "evolution-whatsapp[fastapi]"   # webhook_router()
pip install "evolution-whatsapp[pandas]"    # as_dataframe()

The distribution is evolution-whatsapp; the import name is evolution_api (the bare evolution import is already taken on PyPI — see DECISIONS.md).

Quick start

from evolution_api import EvoClient, jid

client = EvoClient(
    base_url="https://YOUR-HOST",
    api_key="...",            # or set the EVO_APIKEY env var
    instance="yourInstance",
    timeout=30,               # or the EVOLUTION_TIMEOUT env var (default 60)
)

# Send a simple message (verbose logs timing + a response preview)
client.send_text("5581999990000", "Hello from Python!", verbose=True)

jid("+55 81 99999-0000")     # -> "5581999990000@s.whatsapp.net"

Async

import asyncio
from evolution_api import AsyncEvoClient

async def main():
    async with AsyncEvoClient(base_url="https://YOUR-HOST", api_key="...", instance="inst") as client:
        await client.send_text("5581999990000", "Hello from async Python!")

asyncio.run(main())

Functions overview

Method Description Key arguments
EvoClient() / AsyncEvoClient() Preconfigured client base_url, api_key, instance, timeout
send_text() Plain text message number, text, delay, verbose
send_status() Status / story (text or media) type, content, caption
send_media() Image / video / document (URL, base64, or file) number, mediatype, mimetype, media, file_name
send_whatsapp_audio() Voice note (PTT) number, audio
send_sticker() Sticker (URL, base64, or file) number, sticker
send_location() Location pin number, latitude, longitude, name
send_contact() One or more contacts (auto wuid) number, contact
send_reaction() Emoji reaction key, reaction
send_buttons() Interactive buttons ⚠️ number, buttons
send_poll() Poll number, name, values
send_list() Interactive list ⚠️ number, sections, button_text
check_is_whatsapp() / check_numbers() Check if numbers are on WhatsApp numbers
connection_state() Channel connection / health check
jid() Build a WhatsApp JID from a phone number number

⚠️ send_buttons() / send_list(): interactive buttons and lists are not supported on the Baileys (WhatsApp Web) connector and may be discontinued — they work only on the Cloud API connector. Both emit a warning and suggest send_poll().

💡 Local files: send_media(), send_sticker() and send_whatsapp_audio() accept local paths (including ~/...), auto-encoded to base64.

Examples

# Media from a URL
client.send_media("5581999990000", "image", "image/png",
                  media="https://www.r-project.org/logo/Rlogo.png",
                  file_name="Rlogo.png", caption="R Logo")

# Media from a local file (auto base64)
client.send_media("5581999990000", "document", "application/pdf",
                  media="~/report.pdf", file_name="report.pdf")

# Poll
client.send_poll("5581999990000", "Favourite language?",
                 ["R", "Python", "Julia"], selectable_count=1)

# Contact (wuid auto-generated)
client.send_contact("5581999990000", {
    "fullName": "Jane Doe", "phoneNumber": "+5581999990000",
    "organization": "Company Ltd.", "email": "jane@example.com",
})

# Check numbers
client.check_is_whatsapp(["5581999990000", "5511988887777"])

Receiving webhooks

from evolution_api.webhooks import parse_webhook

event = parse_webhook(request_json)
if event.event_type == "MESSAGES_UPSERT":
    print(event.data.key.remote_jid, event.data.message)

FastAPI router (extra fastapi):

from fastapi import FastAPI
from evolution_api.webhooks import webhook_router

async def on_event(event):
    if event.event_type == "MESSAGES_UPSERT":
        ...

app = FastAPI()
app.include_router(webhook_router(on_event))

Drain to a DataFrame (extra pandas):

from evolution_api.webhooks import as_dataframe
df = as_dataframe([parse_webhook(p) for p in payloads])

Configuration

Setting Default Description
EVO_APIKEY (env) API key if api_key is not passed
EVO_INSTANCE (env) Instance if instance is not passed
EVOLUTION_TIMEOUT (env) / timeout= 60 HTTP timeout in seconds
verbose=True per-call Structured logging with timing + response preview

Relationship to the R package

This is a faithful port of StrategicProjects/evolution (CRAN). See the Parity with the R package page in the docs and DECISIONS.md for where Python idioms intentionally differ.

License

MIT © 2026 André Leite, Hugo Vasconcelos & Diogo Bezerra. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

evolution_whatsapp-0.1.1.tar.gz (180.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

evolution_whatsapp-0.1.1-py3-none-any.whl (25.8 kB view details)

Uploaded Python 3

File details

Details for the file evolution_whatsapp-0.1.1.tar.gz.

File metadata

  • Download URL: evolution_whatsapp-0.1.1.tar.gz
  • Upload date:
  • Size: 180.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for evolution_whatsapp-0.1.1.tar.gz
Algorithm Hash digest
SHA256 f0935fda3e87e68c37413670ae154aeec4469e9cf772c166da6aaecb7acd6d99
MD5 8eace647c22beb9df1c1394ff34b9a71
BLAKE2b-256 9f2bcfc34de4cdbe4533388d0f35503a444f3901d419a9fa949f7e0729d9d9f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for evolution_whatsapp-0.1.1.tar.gz:

Publisher: release.yml on StrategicProjects/evolution-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file evolution_whatsapp-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for evolution_whatsapp-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3a6dfbf3f060096348ee32b6ded9fa61a37f1bddbbbc0b7e01792caaf1e3d0eb
MD5 3d0a3abd4a7b028e61c77099f8a1c1f8
BLAKE2b-256 e15789e31854a517e4fea9794c20b849a128af0756edb792125ded51d032880c

See more details on using hashes here.

Provenance

The following attestation bundles were made for evolution_whatsapp-0.1.1-py3-none-any.whl:

Publisher: release.yml on StrategicProjects/evolution-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page