mobiska 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.
mobiska-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Your Name
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.
mobiska-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,257 @@
1
+ Metadata-Version: 2.4
2
+ Name: mobiska
3
+ Version: 0.1.0
4
+ Summary: Python SDK for the Mobiska REST API
5
+ Author-email: Mobiska <dev@mobiska.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Your Name
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/mobiska/mobiska-py
29
+ Project-URL: Documentation, https://github.com/mobiska/mobiska-py#readme
30
+ Project-URL: Issues, https://github.com/mobiska/mobiska-py/issues
31
+ Keywords: mobiska,sdk,api,client
32
+ Classifier: Programming Language :: Python :: 3
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Operating System :: OS Independent
35
+ Classifier: Intended Audience :: Developers
36
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
37
+ Requires-Python: >=3.8
38
+ Description-Content-Type: text/markdown
39
+ License-File: LICENSE
40
+ Requires-Dist: requests>=2.28
41
+ Provides-Extra: dev
42
+ Requires-Dist: pytest>=7.0; extra == "dev"
43
+ Requires-Dist: pytest-cov; extra == "dev"
44
+ Requires-Dist: responses; extra == "dev"
45
+ Requires-Dist: black; extra == "dev"
46
+ Requires-Dist: ruff; extra == "dev"
47
+ Dynamic: license-file
48
+
49
+ # Mobiska Python SDK
50
+
51
+ The official Python SDK for the Mobiska REST API — payments and SMS for businesses across Africa.
52
+
53
+ ## Installation
54
+
55
+ ```bash
56
+ pip install mobiska
57
+ ```
58
+
59
+ ## Quick Start
60
+
61
+ ### Configuration
62
+
63
+ Credentials can be provided via keyword arguments **or** environment variables:
64
+
65
+ ```bash
66
+ MOBISKA_USER_NAME=your_client_key
67
+ MOBISKA_PASSWORD=your_secret_key
68
+ MOBISKA_SERVICE_ID=1
69
+ MOBISKA_SMS_SENDER_ID=YourSender # SMS only
70
+ MOBISKA_API_URL=https://api.mobiska.com # optional, this is the default
71
+ ```
72
+
73
+ ### SMS
74
+
75
+ ```python
76
+ from mobiska import InitSMS
77
+
78
+ # Uses env vars when no arguments are passed
79
+ sms = InitSMS()
80
+
81
+ # Or pass credentials explicitly
82
+ sms = InitSMS(
83
+ username="your_client_key",
84
+ password="your_secret_key",
85
+ service_id=1,
86
+ sender_id="YourSender",
87
+ )
88
+
89
+ # Send a message
90
+ response = sms.send_sms("0540000000", "Welcome to Mobiska!")
91
+ print(response["response_code"])
92
+
93
+ # Send to multiple recipients
94
+ sms.send_sms(["0540000000", "0200000000"], "Batch message")
95
+
96
+ # Check balance
97
+ balance = sms.check_balance()
98
+ print(balance["response_data"]["sms_balance"])
99
+ ```
100
+
101
+ ### Payments
102
+
103
+ ```python
104
+ from mobiska import InitPayment
105
+
106
+ payment = InitPayment(
107
+ username="your_client_key",
108
+ password="your_secret_key",
109
+ service_id=2,
110
+ )
111
+
112
+ # Make a payment
113
+ result = payment.make_payment(
114
+ reference="Order #123",
115
+ nickname="MyShop",
116
+ transaction_id="txn_001",
117
+ trans_type="CTM",
118
+ customer_number="0541840988",
119
+ nw="MTN",
120
+ amount=100,
121
+ payment_option="MOM",
122
+ callback_url="https://example.com/webhook",
123
+ currency_code="GHS",
124
+ )
125
+
126
+ # Check transaction status
127
+ status = payment.check_transaction_status("txn_001")
128
+ print(status["response_data"]["status"])
129
+
130
+ # Account lookup (single)
131
+ info = payment.payment_account_lookup(pan="0541840988", nw="MTN")
132
+ print(info["response_data"]["name"])
133
+
134
+ # Account lookup (batch)
135
+ accounts = payment.payment_account_lookup(accounts=[
136
+ {"pan": "0541840988", "nw": "MTN"},
137
+ {"pan": "0201234567", "nw": "VOD"},
138
+ ])
139
+ ```
140
+
141
+ ### Advanced options
142
+
143
+ Both `InitSMS` and `InitPayment` accept `timeout`, `retry_count`, and `retry_delay`:
144
+
145
+ ```python
146
+ sms = InitSMS(timeout=10, retry_count=3, retry_delay=0.5)
147
+ ```
148
+
149
+ ## Error Handling
150
+
151
+ ```python
152
+ from mobiska import (
153
+ AuthenticationError,
154
+ NotFoundError,
155
+ RateLimitError,
156
+ ValidationError,
157
+ APIError,
158
+ )
159
+
160
+ try:
161
+ payment.make_payment(...)
162
+ except ValidationError as e:
163
+ print(f"Invalid input: {e}")
164
+ except AuthenticationError:
165
+ print("Check your credentials.")
166
+ except RateLimitError:
167
+ print("Slow down — rate limit hit.")
168
+ except APIError as e:
169
+ print(f"Server error ({e.status_code}): {e}")
170
+ ```
171
+
172
+ ## Development
173
+
174
+ ```bash
175
+ # Create a virtual environment and install
176
+ python3 -m venv .venv
177
+ source .venv/bin/activate
178
+ pip install -e ".[dev]"
179
+
180
+ # Run tests
181
+ pytest
182
+
183
+ # Format code
184
+ black mobiska tests
185
+
186
+ # Lint
187
+ ruff check mobiska tests
188
+ ```
189
+
190
+ ## License
191
+
192
+ MIT
193
+
194
+ # Mobiska Python SDK
195
+
196
+ The official Python SDK for the Mobiska REST API.
197
+
198
+ ## Installation
199
+
200
+ ```bash
201
+ pip install mobiska
202
+ ```
203
+
204
+ ## Quick Start
205
+
206
+ ```python
207
+ from mobiska import MobiskaClient
208
+
209
+ client = MobiskaClient(api_key="your-api-key")
210
+
211
+ # GET request
212
+ users = client.get("/users")
213
+
214
+ # POST request
215
+ new_user = client.post("/users", json={"name": "Alice"})
216
+
217
+ # PATCH request
218
+ client.patch(f"/users/{new_user['id']}", json={"name": "Alice Updated"})
219
+
220
+ # DELETE request
221
+ client.delete(f"/users/{new_user['id']}")
222
+ ```
223
+
224
+ ## Error Handling
225
+
226
+ ```python
227
+ from mobiska import MobiskaClient, AuthenticationError, NotFoundError, RateLimitError
228
+
229
+ try:
230
+ client.get("/users/999")
231
+ except AuthenticationError:
232
+ print("Check your API key.")
233
+ except NotFoundError:
234
+ print("Resource not found.")
235
+ except RateLimitError:
236
+ print("Slow down — rate limit hit.")
237
+ ```
238
+
239
+ ## Development
240
+
241
+ ```bash
242
+ # Install with dev dependencies
243
+ pip install -e ".[dev]"
244
+
245
+ # Run tests
246
+ pytest
247
+
248
+ # Format code
249
+ black mobiska tests
250
+
251
+ # Lint
252
+ ruff check mobiska tests
253
+ ```
254
+
255
+ ## License
256
+
257
+ MIT
@@ -0,0 +1,209 @@
1
+ # Mobiska Python SDK
2
+
3
+ The official Python SDK for the Mobiska REST API — payments and SMS for businesses across Africa.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install mobiska
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ### Configuration
14
+
15
+ Credentials can be provided via keyword arguments **or** environment variables:
16
+
17
+ ```bash
18
+ MOBISKA_USER_NAME=your_client_key
19
+ MOBISKA_PASSWORD=your_secret_key
20
+ MOBISKA_SERVICE_ID=1
21
+ MOBISKA_SMS_SENDER_ID=YourSender # SMS only
22
+ MOBISKA_API_URL=https://api.mobiska.com # optional, this is the default
23
+ ```
24
+
25
+ ### SMS
26
+
27
+ ```python
28
+ from mobiska import InitSMS
29
+
30
+ # Uses env vars when no arguments are passed
31
+ sms = InitSMS()
32
+
33
+ # Or pass credentials explicitly
34
+ sms = InitSMS(
35
+ username="your_client_key",
36
+ password="your_secret_key",
37
+ service_id=1,
38
+ sender_id="YourSender",
39
+ )
40
+
41
+ # Send a message
42
+ response = sms.send_sms("0540000000", "Welcome to Mobiska!")
43
+ print(response["response_code"])
44
+
45
+ # Send to multiple recipients
46
+ sms.send_sms(["0540000000", "0200000000"], "Batch message")
47
+
48
+ # Check balance
49
+ balance = sms.check_balance()
50
+ print(balance["response_data"]["sms_balance"])
51
+ ```
52
+
53
+ ### Payments
54
+
55
+ ```python
56
+ from mobiska import InitPayment
57
+
58
+ payment = InitPayment(
59
+ username="your_client_key",
60
+ password="your_secret_key",
61
+ service_id=2,
62
+ )
63
+
64
+ # Make a payment
65
+ result = payment.make_payment(
66
+ reference="Order #123",
67
+ nickname="MyShop",
68
+ transaction_id="txn_001",
69
+ trans_type="CTM",
70
+ customer_number="0541840988",
71
+ nw="MTN",
72
+ amount=100,
73
+ payment_option="MOM",
74
+ callback_url="https://example.com/webhook",
75
+ currency_code="GHS",
76
+ )
77
+
78
+ # Check transaction status
79
+ status = payment.check_transaction_status("txn_001")
80
+ print(status["response_data"]["status"])
81
+
82
+ # Account lookup (single)
83
+ info = payment.payment_account_lookup(pan="0541840988", nw="MTN")
84
+ print(info["response_data"]["name"])
85
+
86
+ # Account lookup (batch)
87
+ accounts = payment.payment_account_lookup(accounts=[
88
+ {"pan": "0541840988", "nw": "MTN"},
89
+ {"pan": "0201234567", "nw": "VOD"},
90
+ ])
91
+ ```
92
+
93
+ ### Advanced options
94
+
95
+ Both `InitSMS` and `InitPayment` accept `timeout`, `retry_count`, and `retry_delay`:
96
+
97
+ ```python
98
+ sms = InitSMS(timeout=10, retry_count=3, retry_delay=0.5)
99
+ ```
100
+
101
+ ## Error Handling
102
+
103
+ ```python
104
+ from mobiska import (
105
+ AuthenticationError,
106
+ NotFoundError,
107
+ RateLimitError,
108
+ ValidationError,
109
+ APIError,
110
+ )
111
+
112
+ try:
113
+ payment.make_payment(...)
114
+ except ValidationError as e:
115
+ print(f"Invalid input: {e}")
116
+ except AuthenticationError:
117
+ print("Check your credentials.")
118
+ except RateLimitError:
119
+ print("Slow down — rate limit hit.")
120
+ except APIError as e:
121
+ print(f"Server error ({e.status_code}): {e}")
122
+ ```
123
+
124
+ ## Development
125
+
126
+ ```bash
127
+ # Create a virtual environment and install
128
+ python3 -m venv .venv
129
+ source .venv/bin/activate
130
+ pip install -e ".[dev]"
131
+
132
+ # Run tests
133
+ pytest
134
+
135
+ # Format code
136
+ black mobiska tests
137
+
138
+ # Lint
139
+ ruff check mobiska tests
140
+ ```
141
+
142
+ ## License
143
+
144
+ MIT
145
+
146
+ # Mobiska Python SDK
147
+
148
+ The official Python SDK for the Mobiska REST API.
149
+
150
+ ## Installation
151
+
152
+ ```bash
153
+ pip install mobiska
154
+ ```
155
+
156
+ ## Quick Start
157
+
158
+ ```python
159
+ from mobiska import MobiskaClient
160
+
161
+ client = MobiskaClient(api_key="your-api-key")
162
+
163
+ # GET request
164
+ users = client.get("/users")
165
+
166
+ # POST request
167
+ new_user = client.post("/users", json={"name": "Alice"})
168
+
169
+ # PATCH request
170
+ client.patch(f"/users/{new_user['id']}", json={"name": "Alice Updated"})
171
+
172
+ # DELETE request
173
+ client.delete(f"/users/{new_user['id']}")
174
+ ```
175
+
176
+ ## Error Handling
177
+
178
+ ```python
179
+ from mobiska import MobiskaClient, AuthenticationError, NotFoundError, RateLimitError
180
+
181
+ try:
182
+ client.get("/users/999")
183
+ except AuthenticationError:
184
+ print("Check your API key.")
185
+ except NotFoundError:
186
+ print("Resource not found.")
187
+ except RateLimitError:
188
+ print("Slow down — rate limit hit.")
189
+ ```
190
+
191
+ ## Development
192
+
193
+ ```bash
194
+ # Install with dev dependencies
195
+ pip install -e ".[dev]"
196
+
197
+ # Run tests
198
+ pytest
199
+
200
+ # Format code
201
+ black mobiska tests
202
+
203
+ # Lint
204
+ ruff check mobiska tests
205
+ ```
206
+
207
+ ## License
208
+
209
+ MIT
@@ -0,0 +1,95 @@
1
+ """Mobiska Python SDK.
2
+
3
+ Public API::
4
+
5
+ from mobiska import InitSMS, InitPayment
6
+
7
+ sms = InitSMS(username=…, password=…, service_id=…, sender_id=…)
8
+ payment = InitPayment(username=…, password=…, service_id=…)
9
+
10
+ Both factories also accept ``timeout``, ``retry_count`` and ``retry_delay``
11
+ keyword arguments. When called with no arguments they read credentials from
12
+ environment variables (``MOBISKA_USER_NAME``, ``MOBISKA_PASSWORD``,
13
+ ``MOBISKA_SERVICE_ID``, ``MOBISKA_SMS_SENDER_ID``, ``MOBISKA_API_URL``).
14
+ """
15
+
16
+ from typing import Optional
17
+
18
+ from .client import BaseClient
19
+ from .exceptions import (
20
+ APIError,
21
+ AuthenticationError,
22
+ MobiskaError,
23
+ NotFoundError,
24
+ RateLimitError,
25
+ ValidationError,
26
+ )
27
+ from .resources import PaymentClient, SMSClient
28
+
29
+ __version__ = "0.1.0"
30
+
31
+ __all__ = [
32
+ "InitSMS",
33
+ "InitPayment",
34
+ "SMSClient",
35
+ "PaymentClient",
36
+ "BaseClient",
37
+ "MobiskaError",
38
+ "AuthenticationError",
39
+ "NotFoundError",
40
+ "RateLimitError",
41
+ "ValidationError",
42
+ "APIError",
43
+ ]
44
+
45
+
46
+ def InitSMS(
47
+ username: Optional[str] = None,
48
+ password: Optional[str] = None,
49
+ service_id: Optional[int] = None,
50
+ sender_id: Optional[str] = None,
51
+ api_url: Optional[str] = None,
52
+ timeout: int = 30,
53
+ retry_count: int = 0,
54
+ retry_delay: float = 0.5,
55
+ ) -> SMSClient:
56
+ """Create and return an :class:`SMSClient`.
57
+
58
+ All arguments are optional — when omitted the values are read from
59
+ environment variables.
60
+ """
61
+ return SMSClient(
62
+ username=username,
63
+ password=password,
64
+ service_id=service_id,
65
+ sender_id=sender_id,
66
+ api_url=api_url,
67
+ timeout=timeout,
68
+ retry_count=retry_count,
69
+ retry_delay=retry_delay,
70
+ )
71
+
72
+
73
+ def InitPayment(
74
+ username: Optional[str] = None,
75
+ password: Optional[str] = None,
76
+ service_id: Optional[int] = None,
77
+ api_url: Optional[str] = None,
78
+ timeout: int = 30,
79
+ retry_count: int = 0,
80
+ retry_delay: float = 0.5,
81
+ ) -> PaymentClient:
82
+ """Create and return a :class:`PaymentClient`.
83
+
84
+ All arguments are optional — when omitted the values are read from
85
+ environment variables.
86
+ """
87
+ return PaymentClient(
88
+ username=username,
89
+ password=password,
90
+ service_id=service_id,
91
+ api_url=api_url,
92
+ timeout=timeout,
93
+ retry_count=retry_count,
94
+ retry_delay=retry_delay,
95
+ )
@@ -0,0 +1,32 @@
1
+ """Basic Authentication helper for the Mobiska API.
2
+
3
+ Mobiska uses HTTP Basic Auth: the client_key (username) and secret_key
4
+ (password) are combined as ``username:password``, base64-encoded, and sent
5
+ in the ``Authorization`` header prefixed with ``Basic``.
6
+ """
7
+
8
+ import base64
9
+ from typing import Dict
10
+
11
+
12
+ class BasicAuth:
13
+ """Generates the Basic-auth Authorization header for API requests."""
14
+
15
+ def __init__(self, username: str, password: str):
16
+ if not username or not password:
17
+ raise ValueError("username and password must not be empty.")
18
+ self.username = username
19
+ self.password = password
20
+
21
+ @property
22
+ def _encoded(self) -> str:
23
+ raw = f"{self.username}:{self.password}".encode("utf-8")
24
+ return base64.b64encode(raw).decode("ascii")
25
+
26
+ def get_headers(self) -> Dict[str, str]:
27
+ """Return the auth headers to attach to every request."""
28
+ return {
29
+ "Authorization": f"Basic {self._encoded}",
30
+ "Content-Type": "application/json",
31
+ "Accept": "application/json",
32
+ }