smsman-client 0.2.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.
- smsman_client-0.2.0/.gitignore +46 -0
- smsman_client-0.2.0/LICENSE +15 -0
- smsman_client-0.2.0/PKG-INFO +202 -0
- smsman_client-0.2.0/README.md +190 -0
- smsman_client-0.2.0/examples/check.py +21 -0
- smsman_client-0.2.0/pyproject.toml +43 -0
- smsman_client-0.2.0/src/sms_man/__init__.py +12 -0
- smsman_client-0.2.0/src/sms_man/client.py +349 -0
- smsman_client-0.2.0/src/sms_man/errors.py +20 -0
- smsman_client-0.2.0/src/sms_man/types.py +40 -0
- smsman_client-0.2.0/tests/test_client.py +115 -0
- smsman_client-0.2.0/tests/test_live.py +15 -0
- smsman_client-0.2.0/uv.lock +295 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules/
|
|
3
|
+
.pnp.*
|
|
4
|
+
.yarn/
|
|
5
|
+
.pnpm-store/
|
|
6
|
+
|
|
7
|
+
# Build
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
*.tsbuildinfo
|
|
11
|
+
*.egg-info/
|
|
12
|
+
.eggs/
|
|
13
|
+
wheels/
|
|
14
|
+
|
|
15
|
+
# Tests and coverage
|
|
16
|
+
coverage/
|
|
17
|
+
.nyc_output/
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.mypy_cache/
|
|
20
|
+
.ruff_cache/
|
|
21
|
+
htmlcov/
|
|
22
|
+
.coverage
|
|
23
|
+
.coverage.*
|
|
24
|
+
|
|
25
|
+
# Python
|
|
26
|
+
__pycache__/
|
|
27
|
+
*.py[cod]
|
|
28
|
+
*$py.class
|
|
29
|
+
.venv/
|
|
30
|
+
venv/
|
|
31
|
+
env/
|
|
32
|
+
|
|
33
|
+
# Secrets
|
|
34
|
+
.env
|
|
35
|
+
.env.*
|
|
36
|
+
!.env.example
|
|
37
|
+
AGENTS.md
|
|
38
|
+
|
|
39
|
+
# GitBook / HonKit
|
|
40
|
+
_book/
|
|
41
|
+
|
|
42
|
+
# OS and editors
|
|
43
|
+
.DS_Store
|
|
44
|
+
Thumbs.db
|
|
45
|
+
.idea/
|
|
46
|
+
*.swp
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 api-kit contributors
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: smsman-client
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Python client for the SMS-MAN virtual number and SMS activation API
|
|
5
|
+
Project-URL: Repository, https://github.com/TysikGG/api-kit
|
|
6
|
+
Project-URL: Documentation, https://sms-man.com/site/api
|
|
7
|
+
License-Expression: ISC
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Requires-Dist: httpx>=0.27
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# smsman-client
|
|
14
|
+
|
|
15
|
+
[](https://pypi.org/project/smsman-client/)
|
|
16
|
+
[](LICENSE)
|
|
17
|
+
[](https://pypi.org/project/smsman-client/)
|
|
18
|
+
|
|
19
|
+
Modern, fully typed Python client library for the [SMS-MAN](https://sms-man.com/site/api) virtual phone numbers and SMS verification API.
|
|
20
|
+
|
|
21
|
+
Official API documentation: <https://sms-man.com/site/api>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
- 📱 **Dual Protocol Support** — Support for both the native SMS-MAN Control API (`/control/`) and the SMS-Activate compatible handler protocol (`/stubs/handler_api.php`).
|
|
28
|
+
- 🌍 **Global Coverage** — Rent disposable virtual phone numbers across 300+ countries and hundreds of applications.
|
|
29
|
+
- 🐍 **Modern Pythonic Design** — Type annotations, dataclass models (`PhoneNumberOrder`, `SmsCodeResult`), context manager support (`with SmsMan(...) as client:`), and custom exceptions.
|
|
30
|
+
- 🔄 **Full Activation Lifecycle** — Rent numbers, check status, fetch SMS codes, or reject/cancel.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install smsman-client
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Requires Python 3.10 or higher.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Quick Start (Safe Check)
|
|
45
|
+
|
|
46
|
+
The quick check only inspects your account balance. It does not order numbers or consume funds:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
import os
|
|
50
|
+
from sms_man import SmsMan
|
|
51
|
+
|
|
52
|
+
with SmsMan(api_key=os.environ["SMSMAN_API_KEY"]) as client:
|
|
53
|
+
balance = client.get_balance()
|
|
54
|
+
print(f"Current SMS-MAN balance: ${balance:.2f} USD")
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Usage Guide
|
|
60
|
+
|
|
61
|
+
### 1. Renting a Number and Receiving an SMS Code (Control API)
|
|
62
|
+
|
|
63
|
+
Full activation lifecycle using the native Control API:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
import time
|
|
67
|
+
from sms_man import SmsMan, SmsManError
|
|
68
|
+
|
|
69
|
+
with SmsMan(api_key="your_api_key") as client:
|
|
70
|
+
# 1. Order a number for Telegram (app 1) in USA (country 1)
|
|
71
|
+
order = client.get_number(country_id=1, application_id=1)
|
|
72
|
+
print(f"Received number: +{order.number} (Request ID: {order.request_id})")
|
|
73
|
+
|
|
74
|
+
# 2. Poll for the incoming SMS verification code
|
|
75
|
+
code = None
|
|
76
|
+
for _ in range(30):
|
|
77
|
+
time.sleep(3)
|
|
78
|
+
try:
|
|
79
|
+
res = client.get_sms(order.request_id)
|
|
80
|
+
if res.sms_code:
|
|
81
|
+
code = res.sms_code
|
|
82
|
+
break
|
|
83
|
+
except SmsManError as err:
|
|
84
|
+
if err.code == "wait_code":
|
|
85
|
+
continue
|
|
86
|
+
raise err
|
|
87
|
+
|
|
88
|
+
if code:
|
|
89
|
+
print(f"Verification code received: {code}")
|
|
90
|
+
else:
|
|
91
|
+
print("Timeout reached. Rejecting number to refund balance...")
|
|
92
|
+
client.set_status(order.request_id, "reject")
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 2. Inspecting Limits, Prices & Applications
|
|
96
|
+
|
|
97
|
+
Check available limits and application IDs before ordering:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
countries = client.get_countries()
|
|
101
|
+
print("Countries:", countries)
|
|
102
|
+
|
|
103
|
+
apps = client.get_applications()
|
|
104
|
+
print("Applications:", apps)
|
|
105
|
+
|
|
106
|
+
limits = client.get_limits(country_id=1, application_id=1)
|
|
107
|
+
print("Available limits:", limits)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 3. Using the SMS-Activate Protocol (`handler_api.php`)
|
|
111
|
+
|
|
112
|
+
If your existing workflow uses standard `handler_api.php`:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
# 1. Check balance via handler
|
|
116
|
+
balance = client.handler_get_balance()
|
|
117
|
+
print(f"Handler balance: {balance}")
|
|
118
|
+
|
|
119
|
+
# 2. Order number via handler
|
|
120
|
+
activation = client.handler_get_number(service="tg", country=1)
|
|
121
|
+
print(f"Order ID: {activation.id}, Number: {activation.number}")
|
|
122
|
+
|
|
123
|
+
# 3. Mark ready (status 1)
|
|
124
|
+
client.handler_set_status(activation.id, 1)
|
|
125
|
+
|
|
126
|
+
# 4. Check status
|
|
127
|
+
status = client.handler_get_status(activation.id)
|
|
128
|
+
print(f"Status: {status.status}, Code: {status.code}")
|
|
129
|
+
|
|
130
|
+
# 5. Complete activation (status 6) or cancel (status 8)
|
|
131
|
+
client.handler_set_status(activation.id, 6)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## API Reference
|
|
137
|
+
|
|
138
|
+
### `SmsMan` Class
|
|
139
|
+
|
|
140
|
+
#### Constructor
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
SmsMan(
|
|
144
|
+
api_key: str,
|
|
145
|
+
base_url: str = "https://api.sms-man.com",
|
|
146
|
+
timeout: float = 30.0,
|
|
147
|
+
)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
| Parameter | Type | Default | Description |
|
|
151
|
+
| :--- | :--- | :--- | :--- |
|
|
152
|
+
| `api_key` | `str` | **Required** | Your SMS-MAN API key. |
|
|
153
|
+
| `base_url` | `str` | `"https://api.sms-man.com"` | Base URL of SMS-MAN API. |
|
|
154
|
+
| `timeout` | `float` | `30.0` | Request timeout in seconds. |
|
|
155
|
+
|
|
156
|
+
#### Control API Methods (`/control/`)
|
|
157
|
+
|
|
158
|
+
- **`get_balance() -> float`** — Returns current balance in USD.
|
|
159
|
+
- **`get_limits(country_id=None, application_id=None) -> Any`** — Checks number availability and limits.
|
|
160
|
+
- **`get_prices(country_id=None) -> Any`** — Returns pricing for services and countries.
|
|
161
|
+
- **`get_countries() -> Any`** — Lists all supported countries with IDs.
|
|
162
|
+
- **`get_applications() -> Any`** — Lists all supported applications with IDs.
|
|
163
|
+
- **`get_number(country_id: int, application_id: int) -> PhoneNumberOrder`** — Orders a number for the application.
|
|
164
|
+
- **`get_sms(request_id: int) -> SmsCodeResult`** — Checks for received SMS verification code.
|
|
165
|
+
- **`set_status(request_id: int, status: str) -> bool`** — Sets status (`'ready'` or `'reject'`).
|
|
166
|
+
|
|
167
|
+
#### Handler API Methods (`/stubs/handler_api.php`)
|
|
168
|
+
|
|
169
|
+
- **`handler_get_balance() -> float`** — Returns balance via handler API.
|
|
170
|
+
- **`handler_get_number(service, country=None) -> HandlerNumberResult`** — Orders number (`ACCESS_NUMBER`).
|
|
171
|
+
- **`handler_get_status(order_id: int | str) -> HandlerStatusResult`** — Retrieves status and code.
|
|
172
|
+
- **`handler_set_status(order_id: int | str, status: int) -> str`** — Updates activation state (1 = ready, 6 = complete, 8 = cancel).
|
|
173
|
+
- **`handler_get_prices(country=None) -> Any`** — Retrieves prices via handler API.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Error Handling
|
|
178
|
+
|
|
179
|
+
When an API error occurs, `SmsManError` is raised:
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from sms_man import SmsMan, SmsManError
|
|
183
|
+
|
|
184
|
+
try:
|
|
185
|
+
with SmsMan(api_key="invalid_key") as client:
|
|
186
|
+
client.get_balance()
|
|
187
|
+
except SmsManError as exc:
|
|
188
|
+
print(f"SMS-MAN Error: {exc.message} (Code: {exc.code})")
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Common error codes:
|
|
192
|
+
- `no_numbers` — No available phone numbers for selected application/country.
|
|
193
|
+
- `balance_empty` — Insufficient funds on account.
|
|
194
|
+
- `wrong_token` — Invalid API key.
|
|
195
|
+
- `wait_code` — SMS code has not arrived yet.
|
|
196
|
+
- `WRONG_ACTIVATION_ID` — Order ID does not exist or expired.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## License
|
|
201
|
+
|
|
202
|
+
ISC
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# smsman-client
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/smsman-client/)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://pypi.org/project/smsman-client/)
|
|
6
|
+
|
|
7
|
+
Modern, fully typed Python client library for the [SMS-MAN](https://sms-man.com/site/api) virtual phone numbers and SMS verification API.
|
|
8
|
+
|
|
9
|
+
Official API documentation: <https://sms-man.com/site/api>
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- 📱 **Dual Protocol Support** — Support for both the native SMS-MAN Control API (`/control/`) and the SMS-Activate compatible handler protocol (`/stubs/handler_api.php`).
|
|
16
|
+
- 🌍 **Global Coverage** — Rent disposable virtual phone numbers across 300+ countries and hundreds of applications.
|
|
17
|
+
- 🐍 **Modern Pythonic Design** — Type annotations, dataclass models (`PhoneNumberOrder`, `SmsCodeResult`), context manager support (`with SmsMan(...) as client:`), and custom exceptions.
|
|
18
|
+
- 🔄 **Full Activation Lifecycle** — Rent numbers, check status, fetch SMS codes, or reject/cancel.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install smsman-client
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Requires Python 3.10 or higher.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Quick Start (Safe Check)
|
|
33
|
+
|
|
34
|
+
The quick check only inspects your account balance. It does not order numbers or consume funds:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
import os
|
|
38
|
+
from sms_man import SmsMan
|
|
39
|
+
|
|
40
|
+
with SmsMan(api_key=os.environ["SMSMAN_API_KEY"]) as client:
|
|
41
|
+
balance = client.get_balance()
|
|
42
|
+
print(f"Current SMS-MAN balance: ${balance:.2f} USD")
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Usage Guide
|
|
48
|
+
|
|
49
|
+
### 1. Renting a Number and Receiving an SMS Code (Control API)
|
|
50
|
+
|
|
51
|
+
Full activation lifecycle using the native Control API:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
import time
|
|
55
|
+
from sms_man import SmsMan, SmsManError
|
|
56
|
+
|
|
57
|
+
with SmsMan(api_key="your_api_key") as client:
|
|
58
|
+
# 1. Order a number for Telegram (app 1) in USA (country 1)
|
|
59
|
+
order = client.get_number(country_id=1, application_id=1)
|
|
60
|
+
print(f"Received number: +{order.number} (Request ID: {order.request_id})")
|
|
61
|
+
|
|
62
|
+
# 2. Poll for the incoming SMS verification code
|
|
63
|
+
code = None
|
|
64
|
+
for _ in range(30):
|
|
65
|
+
time.sleep(3)
|
|
66
|
+
try:
|
|
67
|
+
res = client.get_sms(order.request_id)
|
|
68
|
+
if res.sms_code:
|
|
69
|
+
code = res.sms_code
|
|
70
|
+
break
|
|
71
|
+
except SmsManError as err:
|
|
72
|
+
if err.code == "wait_code":
|
|
73
|
+
continue
|
|
74
|
+
raise err
|
|
75
|
+
|
|
76
|
+
if code:
|
|
77
|
+
print(f"Verification code received: {code}")
|
|
78
|
+
else:
|
|
79
|
+
print("Timeout reached. Rejecting number to refund balance...")
|
|
80
|
+
client.set_status(order.request_id, "reject")
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 2. Inspecting Limits, Prices & Applications
|
|
84
|
+
|
|
85
|
+
Check available limits and application IDs before ordering:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
countries = client.get_countries()
|
|
89
|
+
print("Countries:", countries)
|
|
90
|
+
|
|
91
|
+
apps = client.get_applications()
|
|
92
|
+
print("Applications:", apps)
|
|
93
|
+
|
|
94
|
+
limits = client.get_limits(country_id=1, application_id=1)
|
|
95
|
+
print("Available limits:", limits)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 3. Using the SMS-Activate Protocol (`handler_api.php`)
|
|
99
|
+
|
|
100
|
+
If your existing workflow uses standard `handler_api.php`:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
# 1. Check balance via handler
|
|
104
|
+
balance = client.handler_get_balance()
|
|
105
|
+
print(f"Handler balance: {balance}")
|
|
106
|
+
|
|
107
|
+
# 2. Order number via handler
|
|
108
|
+
activation = client.handler_get_number(service="tg", country=1)
|
|
109
|
+
print(f"Order ID: {activation.id}, Number: {activation.number}")
|
|
110
|
+
|
|
111
|
+
# 3. Mark ready (status 1)
|
|
112
|
+
client.handler_set_status(activation.id, 1)
|
|
113
|
+
|
|
114
|
+
# 4. Check status
|
|
115
|
+
status = client.handler_get_status(activation.id)
|
|
116
|
+
print(f"Status: {status.status}, Code: {status.code}")
|
|
117
|
+
|
|
118
|
+
# 5. Complete activation (status 6) or cancel (status 8)
|
|
119
|
+
client.handler_set_status(activation.id, 6)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## API Reference
|
|
125
|
+
|
|
126
|
+
### `SmsMan` Class
|
|
127
|
+
|
|
128
|
+
#### Constructor
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
SmsMan(
|
|
132
|
+
api_key: str,
|
|
133
|
+
base_url: str = "https://api.sms-man.com",
|
|
134
|
+
timeout: float = 30.0,
|
|
135
|
+
)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
| Parameter | Type | Default | Description |
|
|
139
|
+
| :--- | :--- | :--- | :--- |
|
|
140
|
+
| `api_key` | `str` | **Required** | Your SMS-MAN API key. |
|
|
141
|
+
| `base_url` | `str` | `"https://api.sms-man.com"` | Base URL of SMS-MAN API. |
|
|
142
|
+
| `timeout` | `float` | `30.0` | Request timeout in seconds. |
|
|
143
|
+
|
|
144
|
+
#### Control API Methods (`/control/`)
|
|
145
|
+
|
|
146
|
+
- **`get_balance() -> float`** — Returns current balance in USD.
|
|
147
|
+
- **`get_limits(country_id=None, application_id=None) -> Any`** — Checks number availability and limits.
|
|
148
|
+
- **`get_prices(country_id=None) -> Any`** — Returns pricing for services and countries.
|
|
149
|
+
- **`get_countries() -> Any`** — Lists all supported countries with IDs.
|
|
150
|
+
- **`get_applications() -> Any`** — Lists all supported applications with IDs.
|
|
151
|
+
- **`get_number(country_id: int, application_id: int) -> PhoneNumberOrder`** — Orders a number for the application.
|
|
152
|
+
- **`get_sms(request_id: int) -> SmsCodeResult`** — Checks for received SMS verification code.
|
|
153
|
+
- **`set_status(request_id: int, status: str) -> bool`** — Sets status (`'ready'` or `'reject'`).
|
|
154
|
+
|
|
155
|
+
#### Handler API Methods (`/stubs/handler_api.php`)
|
|
156
|
+
|
|
157
|
+
- **`handler_get_balance() -> float`** — Returns balance via handler API.
|
|
158
|
+
- **`handler_get_number(service, country=None) -> HandlerNumberResult`** — Orders number (`ACCESS_NUMBER`).
|
|
159
|
+
- **`handler_get_status(order_id: int | str) -> HandlerStatusResult`** — Retrieves status and code.
|
|
160
|
+
- **`handler_set_status(order_id: int | str, status: int) -> str`** — Updates activation state (1 = ready, 6 = complete, 8 = cancel).
|
|
161
|
+
- **`handler_get_prices(country=None) -> Any`** — Retrieves prices via handler API.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Error Handling
|
|
166
|
+
|
|
167
|
+
When an API error occurs, `SmsManError` is raised:
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from sms_man import SmsMan, SmsManError
|
|
171
|
+
|
|
172
|
+
try:
|
|
173
|
+
with SmsMan(api_key="invalid_key") as client:
|
|
174
|
+
client.get_balance()
|
|
175
|
+
except SmsManError as exc:
|
|
176
|
+
print(f"SMS-MAN Error: {exc.message} (Code: {exc.code})")
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Common error codes:
|
|
180
|
+
- `no_numbers` — No available phone numbers for selected application/country.
|
|
181
|
+
- `balance_empty` — Insufficient funds on account.
|
|
182
|
+
- `wrong_token` — Invalid API key.
|
|
183
|
+
- `wait_code` — SMS code has not arrived yet.
|
|
184
|
+
- `WRONG_ACTIVATION_ID` — Order ID does not exist or expired.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## License
|
|
189
|
+
|
|
190
|
+
ISC
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from sms_man import SmsMan
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main() -> None:
|
|
7
|
+
token = os.getenv("SMSMAN_API_KEY", "demo_token")
|
|
8
|
+
with SmsMan(token=token) as client:
|
|
9
|
+
print("Checking SMS-MAN account balance...")
|
|
10
|
+
try:
|
|
11
|
+
balance = client.get_balance()
|
|
12
|
+
print(f"Balance: {balance}")
|
|
13
|
+
|
|
14
|
+
countries = client.get_countries()
|
|
15
|
+
print("Countries received:", bool(countries))
|
|
16
|
+
except Exception as exc:
|
|
17
|
+
print(f"Error connecting to SMS-MAN: {exc}")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
if __name__ == "__main__":
|
|
21
|
+
main()
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Publish trigger
|
|
2
|
+
[build-system]
|
|
3
|
+
requires = ["hatchling"]
|
|
4
|
+
build-backend = "hatchling.build"
|
|
5
|
+
|
|
6
|
+
[project]
|
|
7
|
+
name = "smsman-client"
|
|
8
|
+
version = "0.2.0"
|
|
9
|
+
description = "Python client for the SMS-MAN virtual number and SMS activation API"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
license = "ISC"
|
|
13
|
+
dependencies = [
|
|
14
|
+
"httpx>=0.27",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[project.urls]
|
|
18
|
+
Repository = "https://github.com/TysikGG/api-kit"
|
|
19
|
+
Documentation = "https://sms-man.com/site/api"
|
|
20
|
+
|
|
21
|
+
[dependency-groups]
|
|
22
|
+
dev = [
|
|
23
|
+
"pytest>=8",
|
|
24
|
+
"pytest-httpx>=0.30",
|
|
25
|
+
"ruff>=0.8",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[tool.hatch.build.targets.wheel]
|
|
29
|
+
packages = ["src/sms_man"]
|
|
30
|
+
|
|
31
|
+
[tool.pytest.ini_options]
|
|
32
|
+
markers = [
|
|
33
|
+
"live: calls the real SMS-MAN API and requires SMSMAN_API_KEY",
|
|
34
|
+
]
|
|
35
|
+
testpaths = ["tests"]
|
|
36
|
+
|
|
37
|
+
[tool.ruff]
|
|
38
|
+
target-version = "py310"
|
|
39
|
+
line-length = 100
|
|
40
|
+
src = ["src", "tests", "examples"]
|
|
41
|
+
|
|
42
|
+
[tool.ruff.lint]
|
|
43
|
+
select = ["E", "F", "I", "UP"]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from sms_man.client import DEFAULT_REF, SmsMan
|
|
2
|
+
from sms_man.errors import SmsManError
|
|
3
|
+
from sms_man.types import HandlerStatusResult, PhoneNumberOrder, SmsCodeResult
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"DEFAULT_REF",
|
|
7
|
+
"SmsMan",
|
|
8
|
+
"SmsManError",
|
|
9
|
+
"HandlerStatusResult",
|
|
10
|
+
"PhoneNumberOrder",
|
|
11
|
+
"SmsCodeResult",
|
|
12
|
+
]
|