etoneya-api 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.
- etoneya_api-0.1.0/LICENSE +21 -0
- etoneya_api-0.1.0/PKG-INFO +360 -0
- etoneya_api-0.1.0/README.md +327 -0
- etoneya_api-0.1.0/etoneya/__init__.py +31 -0
- etoneya_api-0.1.0/etoneya/client.py +216 -0
- etoneya_api-0.1.0/etoneya/exceptions.py +31 -0
- etoneya_api-0.1.0/etoneya/models.py +122 -0
- etoneya_api-0.1.0/etoneya_api.egg-info/PKG-INFO +360 -0
- etoneya_api-0.1.0/etoneya_api.egg-info/SOURCES.txt +13 -0
- etoneya_api-0.1.0/etoneya_api.egg-info/dependency_links.txt +1 -0
- etoneya_api-0.1.0/etoneya_api.egg-info/requires.txt +10 -0
- etoneya_api-0.1.0/etoneya_api.egg-info/top_level.txt +1 -0
- etoneya_api-0.1.0/pyproject.toml +63 -0
- etoneya_api-0.1.0/setup.cfg +4 -0
- etoneya_api-0.1.0/tests/test_client.py +361 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 nloverx (t.me/nloverx)
|
|
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,360 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: etoneya-api
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client library for Etoneya Subscription Management API
|
|
5
|
+
Author-email: nloverx <owner@nloverx.best>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/etoneya/etoneya-api
|
|
8
|
+
Project-URL: Documentation, https://github.com/etoneya/etoneya-api#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/etoneya/etoneya-api
|
|
10
|
+
Project-URL: Issues, https://github.com/etoneya/etoneya-api/issues
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Requires-Python: >=3.8
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: requests>=2.28.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
|
|
28
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
29
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
31
|
+
Requires-Dist: types-requests>=2.28.0; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# Etoneya API Client
|
|
35
|
+
|
|
36
|
+
Python client library for interacting with the Etoneya Subscription Management API.
|
|
37
|
+
|
|
38
|
+
## Features
|
|
39
|
+
|
|
40
|
+
- 🔐 Full authentication support
|
|
41
|
+
- 👥 User management (CRUD operations)
|
|
42
|
+
- 📱 Device management
|
|
43
|
+
- 🚫 IP ban management
|
|
44
|
+
- 🔄 Subscription updates via webhook
|
|
45
|
+
- ⚡ Type-safe with dataclasses
|
|
46
|
+
- 🛡️ Comprehensive error handling
|
|
47
|
+
- 📦 Zero dependencies (except `requests`)
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install etoneya-api
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Or install from source:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
git clone https://github.com/etoneya/etoneya-api.git
|
|
59
|
+
cd etoneya-api
|
|
60
|
+
pip install -e .
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Quick Start
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from etoneya import EtoneyaClient
|
|
67
|
+
|
|
68
|
+
# Initialize client
|
|
69
|
+
client = EtoneyaClient(
|
|
70
|
+
base_url="https://api.example.com",
|
|
71
|
+
auth_token="your_auth_token_here"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Create a new user
|
|
75
|
+
user = client.create_user(
|
|
76
|
+
tg_id=123456789,
|
|
77
|
+
type_sub="premium",
|
|
78
|
+
udid="unique-device-id",
|
|
79
|
+
limit_devices=3,
|
|
80
|
+
status="user"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
print(f"Created user: {user.id}")
|
|
84
|
+
|
|
85
|
+
# Get user by Telegram ID
|
|
86
|
+
user = client.get_user_by_telegram(123456789)
|
|
87
|
+
print(f"User status: {user.status}")
|
|
88
|
+
|
|
89
|
+
# Ban a user
|
|
90
|
+
banned_user = client.ban_user(user.id, reason="Violation of terms")
|
|
91
|
+
|
|
92
|
+
# Get all user devices
|
|
93
|
+
devices = client.get_user_devices(user.udid)
|
|
94
|
+
print(f"User has {len(devices)} devices")
|
|
95
|
+
|
|
96
|
+
# Ban an IP address
|
|
97
|
+
ip_ban = client.create_ip_ban("192.168.1.1", reason="Suspicious activity")
|
|
98
|
+
|
|
99
|
+
# Check if IP is banned
|
|
100
|
+
ban_status = client.check_ip_ban("192.168.1.1")
|
|
101
|
+
print(f"IP banned: {ban_status['is_banned']}")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## User Management
|
|
105
|
+
|
|
106
|
+
### Create User
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
user = client.create_user(
|
|
110
|
+
tg_id=123456789,
|
|
111
|
+
type_sub="premium",
|
|
112
|
+
udid="unique-device-id",
|
|
113
|
+
limit_devices=3,
|
|
114
|
+
reason="",
|
|
115
|
+
is_banned=False,
|
|
116
|
+
is_active=True,
|
|
117
|
+
allowed_useragents=["volunteer-agent-1"],
|
|
118
|
+
status="volunteer" # "user" or "volunteer"
|
|
119
|
+
)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Get Users
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
# Get by ID
|
|
126
|
+
user = client.get_user(1)
|
|
127
|
+
|
|
128
|
+
# Get by Telegram ID
|
|
129
|
+
user = client.get_user_by_telegram(123456789)
|
|
130
|
+
|
|
131
|
+
# Get all users
|
|
132
|
+
all_users = client.get_all_users()
|
|
133
|
+
|
|
134
|
+
# Get active users
|
|
135
|
+
active_users = client.get_active_users()
|
|
136
|
+
|
|
137
|
+
# Get banned users
|
|
138
|
+
banned_users = client.get_banned_users()
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Update User
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
updated_user = client.update_user(
|
|
145
|
+
user_id=1,
|
|
146
|
+
limit_devices=5,
|
|
147
|
+
is_active=True
|
|
148
|
+
)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Ban/Unban User
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
# Ban user
|
|
155
|
+
banned_user = client.ban_user(1, reason="Spam")
|
|
156
|
+
|
|
157
|
+
# Unban user
|
|
158
|
+
unbanned_user = client.unban_user(1)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Delete User
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
client.delete_user(1)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Device Management
|
|
168
|
+
|
|
169
|
+
### Get Devices
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
# Get device by ID
|
|
173
|
+
device = client.get_device(1)
|
|
174
|
+
|
|
175
|
+
# Get device by hardware ID
|
|
176
|
+
device = client.get_device_by_hwid("hwid-123")
|
|
177
|
+
|
|
178
|
+
# Get all devices for a user
|
|
179
|
+
devices = client.get_user_devices("unique-device-id")
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Delete Device
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
client.delete_device(1)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## IP Ban Management
|
|
189
|
+
|
|
190
|
+
### Create IP Ban
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
ban = client.create_ip_ban("192.168.1.1", reason="Malicious activity")
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Check IP Ban
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
status = client.check_ip_ban("192.168.1.1")
|
|
200
|
+
print(status["is_banned"]) # True/False
|
|
201
|
+
print(status["ban_info"]) # Ban details if banned
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Get All Bans
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
bans = client.get_all_bans()
|
|
208
|
+
for ban in bans:
|
|
209
|
+
print(f"{ban.ip}: {ban.reason}")
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Delete IP Ban
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
# By ID
|
|
216
|
+
client.delete_ip_ban(1)
|
|
217
|
+
|
|
218
|
+
# By IP address
|
|
219
|
+
client.delete_ip_ban_by_address("192.168.1.1")
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## System Operations
|
|
223
|
+
|
|
224
|
+
### Health Check
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
health = client.health_check()
|
|
228
|
+
print(health["status"]) # "healthy"
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Update Subscriptions (Webhook)
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
result = client.update_subscriptions(webhook_token="your_webhook_token")
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Error Handling
|
|
238
|
+
|
|
239
|
+
The library provides specific exceptions for different error cases:
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
from etoneya import (
|
|
243
|
+
EtoneyaAPIError,
|
|
244
|
+
AuthenticationError,
|
|
245
|
+
NotFoundError,
|
|
246
|
+
ValidationError,
|
|
247
|
+
RateLimitError
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
try:
|
|
251
|
+
user = client.get_user(999)
|
|
252
|
+
except NotFoundError as e:
|
|
253
|
+
print(f"User not found: {e.message}")
|
|
254
|
+
print(f"Status code: {e.status_code}")
|
|
255
|
+
except AuthenticationError as e:
|
|
256
|
+
print(f"Authentication failed: {e.message}")
|
|
257
|
+
except ValidationError as e:
|
|
258
|
+
print(f"Validation error: {e.response}")
|
|
259
|
+
except RateLimitError as e:
|
|
260
|
+
print("Rate limit exceeded, please retry later")
|
|
261
|
+
except EtoneyaAPIError as e:
|
|
262
|
+
print(f"API error: {e.message}")
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Models
|
|
266
|
+
|
|
267
|
+
### User
|
|
268
|
+
|
|
269
|
+
```python
|
|
270
|
+
@dataclass
|
|
271
|
+
class User:
|
|
272
|
+
id: int
|
|
273
|
+
tg_id: int
|
|
274
|
+
type_sub: str
|
|
275
|
+
udid: str
|
|
276
|
+
limit_devices: int
|
|
277
|
+
reason: str
|
|
278
|
+
is_banned: bool
|
|
279
|
+
is_active: bool
|
|
280
|
+
allowed_useragents: List[str]
|
|
281
|
+
status: str # "user" or "volunteer"
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Device
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
@dataclass
|
|
288
|
+
class Device:
|
|
289
|
+
id: int
|
|
290
|
+
hwid: str
|
|
291
|
+
udid: str
|
|
292
|
+
useragent: str
|
|
293
|
+
os_type: str
|
|
294
|
+
os_ver: int
|
|
295
|
+
model: str
|
|
296
|
+
app_version: str
|
|
297
|
+
ip: str
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### BannedIP
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
@dataclass
|
|
304
|
+
class BannedIP:
|
|
305
|
+
id: int
|
|
306
|
+
ip: str
|
|
307
|
+
reason: str
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Configuration
|
|
311
|
+
|
|
312
|
+
### Timeout
|
|
313
|
+
|
|
314
|
+
```python
|
|
315
|
+
client = EtoneyaClient(
|
|
316
|
+
base_url="https://api.example.com",
|
|
317
|
+
auth_token="token",
|
|
318
|
+
timeout=60 # seconds
|
|
319
|
+
)
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Development
|
|
323
|
+
|
|
324
|
+
### Install development dependencies
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
pip install -e ".[dev]"
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Run tests
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
pytest
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Format code
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
black etoneya/
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Type checking
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
mypy etoneya/
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## License
|
|
349
|
+
|
|
350
|
+
MIT License - see LICENSE file for details.
|
|
351
|
+
|
|
352
|
+
## Author
|
|
353
|
+
|
|
354
|
+
**nloverx**
|
|
355
|
+
- Telegram: [t.me/nloverx](https://t.me/nloverx)
|
|
356
|
+
- Email: owner@nloverx.best
|
|
357
|
+
|
|
358
|
+
## Contributing
|
|
359
|
+
|
|
360
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# Etoneya API Client
|
|
2
|
+
|
|
3
|
+
Python client library for interacting with the Etoneya Subscription Management API.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔐 Full authentication support
|
|
8
|
+
- 👥 User management (CRUD operations)
|
|
9
|
+
- 📱 Device management
|
|
10
|
+
- 🚫 IP ban management
|
|
11
|
+
- 🔄 Subscription updates via webhook
|
|
12
|
+
- ⚡ Type-safe with dataclasses
|
|
13
|
+
- 🛡️ Comprehensive error handling
|
|
14
|
+
- 📦 Zero dependencies (except `requests`)
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install etoneya-api
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or install from source:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
git clone https://github.com/etoneya/etoneya-api.git
|
|
26
|
+
cd etoneya-api
|
|
27
|
+
pip install -e .
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from etoneya import EtoneyaClient
|
|
34
|
+
|
|
35
|
+
# Initialize client
|
|
36
|
+
client = EtoneyaClient(
|
|
37
|
+
base_url="https://api.example.com",
|
|
38
|
+
auth_token="your_auth_token_here"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Create a new user
|
|
42
|
+
user = client.create_user(
|
|
43
|
+
tg_id=123456789,
|
|
44
|
+
type_sub="premium",
|
|
45
|
+
udid="unique-device-id",
|
|
46
|
+
limit_devices=3,
|
|
47
|
+
status="user"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
print(f"Created user: {user.id}")
|
|
51
|
+
|
|
52
|
+
# Get user by Telegram ID
|
|
53
|
+
user = client.get_user_by_telegram(123456789)
|
|
54
|
+
print(f"User status: {user.status}")
|
|
55
|
+
|
|
56
|
+
# Ban a user
|
|
57
|
+
banned_user = client.ban_user(user.id, reason="Violation of terms")
|
|
58
|
+
|
|
59
|
+
# Get all user devices
|
|
60
|
+
devices = client.get_user_devices(user.udid)
|
|
61
|
+
print(f"User has {len(devices)} devices")
|
|
62
|
+
|
|
63
|
+
# Ban an IP address
|
|
64
|
+
ip_ban = client.create_ip_ban("192.168.1.1", reason="Suspicious activity")
|
|
65
|
+
|
|
66
|
+
# Check if IP is banned
|
|
67
|
+
ban_status = client.check_ip_ban("192.168.1.1")
|
|
68
|
+
print(f"IP banned: {ban_status['is_banned']}")
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## User Management
|
|
72
|
+
|
|
73
|
+
### Create User
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
user = client.create_user(
|
|
77
|
+
tg_id=123456789,
|
|
78
|
+
type_sub="premium",
|
|
79
|
+
udid="unique-device-id",
|
|
80
|
+
limit_devices=3,
|
|
81
|
+
reason="",
|
|
82
|
+
is_banned=False,
|
|
83
|
+
is_active=True,
|
|
84
|
+
allowed_useragents=["volunteer-agent-1"],
|
|
85
|
+
status="volunteer" # "user" or "volunteer"
|
|
86
|
+
)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Get Users
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
# Get by ID
|
|
93
|
+
user = client.get_user(1)
|
|
94
|
+
|
|
95
|
+
# Get by Telegram ID
|
|
96
|
+
user = client.get_user_by_telegram(123456789)
|
|
97
|
+
|
|
98
|
+
# Get all users
|
|
99
|
+
all_users = client.get_all_users()
|
|
100
|
+
|
|
101
|
+
# Get active users
|
|
102
|
+
active_users = client.get_active_users()
|
|
103
|
+
|
|
104
|
+
# Get banned users
|
|
105
|
+
banned_users = client.get_banned_users()
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Update User
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
updated_user = client.update_user(
|
|
112
|
+
user_id=1,
|
|
113
|
+
limit_devices=5,
|
|
114
|
+
is_active=True
|
|
115
|
+
)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Ban/Unban User
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
# Ban user
|
|
122
|
+
banned_user = client.ban_user(1, reason="Spam")
|
|
123
|
+
|
|
124
|
+
# Unban user
|
|
125
|
+
unbanned_user = client.unban_user(1)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Delete User
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
client.delete_user(1)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Device Management
|
|
135
|
+
|
|
136
|
+
### Get Devices
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
# Get device by ID
|
|
140
|
+
device = client.get_device(1)
|
|
141
|
+
|
|
142
|
+
# Get device by hardware ID
|
|
143
|
+
device = client.get_device_by_hwid("hwid-123")
|
|
144
|
+
|
|
145
|
+
# Get all devices for a user
|
|
146
|
+
devices = client.get_user_devices("unique-device-id")
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Delete Device
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
client.delete_device(1)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## IP Ban Management
|
|
156
|
+
|
|
157
|
+
### Create IP Ban
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
ban = client.create_ip_ban("192.168.1.1", reason="Malicious activity")
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Check IP Ban
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
status = client.check_ip_ban("192.168.1.1")
|
|
167
|
+
print(status["is_banned"]) # True/False
|
|
168
|
+
print(status["ban_info"]) # Ban details if banned
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Get All Bans
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
bans = client.get_all_bans()
|
|
175
|
+
for ban in bans:
|
|
176
|
+
print(f"{ban.ip}: {ban.reason}")
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Delete IP Ban
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
# By ID
|
|
183
|
+
client.delete_ip_ban(1)
|
|
184
|
+
|
|
185
|
+
# By IP address
|
|
186
|
+
client.delete_ip_ban_by_address("192.168.1.1")
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## System Operations
|
|
190
|
+
|
|
191
|
+
### Health Check
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
health = client.health_check()
|
|
195
|
+
print(health["status"]) # "healthy"
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Update Subscriptions (Webhook)
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
result = client.update_subscriptions(webhook_token="your_webhook_token")
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Error Handling
|
|
205
|
+
|
|
206
|
+
The library provides specific exceptions for different error cases:
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from etoneya import (
|
|
210
|
+
EtoneyaAPIError,
|
|
211
|
+
AuthenticationError,
|
|
212
|
+
NotFoundError,
|
|
213
|
+
ValidationError,
|
|
214
|
+
RateLimitError
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
try:
|
|
218
|
+
user = client.get_user(999)
|
|
219
|
+
except NotFoundError as e:
|
|
220
|
+
print(f"User not found: {e.message}")
|
|
221
|
+
print(f"Status code: {e.status_code}")
|
|
222
|
+
except AuthenticationError as e:
|
|
223
|
+
print(f"Authentication failed: {e.message}")
|
|
224
|
+
except ValidationError as e:
|
|
225
|
+
print(f"Validation error: {e.response}")
|
|
226
|
+
except RateLimitError as e:
|
|
227
|
+
print("Rate limit exceeded, please retry later")
|
|
228
|
+
except EtoneyaAPIError as e:
|
|
229
|
+
print(f"API error: {e.message}")
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Models
|
|
233
|
+
|
|
234
|
+
### User
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
@dataclass
|
|
238
|
+
class User:
|
|
239
|
+
id: int
|
|
240
|
+
tg_id: int
|
|
241
|
+
type_sub: str
|
|
242
|
+
udid: str
|
|
243
|
+
limit_devices: int
|
|
244
|
+
reason: str
|
|
245
|
+
is_banned: bool
|
|
246
|
+
is_active: bool
|
|
247
|
+
allowed_useragents: List[str]
|
|
248
|
+
status: str # "user" or "volunteer"
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Device
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
@dataclass
|
|
255
|
+
class Device:
|
|
256
|
+
id: int
|
|
257
|
+
hwid: str
|
|
258
|
+
udid: str
|
|
259
|
+
useragent: str
|
|
260
|
+
os_type: str
|
|
261
|
+
os_ver: int
|
|
262
|
+
model: str
|
|
263
|
+
app_version: str
|
|
264
|
+
ip: str
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### BannedIP
|
|
268
|
+
|
|
269
|
+
```python
|
|
270
|
+
@dataclass
|
|
271
|
+
class BannedIP:
|
|
272
|
+
id: int
|
|
273
|
+
ip: str
|
|
274
|
+
reason: str
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Configuration
|
|
278
|
+
|
|
279
|
+
### Timeout
|
|
280
|
+
|
|
281
|
+
```python
|
|
282
|
+
client = EtoneyaClient(
|
|
283
|
+
base_url="https://api.example.com",
|
|
284
|
+
auth_token="token",
|
|
285
|
+
timeout=60 # seconds
|
|
286
|
+
)
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Development
|
|
290
|
+
|
|
291
|
+
### Install development dependencies
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
pip install -e ".[dev]"
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Run tests
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
pytest
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Format code
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
black etoneya/
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Type checking
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
mypy etoneya/
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## License
|
|
316
|
+
|
|
317
|
+
MIT License - see LICENSE file for details.
|
|
318
|
+
|
|
319
|
+
## Author
|
|
320
|
+
|
|
321
|
+
**nloverx**
|
|
322
|
+
- Telegram: [t.me/nloverx](https://t.me/nloverx)
|
|
323
|
+
- Email: owner@nloverx.best
|
|
324
|
+
|
|
325
|
+
## Contributing
|
|
326
|
+
|
|
327
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Etoneya API Client
|
|
3
|
+
A Python client library for interacting with the Etoneya Subscription Management API.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
__version__ = "0.1.0"
|
|
7
|
+
__author__ = "nloverx"
|
|
8
|
+
__email__ = "owner@nloverx.best"
|
|
9
|
+
__telegram__ = "t.me/nloverx"
|
|
10
|
+
|
|
11
|
+
from .client import EtoneyaClient
|
|
12
|
+
from .exceptions import (
|
|
13
|
+
EtoneyaAPIError,
|
|
14
|
+
AuthenticationError,
|
|
15
|
+
NotFoundError,
|
|
16
|
+
ValidationError,
|
|
17
|
+
RateLimitError,
|
|
18
|
+
)
|
|
19
|
+
from .models import User, Device, BannedIP
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"EtoneyaClient",
|
|
23
|
+
"EtoneyaAPIError",
|
|
24
|
+
"AuthenticationError",
|
|
25
|
+
"NotFoundError",
|
|
26
|
+
"ValidationError",
|
|
27
|
+
"RateLimitError",
|
|
28
|
+
"User",
|
|
29
|
+
"Device",
|
|
30
|
+
"BannedIP",
|
|
31
|
+
]
|