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.
@@ -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
+ [![PyPI version](https://img.shields.io/pypi/v/smsman-client.svg)](https://pypi.org/project/smsman-client/)
16
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](LICENSE)
17
+ [![Python Version](https://img.shields.io/pypi/pyversions/smsman-client.svg)](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
+ [![PyPI version](https://img.shields.io/pypi/v/smsman-client.svg)](https://pypi.org/project/smsman-client/)
4
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](LICENSE)
5
+ [![Python Version](https://img.shields.io/pypi/pyversions/smsman-client.svg)](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
+ ]