waha-py 2026.7.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,35 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.9", "3.10", "3.11", "3.12"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python ${{ matrix.python-version }}
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Install dependencies
25
+ run: |
26
+ python -m pip install --upgrade pip
27
+ pip install -e ".[dev]"
28
+
29
+ - name: Lint with ruff
30
+ run: |
31
+ ruff check .
32
+
33
+ - name: Run tests
34
+ run: |
35
+ pytest
@@ -0,0 +1,34 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ push:
7
+ tags:
8
+ - 'v*'
9
+
10
+ jobs:
11
+ pypi-publish:
12
+ name: Build and publish Python distribution to PyPI
13
+ runs-on: ubuntu-latest
14
+ permissions:
15
+ id-token: write # Mandatory for PyPI Trusted Publishing (OIDC)
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: '3.11'
24
+
25
+ - name: Install build tool
26
+ run: |
27
+ python -m pip install --upgrade pip
28
+ pip install build
29
+
30
+ - name: Build package
31
+ run: python -m build
32
+
33
+ - name: Publish package to PyPI
34
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,170 @@
1
+ name: Update OpenAPI Types
2
+
3
+ on:
4
+ schedule:
5
+ # Run daily at midnight UTC
6
+ - cron: '0 0 * * *'
7
+ workflow_dispatch:
8
+ inputs:
9
+ force_release:
10
+ description: 'Force a new release even if no changes'
11
+ required: false
12
+ default: false
13
+ type: boolean
14
+
15
+ env:
16
+ WAHA_URL: http://localhost:3000
17
+ WHATSAPP_SWAGGER_USERNAME: WHATSAPP_SWAGGER_USERNAME
18
+ WHATSAPP_SWAGGER_PASSWORD: WHATSAPP_SWAGGER_PASSWORD
19
+ WAHA_DASHBOARD_USERNAME: WAHA_DASHBOARD_USERNAME
20
+ WAHA_DASHBOARD_PASSWORD: WAHA_DASHBOARD_PASSWORD
21
+ WAHA_API_KEY: WAHA_API_KEY
22
+
23
+ jobs:
24
+ update-types:
25
+ runs-on: ubuntu-latest
26
+ permissions:
27
+ contents: write
28
+
29
+ steps:
30
+ - name: Checkout repository
31
+ uses: actions/checkout@v4
32
+ with:
33
+ fetch-depth: 0
34
+ token: ${{ secrets.GH_PAT }}
35
+
36
+ - name: Set up Python
37
+ uses: actions/setup-python@v5
38
+ with:
39
+ python-version: '3.11'
40
+
41
+ - name: Install dependencies
42
+ run: |
43
+ python -m pip install --upgrade pip
44
+ pip install -e ".[dev]"
45
+
46
+ - name: Get current OpenAPI SHA
47
+ id: old_sha
48
+ run: |
49
+ if [ -f openapi.json ]; then
50
+ SHA=$(sha256sum openapi.json | cut -d' ' -f1)
51
+ echo "sha=$SHA" >> $GITHUB_OUTPUT
52
+ echo "Current OpenAPI SHA: $SHA"
53
+ else
54
+ echo "sha=none" >> $GITHUB_OUTPUT
55
+ echo "No existing openapi.json"
56
+ fi
57
+
58
+ - name: Start WAHA container
59
+ run: |
60
+ docker run -d \
61
+ --name waha \
62
+ -p 3000:3000 \
63
+ -e WHATSAPP_SWAGGER_USERNAME=${{ env.WHATSAPP_SWAGGER_USERNAME }} \
64
+ -e WHATSAPP_SWAGGER_PASSWORD=${{ env.WHATSAPP_SWAGGER_PASSWORD }} \
65
+ -e WAHA_DASHBOARD_USERNAME=${{ env.WAHA_DASHBOARD_USERNAME }} \
66
+ -e WAHA_DASHBOARD_PASSWORD=${{ env.WAHA_DASHBOARD_PASSWORD }} \
67
+ -e WAHA_API_KEY=${{ env.WAHA_API_KEY }} \
68
+ devlikeapro/waha:latest
69
+
70
+ - name: Wait for WAHA to be ready
71
+ run: |
72
+ echo "Waiting for WAHA to start..."
73
+ for i in {1..60}; do
74
+ if curl -s -u ${{ env.WHATSAPP_SWAGGER_USERNAME }}:${{ env.WHATSAPP_SWAGGER_PASSWORD }} ${{ env.WAHA_URL }}/-json > /dev/null 2>&1; then
75
+ echo "WAHA is ready!"
76
+ break
77
+ fi
78
+ if docker logs waha 2>&1 | grep -q "WhatsApp HTTP API is running"; then
79
+ sleep 2
80
+ echo "WAHA started, checking API..."
81
+ fi
82
+ echo "Waiting... ($i/60)"
83
+ sleep 2
84
+ done
85
+
86
+ - name: Fetch OpenAPI spec
87
+ run: |
88
+ if ! curl -f -s -u ${{ env.WHATSAPP_SWAGGER_USERNAME }}:${{ env.WHATSAPP_SWAGGER_PASSWORD }} -o openapi.json ${{ env.WAHA_URL }}/-json; then
89
+ echo "Fixed credentials failed, extracting from logs..."
90
+ SWAGGER_PASSWORD=$(docker logs waha 2>&1 | grep "WHATSAPP_SWAGGER_PASSWORD=" | tail -1 | cut -d'=' -f2)
91
+ curl -u admin:$SWAGGER_PASSWORD -o openapi.json ${{ env.WAHA_URL }}/-json
92
+ fi
93
+ echo "OpenAPI spec size: $(wc -c < openapi.json) bytes"
94
+
95
+ - name: Stop WAHA container
96
+ if: always()
97
+ run: docker stop waha || true
98
+
99
+ - name: Get new OpenAPI SHA
100
+ id: new_sha
101
+ run: |
102
+ SHA=$(sha256sum openapi.json | cut -d' ' -f1)
103
+ echo "sha=$SHA" >> $GITHUB_OUTPUT
104
+ echo "New OpenAPI SHA: $SHA"
105
+
106
+ - name: Check for changes
107
+ id: changes
108
+ run: |
109
+ if [ "${{ steps.old_sha.outputs.sha }}" = "${{ steps.new_sha.outputs.sha }}" ]; then
110
+ echo "has_changes=false" >> $GITHUB_OUTPUT
111
+ echo "No changes detected (SHA match)"
112
+ else
113
+ echo "has_changes=true" >> $GITHUB_OUTPUT
114
+ echo "Changes detected!"
115
+ echo "Old SHA: ${{ steps.old_sha.outputs.sha }}"
116
+ echo "New SHA: ${{ steps.new_sha.outputs.sha }}"
117
+ fi
118
+
119
+ - name: Generate code & models
120
+ if: steps.changes.outputs.has_changes == 'true' || inputs.force_release == true
121
+ run: python scripts/generate.py
122
+
123
+ - name: Get WAHA version
124
+ if: steps.changes.outputs.has_changes == 'true' || inputs.force_release == true
125
+ id: waha_version
126
+ run: |
127
+ VERSION=$(python3 -c "import json; spec=json.load(open('openapi.json')); print(spec.get('info', {}).get('version', '2026.7.1'))")
128
+ echo "waha_version=$VERSION" >> $GITHUB_OUTPUT
129
+ echo "WAHA version: $VERSION"
130
+
131
+ - name: Update pyproject.toml version
132
+ if: steps.changes.outputs.has_changes == 'true' || inputs.force_release == true
133
+ id: bump_version
134
+ run: |
135
+ VERSION="${{ steps.waha_version.outputs.waha_version }}"
136
+ echo "New version: $VERSION"
137
+ python3 -c "
138
+ import re
139
+ content = open('pyproject.toml').read()
140
+ new_content = re.sub(r'version\s*=\s*\".*?\"', f'version = \"{VERSION}\"', content, count=1)
141
+ open('pyproject.toml', 'w').write(new_content)
142
+ "
143
+ echo "new_version=$VERSION" >> $GITHUB_OUTPUT
144
+
145
+ - name: Commit and tag
146
+ if: steps.changes.outputs.has_changes == 'true' || inputs.force_release == true
147
+ run: |
148
+ git config user.name "github-actions[bot]"
149
+ git config user.email "github-actions[bot]@users.noreply.github.com"
150
+
151
+ git add openapi.json openapi_cleaned.json src/ pyproject.toml
152
+ git commit -m "chore: update types for WAHA ${{ steps.waha_version.outputs.waha_version }}"
153
+ git tag -a "v${{ steps.bump_version.outputs.new_version }}" -m "Release v${{ steps.bump_version.outputs.new_version }} for WAHA ${{ steps.waha_version.outputs.waha_version }}"
154
+ git push --follow-tags
155
+
156
+ - name: Create GitHub Release
157
+ if: steps.changes.outputs.has_changes == 'true' || inputs.force_release == true
158
+ uses: softprops/action-gh-release@v2
159
+ with:
160
+ tag_name: v${{ steps.bump_version.outputs.new_version }}
161
+ name: v${{ steps.bump_version.outputs.new_version }}
162
+ body: |
163
+ ## WAHA Version
164
+ This release was generated from WAHA version **${{ steps.waha_version.outputs.waha_version }}**
165
+
166
+ ## Installation
167
+ ```bash
168
+ pip install waha-py==${{ steps.bump_version.outputs.new_version }}
169
+ ```
170
+ generate_release_notes: true
@@ -0,0 +1,26 @@
1
+ # Byte-compiled / optimized files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ dist/
8
+ build/
9
+ *.egg-info/
10
+
11
+ # Environments
12
+ .venv/
13
+ venv/
14
+ env/
15
+
16
+ # Tool caches & test coverage
17
+ .pytest_cache/
18
+ .ruff_cache/
19
+ .mypy_cache/
20
+ .coverage
21
+ htmlcov/
22
+
23
+ # IDE / OS
24
+ .DS_Store
25
+ .vscode/
26
+ .idea/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Muhammed Mustafa AKŞAM
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,160 @@
1
+ Metadata-Version: 2.4
2
+ Name: waha-py
3
+ Version: 2026.7.1
4
+ Summary: Python SDK for WAHA (WhatsApp HTTP API) - auto-generated from OpenAPI spec with full type safety, sync & async support.
5
+ Project-URL: Homepage, https://github.com/muhammedaksam/waha-py
6
+ Project-URL: Documentation, https://github.com/muhammedaksam/waha-py#readme
7
+ Project-URL: Repository, https://github.com/muhammedaksam/waha-py
8
+ Project-URL: Issues, https://github.com/muhammedaksam/waha-py/issues
9
+ Author-email: Muhammed Mustafa AKŞAM <info@muhammedaksam.com.tr>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: http-api,httpx,pydantic,python,sdk,waha,whatsapp,whatsapp-api
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.9
24
+ Requires-Dist: eval-type-backport>=0.1.0; python_version < '3.10'
25
+ Requires-Dist: httpx>=0.25.0
26
+ Requires-Dist: pydantic>=2.0.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: datamodel-code-generator>=0.25.0; extra == 'dev'
29
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
30
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
31
+ Requires-Dist: ruff>=0.4.0; extra == 'dev'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # waha-py
35
+
36
+ [![PyPI version](https://img.shields.io/pypi/v/waha-py.svg)](https://pypi.org/project/waha-py/)
37
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
38
+ [![Python](https://img.shields.io/badge/Python-3.9%2B-blue.svg)](https://www.python.org/)
39
+
40
+ Python SDK for [WAHA (WhatsApp HTTP API)](https://github.com/devlikeapro/waha) - auto-generated from OpenAPI spec with full type safety, Pydantic v2 models, and HTTPX-based synchronous & asynchronous clients.
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ pip install waha-py
46
+ ```
47
+
48
+ ## Usage
49
+
50
+ ### Synchronous Client
51
+
52
+ ```python
53
+ from waha import WahaClient
54
+
55
+ # Initialize with baseURL and optional API key
56
+ client = WahaClient("http://localhost:3000", api_key="your-api-key")
57
+
58
+ # Access controllers via properties
59
+ # Sessions
60
+ sessions = client.sessions.list()
61
+
62
+ # Chatting
63
+ message = client.chatting.send_text(
64
+ session="default",
65
+ payload={
66
+ "chatId": "1234567890@c.us",
67
+ "text": "Hello from waha-py!",
68
+ },
69
+ )
70
+
71
+ # Get QR Code
72
+ qr = client.auth.get_qr(session="default", params={"format": "raw"})
73
+
74
+ # Always close client when done
75
+ client.close()
76
+ ```
77
+
78
+ ### Asynchronous Client
79
+
80
+ ```python
81
+ import asyncio
82
+ from waha import AsyncWahaClient
83
+
84
+
85
+ async def main():
86
+ async_client = AsyncWahaClient("http://localhost:3000", api_key="your-api-key")
87
+
88
+ # Send message asynchronously
89
+ message = await async_client.chatting.a_send_text(
90
+ session="default",
91
+ payload={
92
+ "chatId": "1234567890@c.us",
93
+ "text": "Async hello from waha-py!",
94
+ },
95
+ )
96
+
97
+ await async_client.close()
98
+
99
+
100
+ asyncio.run(main())
101
+ ```
102
+
103
+ ## API Controllers
104
+
105
+ All endpoints are available through client properties:
106
+
107
+ ```python
108
+ client.sessions.* # SessionsApi
109
+ client.chatting.* # ChattingApi
110
+ client.contacts.* # ContactsApi
111
+ client.groups.* # GroupsApi
112
+ client.auth.* # AuthApi
113
+ client.labels.* # LabelsApi
114
+ client.presence.* # PresenceApi
115
+ client.profile.* # ProfileApi
116
+ client.media.* # MediaApi
117
+ # ...and more
118
+ ```
119
+
120
+ ## Pydantic Models
121
+
122
+ All types are auto-generated from the WAHA OpenAPI specification using Pydantic v2:
123
+
124
+ ```python
125
+ from waha.generated.models import SessionInfo, MessageTextRequest, WAMessage
126
+ ```
127
+
128
+ ## How It Works
129
+
130
+ This package is automatically kept in sync with WAHA:
131
+
132
+ 1. **Daily** - GitHub Action spins up latest `devlikeapro/waha` container
133
+ 2. **Fetches** OpenAPI spec from `/-json` endpoint
134
+ 3. **Compares** SHA256 hash with committed `openapi.json`
135
+ 4. **If changed** - Generates new types + Python clients, bumps version, commits, and pushes tag
136
+ 5. **Publishes** to PyPI via OIDC trusted publishing
137
+
138
+ ## Development
139
+
140
+ ### Prerequisites
141
+
142
+ - Python >= 3.9
143
+ - Running WAHA instance (or `openapi.json`)
144
+
145
+ ### Generate Types & Clients Locally
146
+
147
+ ```bash
148
+ # Install development dependencies
149
+ pip install -e ".[dev]"
150
+
151
+ # Generate models and clients from openapi.json
152
+ python scripts/generate.py
153
+
154
+ # Run tests
155
+ pytest
156
+ ```
157
+
158
+ ## License
159
+
160
+ MIT
@@ -0,0 +1,127 @@
1
+ # waha-py
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/waha-py.svg)](https://pypi.org/project/waha-py/)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Python](https://img.shields.io/badge/Python-3.9%2B-blue.svg)](https://www.python.org/)
6
+
7
+ Python SDK for [WAHA (WhatsApp HTTP API)](https://github.com/devlikeapro/waha) - auto-generated from OpenAPI spec with full type safety, Pydantic v2 models, and HTTPX-based synchronous & asynchronous clients.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pip install waha-py
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ### Synchronous Client
18
+
19
+ ```python
20
+ from waha import WahaClient
21
+
22
+ # Initialize with baseURL and optional API key
23
+ client = WahaClient("http://localhost:3000", api_key="your-api-key")
24
+
25
+ # Access controllers via properties
26
+ # Sessions
27
+ sessions = client.sessions.list()
28
+
29
+ # Chatting
30
+ message = client.chatting.send_text(
31
+ session="default",
32
+ payload={
33
+ "chatId": "1234567890@c.us",
34
+ "text": "Hello from waha-py!",
35
+ },
36
+ )
37
+
38
+ # Get QR Code
39
+ qr = client.auth.get_qr(session="default", params={"format": "raw"})
40
+
41
+ # Always close client when done
42
+ client.close()
43
+ ```
44
+
45
+ ### Asynchronous Client
46
+
47
+ ```python
48
+ import asyncio
49
+ from waha import AsyncWahaClient
50
+
51
+
52
+ async def main():
53
+ async_client = AsyncWahaClient("http://localhost:3000", api_key="your-api-key")
54
+
55
+ # Send message asynchronously
56
+ message = await async_client.chatting.a_send_text(
57
+ session="default",
58
+ payload={
59
+ "chatId": "1234567890@c.us",
60
+ "text": "Async hello from waha-py!",
61
+ },
62
+ )
63
+
64
+ await async_client.close()
65
+
66
+
67
+ asyncio.run(main())
68
+ ```
69
+
70
+ ## API Controllers
71
+
72
+ All endpoints are available through client properties:
73
+
74
+ ```python
75
+ client.sessions.* # SessionsApi
76
+ client.chatting.* # ChattingApi
77
+ client.contacts.* # ContactsApi
78
+ client.groups.* # GroupsApi
79
+ client.auth.* # AuthApi
80
+ client.labels.* # LabelsApi
81
+ client.presence.* # PresenceApi
82
+ client.profile.* # ProfileApi
83
+ client.media.* # MediaApi
84
+ # ...and more
85
+ ```
86
+
87
+ ## Pydantic Models
88
+
89
+ All types are auto-generated from the WAHA OpenAPI specification using Pydantic v2:
90
+
91
+ ```python
92
+ from waha.generated.models import SessionInfo, MessageTextRequest, WAMessage
93
+ ```
94
+
95
+ ## How It Works
96
+
97
+ This package is automatically kept in sync with WAHA:
98
+
99
+ 1. **Daily** - GitHub Action spins up latest `devlikeapro/waha` container
100
+ 2. **Fetches** OpenAPI spec from `/-json` endpoint
101
+ 3. **Compares** SHA256 hash with committed `openapi.json`
102
+ 4. **If changed** - Generates new types + Python clients, bumps version, commits, and pushes tag
103
+ 5. **Publishes** to PyPI via OIDC trusted publishing
104
+
105
+ ## Development
106
+
107
+ ### Prerequisites
108
+
109
+ - Python >= 3.9
110
+ - Running WAHA instance (or `openapi.json`)
111
+
112
+ ### Generate Types & Clients Locally
113
+
114
+ ```bash
115
+ # Install development dependencies
116
+ pip install -e ".[dev]"
117
+
118
+ # Generate models and clients from openapi.json
119
+ python scripts/generate.py
120
+
121
+ # Run tests
122
+ pytest
123
+ ```
124
+
125
+ ## License
126
+
127
+ MIT
@@ -0,0 +1,23 @@
1
+ import asyncio
2
+
3
+ from waha import AsyncWahaClient, WahaClient
4
+
5
+
6
+ def sync_example():
7
+ print("=== Sync Example ===")
8
+ client = WahaClient("http://localhost:3000", api_key="secret")
9
+ print("Initialized WahaClient successfully.")
10
+ print("Available controllers:", [attr for attr in dir(client) if not attr.startswith("_")])
11
+ client.close()
12
+
13
+
14
+ async def async_example():
15
+ print("\n=== Async Example ===")
16
+ async_client = AsyncWahaClient("http://localhost:3000", api_key="secret")
17
+ print("Initialized AsyncWahaClient successfully.")
18
+ await async_client.close()
19
+
20
+
21
+ if __name__ == "__main__":
22
+ sync_example()
23
+ asyncio.run(async_example())