wirebox 0.1.0__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.
- wirebox-0.1.0/.gitignore +37 -0
- wirebox-0.1.0/LICENSE +21 -0
- wirebox-0.1.0/PKG-INFO +223 -0
- wirebox-0.1.0/README.md +192 -0
- wirebox-0.1.0/pyproject.toml +69 -0
- wirebox-0.1.0/src/wirebox/__init__.py +90 -0
- wirebox-0.1.0/src/wirebox/_http.py +204 -0
- wirebox-0.1.0/src/wirebox/_version.py +1 -0
- wirebox-0.1.0/src/wirebox/async_client.py +138 -0
- wirebox-0.1.0/src/wirebox/client.py +117 -0
- wirebox-0.1.0/src/wirebox/exceptions.py +118 -0
- wirebox-0.1.0/src/wirebox/identity.py +490 -0
- wirebox-0.1.0/src/wirebox/mail.py +276 -0
- wirebox-0.1.0/src/wirebox/py.typed +1 -0
- wirebox-0.1.0/src/wirebox/tunnels.py +342 -0
- wirebox-0.1.0/src/wirebox/types.py +512 -0
- wirebox-0.1.0/src/wirebox/verify_webhook.py +109 -0
- wirebox-0.1.0/src/wirebox/webhooks.py +235 -0
- wirebox-0.1.0/tests/conftest.py +13 -0
- wirebox-0.1.0/tests/test_async_client.py +103 -0
- wirebox-0.1.0/tests/test_client.py +137 -0
- wirebox-0.1.0/tests/test_exceptions.py +53 -0
- wirebox-0.1.0/tests/test_tunnels.py +96 -0
- wirebox-0.1.0/tests/test_types.py +122 -0
- wirebox-0.1.0/tests/test_verify_webhook.py +122 -0
- wirebox-0.1.0/tests/test_webhooks.py +186 -0
- wirebox-0.1.0/uv.lock +549 -0
wirebox-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
.eggs/
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
env/
|
|
15
|
+
venv/
|
|
16
|
+
ENV/
|
|
17
|
+
|
|
18
|
+
# Testing & Coverage
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
.coverage
|
|
21
|
+
htmlcov/
|
|
22
|
+
coverage.xml
|
|
23
|
+
|
|
24
|
+
# IDE & Editor
|
|
25
|
+
.vscode/
|
|
26
|
+
.idea/
|
|
27
|
+
*.swp
|
|
28
|
+
*.swo
|
|
29
|
+
|
|
30
|
+
# Environment variables
|
|
31
|
+
.env
|
|
32
|
+
.env.*
|
|
33
|
+
!.env.example
|
|
34
|
+
|
|
35
|
+
# OS files
|
|
36
|
+
.DS_Store
|
|
37
|
+
Thumbs.db
|
wirebox-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Wirebox (https://wirebox.sh)
|
|
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.
|
wirebox-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: wirebox
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official Python SDK for Wirebox — Real-world identity and communication layer for AI agents
|
|
5
|
+
Project-URL: Homepage, https://wirebox.sh
|
|
6
|
+
Project-URL: Documentation, https://docs.wirebox.sh
|
|
7
|
+
Project-URL: Repository, https://github.com/wirebox-sh/wirebox-python
|
|
8
|
+
Author-email: Wirebox Team <hi@wirebox.sh>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agents,ai,email,identity,tunnels,webhooks,wirebox
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: httpx>=0.27.0
|
|
24
|
+
Requires-Dist: websockets>=12.0
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# Wirebox Python SDK
|
|
33
|
+
|
|
34
|
+
Official Python SDK for [Wirebox](https://wirebox.sh) — The real-world identity, communication, and context execution layer for AI agents.
|
|
35
|
+
|
|
36
|
+
Equips autonomous agents with dedicated email inboxes, network tunnels, and webhooks with first-class synchronous and asynchronous support.
|
|
37
|
+
|
|
38
|
+
[](https://pypi.org/project/wirebox/)
|
|
39
|
+
[](https://pypi.org/project/wirebox/)
|
|
40
|
+
[](https://opensource.org/licenses/MIT)
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Key Features
|
|
45
|
+
|
|
46
|
+
- **Dual Engine**: High-performance synchronous `Wirebox` and native asynchronous `AsyncWirebox` clients.
|
|
47
|
+
- **Identity & Mailbox Hub**: Provision autonomous agent personas with atomic dedicated email inboxes (`@wireboxmail.com`).
|
|
48
|
+
- **Zero-Config Network Tunnels**: Expose local agent servers or containers to the public internet (`https://<handle>.tunnel.wirebox.sh`) over secure WebSockets — **no ngrok required**.
|
|
49
|
+
- **Cryptographic Webhook Verification**: Constant-time HMAC-SHA256 signature verification (`verify_webhook`) with anti-replay timestamp validation.
|
|
50
|
+
- **Zero Heavy C Dependencies**: Built cleanly on `httpx` and `websockets` — installs instantly across Linux, macOS, and Windows.
|
|
51
|
+
- **Modern Pythonic Design**: Full Python 3.11+ type hints (PEP 561 `py.typed`), immutable dataclasses, and rich exception hierarchy.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Installation
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install wirebox
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or using modern package managers:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# With uv
|
|
65
|
+
uv add wirebox
|
|
66
|
+
|
|
67
|
+
# With poetry
|
|
68
|
+
poetry add wirebox
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Quickstart
|
|
74
|
+
|
|
75
|
+
### 1. Asynchronous Client (Recommended for AI Agents & FastAPI)
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
import asyncio
|
|
79
|
+
from wirebox import AsyncWirebox
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
async def main():
|
|
83
|
+
async with AsyncWirebox(api_key="wb_live_xxxxxxxx") as client:
|
|
84
|
+
# 1. Provision an autonomous agent identity
|
|
85
|
+
agent = await client.create_identity("sales-bot", display_name="Sales Assistant")
|
|
86
|
+
print(f"Created agent @{agent.agent_handle} with inbox {agent.mailbox.email_address}")
|
|
87
|
+
|
|
88
|
+
# 2. Dispatch an outbound email
|
|
89
|
+
result = await agent.send_email(
|
|
90
|
+
to="client@example.com",
|
|
91
|
+
subject="Welcome to Wirebox",
|
|
92
|
+
text="Hello! This message was dispatched autonomously by an AI agent.",
|
|
93
|
+
)
|
|
94
|
+
print(f"Email sent with status: {result.status}")
|
|
95
|
+
|
|
96
|
+
# 3. Retrieve and iterate over inbox messages
|
|
97
|
+
async for msg in agent.iter_messages():
|
|
98
|
+
print(f"[{msg.direction}] {msg.from_address}: {msg.subject}")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
asyncio.run(main())
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 2. Synchronous Client (For Scripts, REPL & CLI tools)
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from wirebox import Wirebox
|
|
108
|
+
|
|
109
|
+
client = Wirebox(api_key="wb_live_xxxxxxxx")
|
|
110
|
+
|
|
111
|
+
# Provision or fetch existing identity
|
|
112
|
+
agent = client.get_identity("sales-bot")
|
|
113
|
+
|
|
114
|
+
# Send email
|
|
115
|
+
agent.send_email(
|
|
116
|
+
to="support@example.com",
|
|
117
|
+
subject="Agent status update",
|
|
118
|
+
text="All background jobs running normally.",
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Whoami identity check
|
|
122
|
+
me = client.whoami()
|
|
123
|
+
print(f"Authenticated as org: {me.organization.slug} ({me.api_key.role})")
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Webhooks & Cryptographic Signature Verification
|
|
129
|
+
|
|
130
|
+
Wirebox signs every webhook payload with an HMAC-SHA256 signature to guarantee authenticity and prevent tampering or replay attacks.
|
|
131
|
+
|
|
132
|
+
Use `verify_webhook` directly in any web framework:
|
|
133
|
+
|
|
134
|
+
### FastAPI / Starlette Example:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from fastapi import FastAPI, Request, HTTPException
|
|
138
|
+
from wirebox import verify_webhook
|
|
139
|
+
|
|
140
|
+
app = FastAPI()
|
|
141
|
+
WEBHOOK_SECRET = "whsec_your_signing_secret"
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@app.post("/webhook")
|
|
145
|
+
async def webhook_endpoint(request: Request):
|
|
146
|
+
raw_body = await request.body()
|
|
147
|
+
|
|
148
|
+
# Validates signature and checks timestamp within 300-second window
|
|
149
|
+
if not verify_webhook(payload=raw_body, headers=request.headers, secret=WEBHOOK_SECRET):
|
|
150
|
+
raise HTTPException(status_code=403, detail="Invalid signature")
|
|
151
|
+
|
|
152
|
+
payload = await request.json()
|
|
153
|
+
event_type = payload.get("event_type")
|
|
154
|
+
print(f"Received verified event: {event_type}")
|
|
155
|
+
|
|
156
|
+
return {"status": "ok"}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Network Tunnels (Local Port Forwarding)
|
|
162
|
+
|
|
163
|
+
Connect local ports or container services to your agent's public tunnel URL without opening firewall ports or buying static IPs:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
import asyncio
|
|
167
|
+
from wirebox import AsyncWirebox
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
async def main():
|
|
171
|
+
async with AsyncWirebox(api_key="wb_live_...") as client:
|
|
172
|
+
agent = await client.get_identity("sales-bot")
|
|
173
|
+
|
|
174
|
+
# Reverse-proxy inbound HTTPS traffic from tunnel to local port 3456
|
|
175
|
+
tunnel = await agent.connect_tunnel(forward_to=3456)
|
|
176
|
+
print(f"Public tunnel URL: {tunnel.public_url}")
|
|
177
|
+
|
|
178
|
+
# Keep proxying until closed
|
|
179
|
+
await tunnel.wait_closed()
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
asyncio.run(main())
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Exception Hierarchy
|
|
188
|
+
|
|
189
|
+
All SDK exceptions inherit from `WireboxError`:
|
|
190
|
+
|
|
191
|
+
```text
|
|
192
|
+
WireboxError
|
|
193
|
+
├── WireboxConnectionError # Network, connection drop, or timeout failures
|
|
194
|
+
├── ValidationError # Client-side parameter validation failure
|
|
195
|
+
└── WireboxAPIError # Non-2xx responses from Wirebox API
|
|
196
|
+
├── AuthenticationError # HTTP 401 / 403 (invalid API key or lack of permissions)
|
|
197
|
+
├── NotFoundError # HTTP 404 (identity, mailbox, message, or webhook not found)
|
|
198
|
+
├── RateLimitError # HTTP 429 (rate limits exceeded)
|
|
199
|
+
├── HandleAlreadyTakenError # HTTP 409 (agent_handle already registered)
|
|
200
|
+
└── FreeTierLimitExceededError # HTTP 403/429 (free tier quota limit reached)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Example handling:
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
from wirebox import Wirebox, HandleAlreadyTakenError, WireboxAPIError
|
|
207
|
+
|
|
208
|
+
client = Wirebox(api_key="wb_live_...")
|
|
209
|
+
|
|
210
|
+
try:
|
|
211
|
+
agent = client.create_identity("sales-bot")
|
|
212
|
+
except HandleAlreadyTakenError:
|
|
213
|
+
print("Handle is already claimed. Fetching existing identity instead...")
|
|
214
|
+
agent = client.get_identity("sales-bot")
|
|
215
|
+
except WireboxAPIError as e:
|
|
216
|
+
print(f"API failed with [{e.status} {e.code}]: {e.message} (request_id: {e.request_id})")
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## License
|
|
222
|
+
|
|
223
|
+
MIT © [Wirebox](https://wirebox.sh)
|
wirebox-0.1.0/README.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Wirebox Python SDK
|
|
2
|
+
|
|
3
|
+
Official Python SDK for [Wirebox](https://wirebox.sh) — The real-world identity, communication, and context execution layer for AI agents.
|
|
4
|
+
|
|
5
|
+
Equips autonomous agents with dedicated email inboxes, network tunnels, and webhooks with first-class synchronous and asynchronous support.
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/wirebox/)
|
|
8
|
+
[](https://pypi.org/project/wirebox/)
|
|
9
|
+
[](https://opensource.org/licenses/MIT)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Key Features
|
|
14
|
+
|
|
15
|
+
- **Dual Engine**: High-performance synchronous `Wirebox` and native asynchronous `AsyncWirebox` clients.
|
|
16
|
+
- **Identity & Mailbox Hub**: Provision autonomous agent personas with atomic dedicated email inboxes (`@wireboxmail.com`).
|
|
17
|
+
- **Zero-Config Network Tunnels**: Expose local agent servers or containers to the public internet (`https://<handle>.tunnel.wirebox.sh`) over secure WebSockets — **no ngrok required**.
|
|
18
|
+
- **Cryptographic Webhook Verification**: Constant-time HMAC-SHA256 signature verification (`verify_webhook`) with anti-replay timestamp validation.
|
|
19
|
+
- **Zero Heavy C Dependencies**: Built cleanly on `httpx` and `websockets` — installs instantly across Linux, macOS, and Windows.
|
|
20
|
+
- **Modern Pythonic Design**: Full Python 3.11+ type hints (PEP 561 `py.typed`), immutable dataclasses, and rich exception hierarchy.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install wirebox
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or using modern package managers:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# With uv
|
|
34
|
+
uv add wirebox
|
|
35
|
+
|
|
36
|
+
# With poetry
|
|
37
|
+
poetry add wirebox
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Quickstart
|
|
43
|
+
|
|
44
|
+
### 1. Asynchronous Client (Recommended for AI Agents & FastAPI)
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import asyncio
|
|
48
|
+
from wirebox import AsyncWirebox
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
async def main():
|
|
52
|
+
async with AsyncWirebox(api_key="wb_live_xxxxxxxx") as client:
|
|
53
|
+
# 1. Provision an autonomous agent identity
|
|
54
|
+
agent = await client.create_identity("sales-bot", display_name="Sales Assistant")
|
|
55
|
+
print(f"Created agent @{agent.agent_handle} with inbox {agent.mailbox.email_address}")
|
|
56
|
+
|
|
57
|
+
# 2. Dispatch an outbound email
|
|
58
|
+
result = await agent.send_email(
|
|
59
|
+
to="client@example.com",
|
|
60
|
+
subject="Welcome to Wirebox",
|
|
61
|
+
text="Hello! This message was dispatched autonomously by an AI agent.",
|
|
62
|
+
)
|
|
63
|
+
print(f"Email sent with status: {result.status}")
|
|
64
|
+
|
|
65
|
+
# 3. Retrieve and iterate over inbox messages
|
|
66
|
+
async for msg in agent.iter_messages():
|
|
67
|
+
print(f"[{msg.direction}] {msg.from_address}: {msg.subject}")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
asyncio.run(main())
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 2. Synchronous Client (For Scripts, REPL & CLI tools)
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from wirebox import Wirebox
|
|
77
|
+
|
|
78
|
+
client = Wirebox(api_key="wb_live_xxxxxxxx")
|
|
79
|
+
|
|
80
|
+
# Provision or fetch existing identity
|
|
81
|
+
agent = client.get_identity("sales-bot")
|
|
82
|
+
|
|
83
|
+
# Send email
|
|
84
|
+
agent.send_email(
|
|
85
|
+
to="support@example.com",
|
|
86
|
+
subject="Agent status update",
|
|
87
|
+
text="All background jobs running normally.",
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# Whoami identity check
|
|
91
|
+
me = client.whoami()
|
|
92
|
+
print(f"Authenticated as org: {me.organization.slug} ({me.api_key.role})")
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Webhooks & Cryptographic Signature Verification
|
|
98
|
+
|
|
99
|
+
Wirebox signs every webhook payload with an HMAC-SHA256 signature to guarantee authenticity and prevent tampering or replay attacks.
|
|
100
|
+
|
|
101
|
+
Use `verify_webhook` directly in any web framework:
|
|
102
|
+
|
|
103
|
+
### FastAPI / Starlette Example:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from fastapi import FastAPI, Request, HTTPException
|
|
107
|
+
from wirebox import verify_webhook
|
|
108
|
+
|
|
109
|
+
app = FastAPI()
|
|
110
|
+
WEBHOOK_SECRET = "whsec_your_signing_secret"
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@app.post("/webhook")
|
|
114
|
+
async def webhook_endpoint(request: Request):
|
|
115
|
+
raw_body = await request.body()
|
|
116
|
+
|
|
117
|
+
# Validates signature and checks timestamp within 300-second window
|
|
118
|
+
if not verify_webhook(payload=raw_body, headers=request.headers, secret=WEBHOOK_SECRET):
|
|
119
|
+
raise HTTPException(status_code=403, detail="Invalid signature")
|
|
120
|
+
|
|
121
|
+
payload = await request.json()
|
|
122
|
+
event_type = payload.get("event_type")
|
|
123
|
+
print(f"Received verified event: {event_type}")
|
|
124
|
+
|
|
125
|
+
return {"status": "ok"}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Network Tunnels (Local Port Forwarding)
|
|
131
|
+
|
|
132
|
+
Connect local ports or container services to your agent's public tunnel URL without opening firewall ports or buying static IPs:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
import asyncio
|
|
136
|
+
from wirebox import AsyncWirebox
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
async def main():
|
|
140
|
+
async with AsyncWirebox(api_key="wb_live_...") as client:
|
|
141
|
+
agent = await client.get_identity("sales-bot")
|
|
142
|
+
|
|
143
|
+
# Reverse-proxy inbound HTTPS traffic from tunnel to local port 3456
|
|
144
|
+
tunnel = await agent.connect_tunnel(forward_to=3456)
|
|
145
|
+
print(f"Public tunnel URL: {tunnel.public_url}")
|
|
146
|
+
|
|
147
|
+
# Keep proxying until closed
|
|
148
|
+
await tunnel.wait_closed()
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
asyncio.run(main())
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Exception Hierarchy
|
|
157
|
+
|
|
158
|
+
All SDK exceptions inherit from `WireboxError`:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
WireboxError
|
|
162
|
+
├── WireboxConnectionError # Network, connection drop, or timeout failures
|
|
163
|
+
├── ValidationError # Client-side parameter validation failure
|
|
164
|
+
└── WireboxAPIError # Non-2xx responses from Wirebox API
|
|
165
|
+
├── AuthenticationError # HTTP 401 / 403 (invalid API key or lack of permissions)
|
|
166
|
+
├── NotFoundError # HTTP 404 (identity, mailbox, message, or webhook not found)
|
|
167
|
+
├── RateLimitError # HTTP 429 (rate limits exceeded)
|
|
168
|
+
├── HandleAlreadyTakenError # HTTP 409 (agent_handle already registered)
|
|
169
|
+
└── FreeTierLimitExceededError # HTTP 403/429 (free tier quota limit reached)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Example handling:
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
from wirebox import Wirebox, HandleAlreadyTakenError, WireboxAPIError
|
|
176
|
+
|
|
177
|
+
client = Wirebox(api_key="wb_live_...")
|
|
178
|
+
|
|
179
|
+
try:
|
|
180
|
+
agent = client.create_identity("sales-bot")
|
|
181
|
+
except HandleAlreadyTakenError:
|
|
182
|
+
print("Handle is already claimed. Fetching existing identity instead...")
|
|
183
|
+
agent = client.get_identity("sales-bot")
|
|
184
|
+
except WireboxAPIError as e:
|
|
185
|
+
print(f"API failed with [{e.status} {e.code}]: {e.message} (request_id: {e.request_id})")
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
MIT © [Wirebox](https://wirebox.sh)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "wirebox"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Official Python SDK for Wirebox — Real-world identity and communication layer for AI agents"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Wirebox Team", email = "hi@wirebox.sh" }
|
|
15
|
+
]
|
|
16
|
+
keywords = [
|
|
17
|
+
"wirebox",
|
|
18
|
+
"ai",
|
|
19
|
+
"agents",
|
|
20
|
+
"email",
|
|
21
|
+
"webhooks",
|
|
22
|
+
"tunnels",
|
|
23
|
+
"identity"
|
|
24
|
+
]
|
|
25
|
+
classifiers = [
|
|
26
|
+
"Development Status :: 4 - Beta",
|
|
27
|
+
"Intended Audience :: Developers",
|
|
28
|
+
"License :: OSI Approved :: MIT License",
|
|
29
|
+
"Programming Language :: Python :: 3",
|
|
30
|
+
"Programming Language :: Python :: 3.11",
|
|
31
|
+
"Programming Language :: Python :: 3.12",
|
|
32
|
+
"Programming Language :: Python :: 3.13",
|
|
33
|
+
"Programming Language :: Python :: 3.14",
|
|
34
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
35
|
+
"Typing :: Typed",
|
|
36
|
+
]
|
|
37
|
+
dependencies = [
|
|
38
|
+
"httpx>=0.27.0",
|
|
39
|
+
"websockets>=12.0",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.optional-dependencies]
|
|
43
|
+
dev = [
|
|
44
|
+
"pytest>=8.0.0",
|
|
45
|
+
"pytest-asyncio>=0.23.0",
|
|
46
|
+
"pytest-cov>=5.0.0",
|
|
47
|
+
"ruff>=0.4.0",
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[project.urls]
|
|
51
|
+
Homepage = "https://wirebox.sh"
|
|
52
|
+
Documentation = "https://docs.wirebox.sh"
|
|
53
|
+
Repository = "https://github.com/wirebox-sh/wirebox-python"
|
|
54
|
+
|
|
55
|
+
[tool.hatch.build.targets.wheel]
|
|
56
|
+
packages = ["src/wirebox"]
|
|
57
|
+
|
|
58
|
+
[tool.pytest.ini_options]
|
|
59
|
+
testpaths = ["tests"]
|
|
60
|
+
pythonpath = ["src"]
|
|
61
|
+
asyncio_mode = "auto"
|
|
62
|
+
|
|
63
|
+
[tool.ruff]
|
|
64
|
+
line-length = 100
|
|
65
|
+
target-version = "py311"
|
|
66
|
+
|
|
67
|
+
[tool.ruff.lint]
|
|
68
|
+
select = ["E", "F", "W", "I", "UP", "B", "SIM"]
|
|
69
|
+
ignore = ["E501"]
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Wirebox — Real-world identity, communication, and context execution layer for AI agents.
|
|
2
|
+
|
|
3
|
+
Official Python SDK providing synchronous and asynchronous interfaces to equip autonomous
|
|
4
|
+
agents with dedicated phone numbers, email inboxes, network tunnels, and webhooks.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from wirebox._version import __version__
|
|
8
|
+
from wirebox.async_client import AsyncWirebox
|
|
9
|
+
from wirebox.client import Wirebox
|
|
10
|
+
from wirebox.exceptions import (
|
|
11
|
+
AuthenticationError,
|
|
12
|
+
FreeTierLimitExceededError,
|
|
13
|
+
HandleAlreadyTakenError,
|
|
14
|
+
NotFoundError,
|
|
15
|
+
RateLimitError,
|
|
16
|
+
ValidationError,
|
|
17
|
+
WireboxAPIError,
|
|
18
|
+
WireboxConnectionError,
|
|
19
|
+
WireboxError,
|
|
20
|
+
)
|
|
21
|
+
from wirebox.identity import AgentIdentity, AsyncAgentIdentity
|
|
22
|
+
from wirebox.tunnels import TunnelSession
|
|
23
|
+
from wirebox.types import (
|
|
24
|
+
EmailMessage,
|
|
25
|
+
IdentityData,
|
|
26
|
+
IdentityTunnelSummary,
|
|
27
|
+
MailboxSummary,
|
|
28
|
+
MessageAttachmentSummary,
|
|
29
|
+
MessageSummary,
|
|
30
|
+
SendEmailAttachment,
|
|
31
|
+
SendEmailResult,
|
|
32
|
+
Tunnel,
|
|
33
|
+
TunnelClientTelemetry,
|
|
34
|
+
Webhook,
|
|
35
|
+
WebhookCreateResult,
|
|
36
|
+
WebhookEventType,
|
|
37
|
+
WebhookRotateSecretResult,
|
|
38
|
+
WebhookStatus,
|
|
39
|
+
WebhookTestResult,
|
|
40
|
+
WhoamiApiKey,
|
|
41
|
+
WhoamiOrganization,
|
|
42
|
+
WhoamiResult,
|
|
43
|
+
)
|
|
44
|
+
from wirebox.verify_webhook import verify_webhook
|
|
45
|
+
|
|
46
|
+
# Canonical aliases for cross-SDK naming consistency
|
|
47
|
+
WireboxClient = Wirebox
|
|
48
|
+
AsyncWireboxClient = AsyncWirebox
|
|
49
|
+
|
|
50
|
+
__all__ = [
|
|
51
|
+
"__version__",
|
|
52
|
+
"Wirebox",
|
|
53
|
+
"WireboxClient",
|
|
54
|
+
"AsyncWirebox",
|
|
55
|
+
"AsyncWireboxClient",
|
|
56
|
+
"AgentIdentity",
|
|
57
|
+
"AsyncAgentIdentity",
|
|
58
|
+
"TunnelSession",
|
|
59
|
+
"verify_webhook",
|
|
60
|
+
# Exceptions
|
|
61
|
+
"WireboxError",
|
|
62
|
+
"WireboxAPIError",
|
|
63
|
+
"AuthenticationError",
|
|
64
|
+
"NotFoundError",
|
|
65
|
+
"RateLimitError",
|
|
66
|
+
"HandleAlreadyTakenError",
|
|
67
|
+
"FreeTierLimitExceededError",
|
|
68
|
+
"WireboxConnectionError",
|
|
69
|
+
"ValidationError",
|
|
70
|
+
# Types
|
|
71
|
+
"IdentityData",
|
|
72
|
+
"IdentityTunnelSummary",
|
|
73
|
+
"MailboxSummary",
|
|
74
|
+
"SendEmailAttachment",
|
|
75
|
+
"SendEmailResult",
|
|
76
|
+
"MessageAttachmentSummary",
|
|
77
|
+
"MessageSummary",
|
|
78
|
+
"EmailMessage",
|
|
79
|
+
"Tunnel",
|
|
80
|
+
"TunnelClientTelemetry",
|
|
81
|
+
"Webhook",
|
|
82
|
+
"WebhookCreateResult",
|
|
83
|
+
"WebhookTestResult",
|
|
84
|
+
"WebhookRotateSecretResult",
|
|
85
|
+
"WebhookEventType",
|
|
86
|
+
"WebhookStatus",
|
|
87
|
+
"WhoamiOrganization",
|
|
88
|
+
"WhoamiApiKey",
|
|
89
|
+
"WhoamiResult",
|
|
90
|
+
]
|