Skip to content

Commit 7097136

Browse files
committed
Merge branch 'v3'
# Conflicts: # README.md
2 parents 63cba4a + 55894b8 commit 7097136

File tree

158 files changed

+21454
-6485
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

158 files changed

+21454
-6485
lines changed

β€Ž.github/workflows/tests.ymlβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
pip install -r requirements-dev.txt
2727
2828
- name: Run tests
29+
# run: pytest
2930
run: pytest --cov --cov-report=xml
3031

3132
- name: Upload results to Codecov

β€ŽCHANGELOG.mdβ€Ž

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,55 @@
33

44
> NOTE: pywa follows the [semver](https://semver.org/) versioning standard.
55
6+
#### 3.0.0-rc.3 (2025-08-06)
7+
8+
- [templates] `params` is now can be called on class level
9+
- [templates] adding support for `library_input` when creating library templates
10+
- [templates] adding support for `degrees_of_freedom_spec` when creating template
11+
- [listeners] handling old `to` parameter in `listen` and update migration guide
12+
13+
#### 3.0.0-rc.2 (2025-08-04)
14+
15+
- [client] allowing to use mm-lite-api when sending a template
16+
- [templates] allowing to set app-depplinks in `URLButton`'s
17+
- [templates] adding `TopBlockReasonType` enum
18+
- [client] adding `get_business_account` method
19+
- [client] adding `deregister_phone_number` method
20+
- [client] allowing to get and set `StorageConfiguration`
21+
- [callback] adding `is_quick_reply` to `CallbackButton`
22+
- [callback] validate not `kw_only` in dataclasses
23+
- [client] fix creating `LibraryTemplate`
24+
- [system] support old `customer_changed_number` sys type
25+
- [docs] new logo for pywa!
26+
27+
28+
#### 3.0.0-rc.1 (2025-07-31)
29+
30+
- [templates] refactored and improved templates support
31+
- [calls] added full support for calls
32+
- [user_preferences] added full support for user preferences
33+
- [server] continued handling if listener is not using the update
34+
- [system] moved `system` messages to `PhoneNumberChange` and `IdentityChange` updates
35+
- [client] forced keyword-only for context args in `send_message`, `send_image`, and other `send_...` methods
36+
- [types] returned `SuccessResult` instead of `bool` to allow future extension with other attributes
37+
- [client] `upload_media` returns `Media` object
38+
- [client] added `get_business_phone_number_settings` and `update_business_phone_number_settings` to get and update calling settings
39+
- [client] added `update_display_name` method to update the WhatsApp display name
40+
- [security] fixed XSS vulnerability
41+
- [api] suggest to provide custom `httpx.Client` on `httpx.RequestError`
42+
- [handlers] added `on_completion` decorator to flow request callback wrapper
43+
- [errors] show more descriptive error messages
44+
- [base_update] added `waba_id` for all user updates
45+
- [message] added `referral` field
46+
- [types] support `is_on_biz_app` in `BusinessPhoneNumber`
47+
- [client] added `delete_media` method
48+
- [listeners] check if `server` exists before starting to listen
49+
- [utils] handled enum values case-sensitively
50+
- [utils] returned `FlowRequestDecryptedMedia` instead of `(media_id, filename, data)` tuple
51+
- [utils] new `APIObject` to get fields from datacls
52+
- [deprecations] removed attrs and types marked as deprecated
53+
54+
655
### 2.11.0 (2025-06-17) **Latest**
756

857
- [flows] adding support for `ImageCarousel`

β€ŽCONTRIBUTING.mdβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ pywa/
120120
β”‚Β Β  β”œβ”€β”€ message_status.py
121121
β”‚Β Β  β”œβ”€β”€ others.py
122122
β”‚Β Β  β”œβ”€β”€ sent_message.py
123-
β”‚Β Β  └── template.py
123+
β”‚Β Β  └── templates.py
124124
└── utils.py
125125
```
126126

β€ŽMIGRATION.mdβ€Ž

Lines changed: 341 additions & 0 deletions
Large diffs are not rendered by default.

β€ŽREADME.mdβ€Ž

Lines changed: 70 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
<p align="center">
1818
<a href="https://pypi.org/project/pywa/"><img src="https://img.shields.io/pypi/v/pywa.svg" /></a>
19-
<a href="https://pypi.org/project/pywa/"><img src="https://img.shields.io/pypi/dm/pywa" /></a>
19+
<a href="https://pypi.org/project/pywa/"><img src="https://static.pepy.tech/badge/pywa" /></a>
2020
<a href="https://github.com/david-lev/pywa/actions/workflows/tests.yml"><img src="https://img.shields.io/github/actions/workflow/status/david-lev/pywa/tests.yml?label=Tests" /></a>
2121
<a href="https://codecov.io/gh/david-lev/pywa"><img src="https://img.shields.io/codecov/c/github/david-lev/pywa" /></a>
2222
<a href="https://pywa.readthedocs.io"><img src="https://readthedocs.org/projects/pywa/badge/?version=latest&" /></a>
@@ -25,26 +25,6 @@
2525
<a href="https://t.me/py_wa"><img src="https://badges.aleen42.com/src/telegram.svg" /></a>
2626
</p>
2727

28-
> ⚠️ **Pywa v3 Release Candidate Available!**
29-
> Pywa `v3.0.0` is now available for testing!
30-
>
31-
> πŸš€ **What’s New in v3:**
32-
33-
> β€’ Complete **template system redesign** – easier structure, validation, and sending
34-
> β€’ Full support for **calls** (incoming and outgoing)
35-
> β€’ Improved **security**, **typing**, and **input validation**
36-
37-
> πŸ“š [v3 Documentation Β»](https://pywa.readthedocs.io/en/v3/)
38-
> 🧭 [Migration Guide (2.x β†’ 3.x) Β»](https://github.com/david-lev/pywa/blob/v3/MIGRATION.md)
39-
> πŸ“ [Full Changelog Β»](https://github.com/david-lev/pywa/blob/v3/CHANGELOG.md)
40-
>
41-
> πŸ“¦ **Install for testing:**
42-
> ```bash
43-
> pip install pywa==3.0.0-rc.3
44-
> ```
45-
>
46-
> πŸ’¬ Feedback and issue reports are encouraged to help us prepare for the stable release.
47-
4828
---
4929

5030
**πŸ’« PyWa is an all-in-one Python framework for the WhatsApp Cloud API.**
@@ -58,30 +38,29 @@ Fully **typed**, **documented**, and **production-ready** β€” build powerful bot
5838
--------------------------------
5939

6040
> [Get Started](https://pywa.readthedocs.io/en/latest/content/getting-started.html)
61-
β€’ [WhatsApp Client](https://pywa.readthedocs.io/en/latest/content/client/overview.html)
41+
β€’ [Client](https://pywa.readthedocs.io/en/latest/content/client/overview.html)
6242
β€’ [Handlers](https://pywa.readthedocs.io/en/latest/content/handlers/overview.html)
6343
β€’ [Listeners](https://pywa.readthedocs.io/en/latest/content/listeners/overview.html)
64-
β€’ [Filters](https://pywa.readthedocs.io/en/latest/content/filters/overview.html)
6544
β€’ [Updates](https://pywa.readthedocs.io/en/latest/content/updates/overview.html)
66-
β€’ [Templates](https://pywa.readthedocs.io/en/v3/content/templates/overview.html)
45+
β€’ [Filters](https://pywa.readthedocs.io/en/latest/content/filters/overview.html)
46+
β€’ [Templates](https://pywa.readthedocs.io/en/latest/content/templates/overview.html)
6747
β€’ [Flows](https://pywa.readthedocs.io/en/latest/content/flows/overview.html)
68-
β€’ [Calls](https://pywa.readthedocs.io/en/v3/content/calls/overview.html)
69-
β€’ [Examples](https://pywa.readthedocs.io/en/latest/content/examples/overview.html)
70-
48+
β€’ [Calls](https://pywa.readthedocs.io/en/latest/content/calls/overview.html)
7149

7250
------------------------
7351

7452
⚑ **Why PyWa?**
7553
---------------
76-
- **πŸš€ Fast and Simple**: Focus on building your bot without worrying about low-level details.
77-
- **πŸ’¬ Rich Messaging**: Send text, images, videos, documents, audio, locations, contacts, and interactive keyboards.
78-
- **πŸ“© Real-Time Updates**: Receive messages, callbacks, and message status updates effortlessly.
79-
- **πŸ”” Listeners**: Use powerful listeners to wait for specific user events.
80-
- **♻️ Flows Support**: Create, send, and listen to Flows seamlessly.
81-
- **πŸ”„ Webhook Integration**: Built-in support for popular frameworks like Flask and FastAPI.
82-
- **πŸ”¬ Advanced Filters**: Handle incoming updates with powerful filtering options.
83-
- **πŸ“„ Template Messaging**: Easily create and send template messages.
84-
- **βœ… Production-Ready**: Fully typed, documented, and rigorously tested for reliability.
54+
- **πŸš€ Fast & Simple** – Focus on building, not boilerplate.
55+
- **πŸ’¬ Rich Messaging** – Text, images, files, audio, locations, contacts, buttons & more.
56+
- **πŸ“© Real-Time Updates** – Messages, callbacks, delivery/read receipts, account updates, and more.
57+
- **πŸ”” Listeners** – Wait for user replies, clicks, or reactions with ease.
58+
- **πŸ“„ Templates** – Create and send powerful WhatsApp templates.
59+
- **♻️ Flows** – Build interactive WhatsApp flows effortlessly.
60+
- **πŸ“ž Calls Support** – Receive and handle call events.
61+
- **πŸ”„ Webhook-Ready** – Native support for Flask, FastAPI, and more.
62+
- **πŸ”¬ Filters** – Advanced filtering for incoming updates.
63+
- **βœ… Production-Ready** – Typed, documented, and fully tested.
8564

8665
------------------------
8766

@@ -165,7 +144,7 @@ def click_me(client: WhatsApp, clb: types.CallbackButton):
165144
- To run the server, use [fastapi-cli](https://fastapi.tiangolo.com/#run-it) (`pip install "fastapi[standard]"`):
166145

167146
```bash
168-
fastapi dev wa.py # see uvicorn docs for more options (port, host, reload, etc.)
147+
fastapi dev wa.py # see uvicorn docs for more options (port, host, etc.)
169148
```
170149

171150
- **Async Usage**
@@ -186,7 +165,55 @@ async def main():
186165
@wa.on_message
187166
async def hello(_: WhatsApp, msg: types.Message): # async callback
188167
await msg.react("πŸ‘‹")
189-
await msg.reply(...)
168+
await msg.reply("Hello from PyWa Async!")
169+
```
170+
171+
- **Create and send template messages**
172+
> See [Templates](https://pywa.readthedocs.io/en/latest/content/templates/overview.html) for more details and examples.
173+
174+
```python
175+
from pywa import WhatsApp
176+
from pywa.types.templates import *
177+
178+
wa = WhatsApp(..., business_account_id=123456)
179+
180+
# Create a template
181+
wa.create_template(
182+
template=Template(
183+
name="buy_new_iphone_x",
184+
category=TemplateCategory.MARKETING,
185+
language=TemplateLanguage.ENGLISH_US,
186+
parameter_format=ParamFormat.NAMED,
187+
components=[
188+
ht := HeaderText("The New iPhone {{iphone_num}} is here!", iphone_num=15),
189+
bt := BodyText("Buy now and use the code {{code}} to get {{per}}% off!", code="WA_IPHONE_15", per=15),
190+
FooterText(text="Powered by PyWa"),
191+
Buttons(
192+
buttons=[
193+
url := URLButton(text="Buy Now", url="https://example.com/shop/{{1}}", example="iphone15"),
194+
PhoneNumberButton(text="Call Us", phone_number="1234567890"),
195+
qrb1 := QuickReplyButton(text="Unsubscribe from marketing messages"),
196+
qrb2 := QuickReplyButton(text="Unsubscribe from all messages"),
197+
]
198+
),
199+
200+
]
201+
),
202+
)
203+
204+
# Send the template message
205+
wa.send_template(
206+
to="9876543210",
207+
name="buy_new_iphone_x",
208+
language=TemplateLanguage.ENGLISH_US,
209+
params=[
210+
ht.params(iphone_num=30),
211+
bt.params(code="WA_IPHONE_30", per=30),
212+
url.params(url_variable="iphone30", index=0),
213+
qrb1.params(callback_data="unsubscribe_from_marketing_messages", index=1),
214+
qrb2.params(callback_data="unsubscribe_from_all_messages", index=2),
215+
]
216+
)
190217
```
191218

192219
- **Create and send flows**
@@ -263,53 +290,6 @@ def handle_flow_response(_: WhatsApp, flow: types.FlowCompletion):
263290
)
264291
```
265292

266-
- **Create and send template messages**
267-
268-
```python
269-
from pywa import WhatsApp, types
270-
271-
# Create a WhatsApp client
272-
wa = WhatsApp(..., business_account_id=123456)
273-
274-
# Create a template
275-
created = wa.create_template(
276-
template=types.NewTemplate(
277-
name="buy_new_iphone_x",
278-
category=types.NewTemplate.Category.MARKETING,
279-
language=types.NewTemplate.Language.ENGLISH_US,
280-
header=types.NewTemplate.Text(text="The New iPhone {15} is here!"),
281-
body=types.NewTemplate.Body(text="Buy now and use the code {WA_IPHONE_15} to get {15%} off!"),
282-
footer=types.NewTemplate.Footer(text="Powered by PyWa"),
283-
buttons=[
284-
types.NewTemplate.UrlButton(title="Buy Now", url="https://example.com/shop/{iphone15}"),
285-
types.NewTemplate.PhoneNumberButton(title="Call Us", phone_number='1234567890'),
286-
types.NewTemplate.QuickReplyButton(text="Unsubscribe from marketing messages"),
287-
types.NewTemplate.QuickReplyButton(text="Unsubscribe from all messages"),
288-
],
289-
),
290-
)
291-
292-
# Send the template message
293-
wa.send_template(
294-
to="9876543210",
295-
template=types.Template(
296-
name="buy_new_iphone_x",
297-
language=types.Template.Language.ENGLISH_US,
298-
header=types.Template.TextValue(value="15"),
299-
body=[
300-
types.Template.TextValue(value="John Doe"),
301-
types.Template.TextValue(value="WA_IPHONE_15"),
302-
types.Template.TextValue(value="15%"),
303-
],
304-
buttons=[
305-
types.Template.UrlButtonValue(value="iphone15"),
306-
types.Template.QuickReplyButtonData(data="unsubscribe_from_marketing_messages"),
307-
types.Template.QuickReplyButtonData(data="unsubscribe_from_all_messages"),
308-
],
309-
),
310-
)
311-
```
312-
313293
πŸŽ› **Installation**
314294
--------------------
315295

@@ -348,16 +328,6 @@ pip3 install -U "pywa[cryptography]"
348328

349329
See the [Documentation](https://pywa.readthedocs.io/) for detailed instructions
350330

351-
β˜‘οΈ **TODO**
352-
------------
353-
354-
- ~~Add support for async~~
355-
- ~~Add support for more web frameworks (Django, aiohttp, etc.)~~
356-
- ~~Add support for flows~~
357-
- Add support for more types of updates (``account_alerts``, ``phone_number_quality_updates``, ``template_category_updates``, etc.)
358-
- Add more examples and guides
359-
360-
Feel free to open an issue if you have any suggestions. or even better - submit a PR!
361331

362332
βš–οΈ **License**
363333
---------------
@@ -370,3 +340,8 @@ This project is licensed under the MIT License - see the
370340
--------------------
371341

372342
Contributions are welcome! Please see the [Contributing Guide](https://github.com/david-lev/pywa/blob/master/CONTRIBUTING.md) for more information.
343+
344+
πŸ—£ **Community**
345+
--------------------
346+
347+
Join the [Telegram Group](https://t.me/pywachat) to discuss, ask questions, and share your projects built with PyWa!

β€Ždocs/requirements.txtβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
sphinx-book-theme==1.1.3
1+
sphinx-book-theme==1.1.4
22
sphinx-copybutton==0.5.2
33
sphinxext-opengraph==0.9.1
44
sphinx-togglebutton==0.3.2
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{% extends "!layout.html" %}
2+
3+
{% block extrahead %}
4+
{{ super() }}
5+
<link rel="apple-touch-icon" sizes="180x180" href="{{ pathto('_static/apple-touch-icon.png', 1) }}">
6+
<link rel="icon" type="image/png" sizes="32x32" href="{{ pathto('_static/favicon-32x32.png', 1) }}">
7+
<link rel="icon" type="image/png" sizes="16x16" href="{{ pathto('_static/favicon-16x16.png', 1) }}">
8+
<link rel="manifest" href="{{ pathto('_static/site.webmanifest', 1) }}">
9+
<link rel="icon" type="image/png" sizes="192x192" href="{{ pathto('_static/android-chrome-192x192.png', 1) }}">
10+
<link rel="icon" type="image/png" sizes="512x512" href="{{ pathto('_static/android-chrome-512x512.png', 1) }}">
11+
{% endblock %}

β€Ždocs/source/conf.pyβ€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
# relative to this directory. They are copied after the builtin static files,
7070
# so a file named "default.css" will overwrite the builtin "default.css".
7171
html_static_path = ["../static"]
72-
html_favicon = "favicon.ico"
72+
html_favicon = "../static/favicon.ico"
7373

7474
# sphinx.ext.autodoc
7575
autodoc_member_order = "bysource"
@@ -147,7 +147,7 @@
147147
ogp_description_length = 300
148148
ogp_type = "website"
149149
ogp_custom_meta_tags = [
150-
'<meta property="og:description" content="PyWa β€’ Build WhatsApp Bots in Python β€’ Fast, Effortless, Powerful πŸš€" /> '
150+
'<meta property="og:description" content="πŸš€ PyWa β€’ Build WhatsApp Bots in Python β€’ Fast, Effortless, Powerful" /> '
151151
]
152152

153153
# html_extra_path = ["google898e98a538257a96.html"]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
πŸ“ž Calls
2+
=========
3+
4+
The WhatsApp Business Calling API enables you to initiate and receive calls with users on WhatsApp using voice-over-internet protocol (VoIP).
5+
6+
It provides a way to manage call permissions, initiate calls, and handle call events such as connection, termination, and status updates.
7+
8+
.. note::
9+
10+
WORK IN PROGRESS: Pywa support for WhatsApp calls is still under development. The API is fully implemented and tested, but no actual calls have been made yet.
11+
12+
For full documentation of the Cloud API Calling, see the official documentation: https://developers.facebook.com/docs/whatsapp/cloud-api/calling
13+
14+
.. toctree::
15+
types

0 commit comments

Comments
Β (0)