asiacellclient 1.0.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.
- asiacellclient-1.0.0/PKG-INFO +248 -0
- asiacellclient-1.0.0/README.md +233 -0
- asiacellclient-1.0.0/asiacellclient/__init__.py +8 -0
- asiacellclient-1.0.0/asiacellclient/client.py +151 -0
- asiacellclient-1.0.0/asiacellclient/exceptions.py +14 -0
- asiacellclient-1.0.0/asiacellclient/models.py +27 -0
- asiacellclient-1.0.0/asiacellclient.egg-info/PKG-INFO +248 -0
- asiacellclient-1.0.0/asiacellclient.egg-info/SOURCES.txt +11 -0
- asiacellclient-1.0.0/asiacellclient.egg-info/dependency_links.txt +1 -0
- asiacellclient-1.0.0/asiacellclient.egg-info/requires.txt +2 -0
- asiacellclient-1.0.0/asiacellclient.egg-info/top_level.txt +1 -0
- asiacellclient-1.0.0/setup.cfg +4 -0
- asiacellclient-1.0.0/setup.py +23 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: asiacellclient
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Unofficial AsiaCell Python SDK
|
|
5
|
+
Author: KingZero
|
|
6
|
+
Author-email: KingZero@darksidehost.com
|
|
7
|
+
License: MIT
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: requests
|
|
14
|
+
Requires-Dist: fake_useragent
|
|
15
|
+
|
|
16
|
+
# AsiaCell SDK
|
|
17
|
+
|
|
18
|
+
A modern Python SDK for interacting with AsiaCell APIs.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- Token-based authentication
|
|
23
|
+
- Profile parsing
|
|
24
|
+
- Balance retrieval
|
|
25
|
+
- Voucher top-up
|
|
26
|
+
- Typed response models
|
|
27
|
+
- Session management
|
|
28
|
+
- Random User-Agent rotation
|
|
29
|
+
- Custom exceptions
|
|
30
|
+
- Lightweight and easy to use
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
# Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install asiacell
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
# Quick Start
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from asiacell import AsiaCellClient
|
|
46
|
+
|
|
47
|
+
client = AsiaCellClient(
|
|
48
|
+
token="YOUR_TOKEN"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
profile = client.get_profile()
|
|
52
|
+
|
|
53
|
+
print(profile.name)
|
|
54
|
+
print(profile.phone)
|
|
55
|
+
print(profile.balance.amount)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
# Authentication
|
|
61
|
+
|
|
62
|
+
The SDK currently supports Bearer Token authentication.
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from asiacell import AsiaCellClient
|
|
66
|
+
|
|
67
|
+
client = AsiaCellClient(
|
|
68
|
+
token="YOUR_JWT_TOKEN"
|
|
69
|
+
)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
You can also set or clear the token later:
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
client.set_token("TOKEN")
|
|
76
|
+
|
|
77
|
+
client.clear_token()
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
# Profile
|
|
83
|
+
|
|
84
|
+
Retrieve account profile information.
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
profile = client.get_profile()
|
|
88
|
+
|
|
89
|
+
print(profile.name)
|
|
90
|
+
print(profile.phone)
|
|
91
|
+
print(profile.photo)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Profile Object
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
profile.name
|
|
98
|
+
profile.phone
|
|
99
|
+
profile.photo
|
|
100
|
+
profile.balance
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
# Balance
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
balance = client.get_balance()
|
|
109
|
+
|
|
110
|
+
print(balance.amount)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
# Voucher Top-Up
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
result = client.topup(
|
|
119
|
+
msisdn="077XXXXXXXX",
|
|
120
|
+
voucher="1234567890"
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
print(result.success)
|
|
124
|
+
print(result.message)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## TopUpResult Object
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
result.success
|
|
131
|
+
result.message
|
|
132
|
+
result.raw
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
# Random User-Agent Rotation
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
client.rotate_user_agent()
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
# Exceptions
|
|
146
|
+
|
|
147
|
+
The SDK provides custom exceptions:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from asiacell.exceptions import (
|
|
151
|
+
AsiacellError,
|
|
152
|
+
AuthenticationError,
|
|
153
|
+
APIError,
|
|
154
|
+
VoucherUsedError
|
|
155
|
+
)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Example:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
try:
|
|
162
|
+
client.get_profile()
|
|
163
|
+
|
|
164
|
+
except AuthenticationError:
|
|
165
|
+
print("Invalid token")
|
|
166
|
+
|
|
167
|
+
except APIError as e:
|
|
168
|
+
print(e)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
# Models
|
|
174
|
+
|
|
175
|
+
## Profile
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
Profile(
|
|
179
|
+
name: str,
|
|
180
|
+
phone: str,
|
|
181
|
+
photo: str,
|
|
182
|
+
balance: Balance
|
|
183
|
+
)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Balance
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
Balance(
|
|
190
|
+
amount: int
|
|
191
|
+
)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## TopUpResult
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
TopUpResult(
|
|
198
|
+
success: bool,
|
|
199
|
+
message: str,
|
|
200
|
+
raw: dict
|
|
201
|
+
)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
# Example
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from asiacell import AsiaCellClient
|
|
210
|
+
|
|
211
|
+
client = AsiaCellClient(
|
|
212
|
+
token="YOUR_TOKEN"
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
profile = client.get_profile()
|
|
216
|
+
|
|
217
|
+
print(profile.name)
|
|
218
|
+
print(profile.balance.amount)
|
|
219
|
+
|
|
220
|
+
result = client.topup(
|
|
221
|
+
msisdn=profile.phone,
|
|
222
|
+
voucher="1234567890"
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
print(result.message)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
# Requirements
|
|
231
|
+
|
|
232
|
+
- Python 3.9+
|
|
233
|
+
- requests
|
|
234
|
+
- fake-useragent
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
# Legal Disclaimer
|
|
239
|
+
|
|
240
|
+
This project is an unofficial SDK and is not affiliated with or endorsed by AsiaCell.
|
|
241
|
+
|
|
242
|
+
Use responsibly and in compliance with applicable terms of service.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
# License
|
|
247
|
+
|
|
248
|
+
MIT License
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# AsiaCell SDK
|
|
2
|
+
|
|
3
|
+
A modern Python SDK for interacting with AsiaCell APIs.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Token-based authentication
|
|
8
|
+
- Profile parsing
|
|
9
|
+
- Balance retrieval
|
|
10
|
+
- Voucher top-up
|
|
11
|
+
- Typed response models
|
|
12
|
+
- Session management
|
|
13
|
+
- Random User-Agent rotation
|
|
14
|
+
- Custom exceptions
|
|
15
|
+
- Lightweight and easy to use
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install asiacell
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# Quick Start
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from asiacell import AsiaCellClient
|
|
31
|
+
|
|
32
|
+
client = AsiaCellClient(
|
|
33
|
+
token="YOUR_TOKEN"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
profile = client.get_profile()
|
|
37
|
+
|
|
38
|
+
print(profile.name)
|
|
39
|
+
print(profile.phone)
|
|
40
|
+
print(profile.balance.amount)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
# Authentication
|
|
46
|
+
|
|
47
|
+
The SDK currently supports Bearer Token authentication.
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from asiacell import AsiaCellClient
|
|
51
|
+
|
|
52
|
+
client = AsiaCellClient(
|
|
53
|
+
token="YOUR_JWT_TOKEN"
|
|
54
|
+
)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
You can also set or clear the token later:
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
client.set_token("TOKEN")
|
|
61
|
+
|
|
62
|
+
client.clear_token()
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
# Profile
|
|
68
|
+
|
|
69
|
+
Retrieve account profile information.
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
profile = client.get_profile()
|
|
73
|
+
|
|
74
|
+
print(profile.name)
|
|
75
|
+
print(profile.phone)
|
|
76
|
+
print(profile.photo)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Profile Object
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
profile.name
|
|
83
|
+
profile.phone
|
|
84
|
+
profile.photo
|
|
85
|
+
profile.balance
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
# Balance
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
balance = client.get_balance()
|
|
94
|
+
|
|
95
|
+
print(balance.amount)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
# Voucher Top-Up
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
result = client.topup(
|
|
104
|
+
msisdn="077XXXXXXXX",
|
|
105
|
+
voucher="1234567890"
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
print(result.success)
|
|
109
|
+
print(result.message)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## TopUpResult Object
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
result.success
|
|
116
|
+
result.message
|
|
117
|
+
result.raw
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
# Random User-Agent Rotation
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
client.rotate_user_agent()
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
# Exceptions
|
|
131
|
+
|
|
132
|
+
The SDK provides custom exceptions:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
from asiacell.exceptions import (
|
|
136
|
+
AsiacellError,
|
|
137
|
+
AuthenticationError,
|
|
138
|
+
APIError,
|
|
139
|
+
VoucherUsedError
|
|
140
|
+
)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Example:
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
try:
|
|
147
|
+
client.get_profile()
|
|
148
|
+
|
|
149
|
+
except AuthenticationError:
|
|
150
|
+
print("Invalid token")
|
|
151
|
+
|
|
152
|
+
except APIError as e:
|
|
153
|
+
print(e)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
# Models
|
|
159
|
+
|
|
160
|
+
## Profile
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
Profile(
|
|
164
|
+
name: str,
|
|
165
|
+
phone: str,
|
|
166
|
+
photo: str,
|
|
167
|
+
balance: Balance
|
|
168
|
+
)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Balance
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
Balance(
|
|
175
|
+
amount: int
|
|
176
|
+
)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## TopUpResult
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
TopUpResult(
|
|
183
|
+
success: bool,
|
|
184
|
+
message: str,
|
|
185
|
+
raw: dict
|
|
186
|
+
)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
# Example
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
from asiacell import AsiaCellClient
|
|
195
|
+
|
|
196
|
+
client = AsiaCellClient(
|
|
197
|
+
token="YOUR_TOKEN"
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
profile = client.get_profile()
|
|
201
|
+
|
|
202
|
+
print(profile.name)
|
|
203
|
+
print(profile.balance.amount)
|
|
204
|
+
|
|
205
|
+
result = client.topup(
|
|
206
|
+
msisdn=profile.phone,
|
|
207
|
+
voucher="1234567890"
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
print(result.message)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
# Requirements
|
|
216
|
+
|
|
217
|
+
- Python 3.9+
|
|
218
|
+
- requests
|
|
219
|
+
- fake-useragent
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
# Legal Disclaimer
|
|
224
|
+
|
|
225
|
+
This project is an unofficial SDK and is not affiliated with or endorsed by AsiaCell.
|
|
226
|
+
|
|
227
|
+
Use responsibly and in compliance with applicable terms of service.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
# License
|
|
232
|
+
|
|
233
|
+
MIT License
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from typing import Optional, Dict
|
|
3
|
+
from fake_useragent import UserAgent
|
|
4
|
+
from .models import Profile, Balance, TopUpResult
|
|
5
|
+
from .exceptions import APIError, AuthenticationError, VoucherUsedError
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AsiaCellClient:
|
|
9
|
+
BASE_URL = "https://www.asiacell.com/api/v1"
|
|
10
|
+
|
|
11
|
+
def __init__(self, device_id: Optional[str] = None, token: Optional[str] = None, timeout: int = 20):
|
|
12
|
+
self.device_id = device_id if device_id else self.generate_device_id()
|
|
13
|
+
self.timeout = timeout
|
|
14
|
+
self.ua = UserAgent()
|
|
15
|
+
self.session = requests.Session()
|
|
16
|
+
if token:
|
|
17
|
+
self.set_token(token)
|
|
18
|
+
self.session.headers.update({
|
|
19
|
+
"Accept": "*/*",
|
|
20
|
+
"Content-Type": "application/json",
|
|
21
|
+
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
|
|
22
|
+
"DeviceId": self.device_id,
|
|
23
|
+
"Accept-Language": "ar-EG,ar;q=0.9,en-US;q=0.8,en;q=0.7,ar-AE;q=0.6",
|
|
24
|
+
"Connection": "keep-alive",
|
|
25
|
+
"Referer": "https://www.asiacell.com/personal/my-account",
|
|
26
|
+
"Origin": "https://www.asiacell.com"
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
if self.token:
|
|
30
|
+
self.session.headers["Authorization"] = f"Bearer {self.token}"
|
|
31
|
+
self.rotate_user_agent()
|
|
32
|
+
|
|
33
|
+
# ======================
|
|
34
|
+
# Token handling
|
|
35
|
+
# ======================
|
|
36
|
+
|
|
37
|
+
def set_token(self, token: str):
|
|
38
|
+
self.token = token
|
|
39
|
+
self.session.headers["Authorization"] = f"Bearer {token}"
|
|
40
|
+
self.session.get(url="https://www.asiacell.com/personal/my-account?tab=1",timeout=self.timeout)
|
|
41
|
+
|
|
42
|
+
def clear_token(self):
|
|
43
|
+
self.token = None
|
|
44
|
+
self.session.headers.pop("Authorization", None)
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def is_authenticated(self) -> bool:
|
|
48
|
+
return self.token is not None
|
|
49
|
+
|
|
50
|
+
def generate_device_id(self):
|
|
51
|
+
import uuid
|
|
52
|
+
return uuid.uuid4().hex
|
|
53
|
+
|
|
54
|
+
def rotate_user_agent(self):
|
|
55
|
+
self.session.headers["User-Agent"] = self.ua.random
|
|
56
|
+
|
|
57
|
+
# ======================
|
|
58
|
+
# Core request
|
|
59
|
+
# ======================
|
|
60
|
+
|
|
61
|
+
def _request(self, method: str, endpoint: str, json: Dict = None):
|
|
62
|
+
url = f"{self.BASE_URL}{endpoint}"
|
|
63
|
+
if not self.is_authenticated:
|
|
64
|
+
raise AuthenticationError("Unauthorized")
|
|
65
|
+
try:
|
|
66
|
+
res = self.session.request(
|
|
67
|
+
method=method,
|
|
68
|
+
url=url,
|
|
69
|
+
json=json,
|
|
70
|
+
timeout=self.timeout
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
data = res.json()
|
|
74
|
+
|
|
75
|
+
except Exception as e:
|
|
76
|
+
raise APIError(f"Request failed: {str(e)}")
|
|
77
|
+
|
|
78
|
+
if isinstance(data, dict) and data.get("success") is False:
|
|
79
|
+
msg = data.get("message", "Unknown error")
|
|
80
|
+
|
|
81
|
+
if "voucher has been used" in msg.lower():
|
|
82
|
+
raise VoucherUsedError(msg)
|
|
83
|
+
|
|
84
|
+
if "unauthorized" in msg.lower():
|
|
85
|
+
raise AuthenticationError(msg)
|
|
86
|
+
|
|
87
|
+
raise APIError(msg)
|
|
88
|
+
|
|
89
|
+
return data
|
|
90
|
+
|
|
91
|
+
# ======================
|
|
92
|
+
# Profile
|
|
93
|
+
# ======================
|
|
94
|
+
|
|
95
|
+
def get_profile(self) -> Profile:
|
|
96
|
+
data = self._request("GET", "/profile?lang=ar")
|
|
97
|
+
|
|
98
|
+
bodies = data["data"]["bodies"]
|
|
99
|
+
|
|
100
|
+
profile_block = next(
|
|
101
|
+
(b for b in bodies if b.get("type") == "profile"),
|
|
102
|
+
None
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
item = profile_block["items"][0]
|
|
106
|
+
|
|
107
|
+
balance = self.get_balance()
|
|
108
|
+
|
|
109
|
+
return Profile(
|
|
110
|
+
name=item.get("name"),
|
|
111
|
+
phone=item.get("phoneNumber"),
|
|
112
|
+
photo=item.get("photo"),
|
|
113
|
+
balance=balance
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# ======================
|
|
117
|
+
# Balance
|
|
118
|
+
# ======================
|
|
119
|
+
|
|
120
|
+
def get_balance(self) -> Balance:
|
|
121
|
+
data = self._request("GET", "/profile?lang=ar")
|
|
122
|
+
|
|
123
|
+
bodies = data["data"]["bodies"]
|
|
124
|
+
|
|
125
|
+
balance_block = next(
|
|
126
|
+
(b for b in bodies if b.get("type") == "balance"),
|
|
127
|
+
None
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
amount = balance_block["items"][0]["value"]
|
|
131
|
+
|
|
132
|
+
return Balance(amount=int(amount))
|
|
133
|
+
|
|
134
|
+
# ======================
|
|
135
|
+
# TopUp
|
|
136
|
+
# ======================
|
|
137
|
+
|
|
138
|
+
def topup(self, msisdn: str, voucher: str, recharge_type: int = 1) -> TopUpResult:
|
|
139
|
+
payload = {
|
|
140
|
+
"msisdn": msisdn,
|
|
141
|
+
"voucher": voucher,
|
|
142
|
+
"rechargeType": recharge_type
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
data = self._request("POST", "/top-up?lang=ar", json=payload)
|
|
146
|
+
|
|
147
|
+
return TopUpResult(
|
|
148
|
+
success=data.get("success", False),
|
|
149
|
+
message=data.get("message", ""),
|
|
150
|
+
raw=data
|
|
151
|
+
)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Optional, Dict
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class Balance:
|
|
7
|
+
amount: int
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class Profile:
|
|
12
|
+
name: str
|
|
13
|
+
phone: str
|
|
14
|
+
photo: str
|
|
15
|
+
|
|
16
|
+
balance: Optional[Balance] = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class TopUpResult:
|
|
21
|
+
success: bool
|
|
22
|
+
message: str
|
|
23
|
+
raw: Optional[Dict] = None
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def is_success(self) -> bool:
|
|
27
|
+
return self.success
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: asiacellclient
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Unofficial AsiaCell Python SDK
|
|
5
|
+
Author: KingZero
|
|
6
|
+
Author-email: KingZero@darksidehost.com
|
|
7
|
+
License: MIT
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: requests
|
|
14
|
+
Requires-Dist: fake_useragent
|
|
15
|
+
|
|
16
|
+
# AsiaCell SDK
|
|
17
|
+
|
|
18
|
+
A modern Python SDK for interacting with AsiaCell APIs.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- Token-based authentication
|
|
23
|
+
- Profile parsing
|
|
24
|
+
- Balance retrieval
|
|
25
|
+
- Voucher top-up
|
|
26
|
+
- Typed response models
|
|
27
|
+
- Session management
|
|
28
|
+
- Random User-Agent rotation
|
|
29
|
+
- Custom exceptions
|
|
30
|
+
- Lightweight and easy to use
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
# Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install asiacell
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
# Quick Start
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from asiacell import AsiaCellClient
|
|
46
|
+
|
|
47
|
+
client = AsiaCellClient(
|
|
48
|
+
token="YOUR_TOKEN"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
profile = client.get_profile()
|
|
52
|
+
|
|
53
|
+
print(profile.name)
|
|
54
|
+
print(profile.phone)
|
|
55
|
+
print(profile.balance.amount)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
# Authentication
|
|
61
|
+
|
|
62
|
+
The SDK currently supports Bearer Token authentication.
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from asiacell import AsiaCellClient
|
|
66
|
+
|
|
67
|
+
client = AsiaCellClient(
|
|
68
|
+
token="YOUR_JWT_TOKEN"
|
|
69
|
+
)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
You can also set or clear the token later:
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
client.set_token("TOKEN")
|
|
76
|
+
|
|
77
|
+
client.clear_token()
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
# Profile
|
|
83
|
+
|
|
84
|
+
Retrieve account profile information.
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
profile = client.get_profile()
|
|
88
|
+
|
|
89
|
+
print(profile.name)
|
|
90
|
+
print(profile.phone)
|
|
91
|
+
print(profile.photo)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Profile Object
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
profile.name
|
|
98
|
+
profile.phone
|
|
99
|
+
profile.photo
|
|
100
|
+
profile.balance
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
# Balance
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
balance = client.get_balance()
|
|
109
|
+
|
|
110
|
+
print(balance.amount)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
# Voucher Top-Up
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
result = client.topup(
|
|
119
|
+
msisdn="077XXXXXXXX",
|
|
120
|
+
voucher="1234567890"
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
print(result.success)
|
|
124
|
+
print(result.message)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## TopUpResult Object
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
result.success
|
|
131
|
+
result.message
|
|
132
|
+
result.raw
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
# Random User-Agent Rotation
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
client.rotate_user_agent()
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
# Exceptions
|
|
146
|
+
|
|
147
|
+
The SDK provides custom exceptions:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from asiacell.exceptions import (
|
|
151
|
+
AsiacellError,
|
|
152
|
+
AuthenticationError,
|
|
153
|
+
APIError,
|
|
154
|
+
VoucherUsedError
|
|
155
|
+
)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Example:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
try:
|
|
162
|
+
client.get_profile()
|
|
163
|
+
|
|
164
|
+
except AuthenticationError:
|
|
165
|
+
print("Invalid token")
|
|
166
|
+
|
|
167
|
+
except APIError as e:
|
|
168
|
+
print(e)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
# Models
|
|
174
|
+
|
|
175
|
+
## Profile
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
Profile(
|
|
179
|
+
name: str,
|
|
180
|
+
phone: str,
|
|
181
|
+
photo: str,
|
|
182
|
+
balance: Balance
|
|
183
|
+
)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Balance
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
Balance(
|
|
190
|
+
amount: int
|
|
191
|
+
)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## TopUpResult
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
TopUpResult(
|
|
198
|
+
success: bool,
|
|
199
|
+
message: str,
|
|
200
|
+
raw: dict
|
|
201
|
+
)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
# Example
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from asiacell import AsiaCellClient
|
|
210
|
+
|
|
211
|
+
client = AsiaCellClient(
|
|
212
|
+
token="YOUR_TOKEN"
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
profile = client.get_profile()
|
|
216
|
+
|
|
217
|
+
print(profile.name)
|
|
218
|
+
print(profile.balance.amount)
|
|
219
|
+
|
|
220
|
+
result = client.topup(
|
|
221
|
+
msisdn=profile.phone,
|
|
222
|
+
voucher="1234567890"
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
print(result.message)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
# Requirements
|
|
231
|
+
|
|
232
|
+
- Python 3.9+
|
|
233
|
+
- requests
|
|
234
|
+
- fake-useragent
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
# Legal Disclaimer
|
|
239
|
+
|
|
240
|
+
This project is an unofficial SDK and is not affiliated with or endorsed by AsiaCell.
|
|
241
|
+
|
|
242
|
+
Use responsibly and in compliance with applicable terms of service.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
# License
|
|
247
|
+
|
|
248
|
+
MIT License
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
setup.py
|
|
3
|
+
asiacellclient/__init__.py
|
|
4
|
+
asiacellclient/client.py
|
|
5
|
+
asiacellclient/exceptions.py
|
|
6
|
+
asiacellclient/models.py
|
|
7
|
+
asiacellclient.egg-info/PKG-INFO
|
|
8
|
+
asiacellclient.egg-info/SOURCES.txt
|
|
9
|
+
asiacellclient.egg-info/dependency_links.txt
|
|
10
|
+
asiacellclient.egg-info/requires.txt
|
|
11
|
+
asiacellclient.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
asiacellclient
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="asiacellclient",
|
|
5
|
+
version="1.0.0",
|
|
6
|
+
author="KingZero",
|
|
7
|
+
author_email="KingZero@darksidehost.com",
|
|
8
|
+
description="Unofficial AsiaCell Python SDK",
|
|
9
|
+
long_description=open("README.md").read(),
|
|
10
|
+
long_description_content_type="text/markdown",
|
|
11
|
+
packages=find_packages(),
|
|
12
|
+
install_requires=[
|
|
13
|
+
"requests",
|
|
14
|
+
"fake_useragent"
|
|
15
|
+
],
|
|
16
|
+
classifiers=[
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
],
|
|
21
|
+
python_requires='>=3.9',
|
|
22
|
+
license="MIT"
|
|
23
|
+
)
|