kra-etims-sdk 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl
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.
- kra_etims_sdk/base_client.py +2 -1
- kra_etims_sdk/client.py +6 -6
- kra_etims_sdk/schemas.py +1 -1
- {kra_etims_sdk-0.1.0.dist-info → kra_etims_sdk-0.1.1.dist-info}/METADATA +10 -11
- kra_etims_sdk-0.1.1.dist-info/RECORD +12 -0
- kra_etims_sdk-0.1.0.dist-info/RECORD +0 -12
- {kra_etims_sdk-0.1.0.dist-info → kra_etims_sdk-0.1.1.dist-info}/WHEEL +0 -0
- {kra_etims_sdk-0.1.0.dist-info → kra_etims_sdk-0.1.1.dist-info}/licenses/LICENSE +0 -0
- {kra_etims_sdk-0.1.0.dist-info → kra_etims_sdk-0.1.1.dist-info}/top_level.txt +0 -0
kra_etims_sdk/base_client.py
CHANGED
|
@@ -32,10 +32,11 @@ class BaseClient:
|
|
|
32
32
|
def _request(self, method, endpoint, data):
|
|
33
33
|
url = self.base_url() + endpoint
|
|
34
34
|
headers = self._headers(endpoint)
|
|
35
|
+
print(url, headers, data)
|
|
35
36
|
return requests.request(method, url, json=data, headers=headers, timeout=30)
|
|
36
37
|
|
|
37
38
|
def _headers(self, endpoint):
|
|
38
|
-
if endpoint.endswith("/
|
|
39
|
+
if endpoint.endswith("/selectInitOsdcInfo"):
|
|
39
40
|
return {
|
|
40
41
|
"Authorization": f"Bearer {self.auth.token()}",
|
|
41
42
|
"Content-Type": "application/json",
|
kra_etims_sdk/client.py
CHANGED
|
@@ -11,12 +11,12 @@ class EtimsClient(BaseClient):
|
|
|
11
11
|
def _validate(self, data: dict, schema: str) -> dict:
|
|
12
12
|
return self.validator.validate(data, schema)
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return self.post("
|
|
14
|
+
def select_init_osdc_info(self, data: dict) -> dict:
|
|
15
|
+
"""
|
|
16
|
+
Initialize the OSCU device with KRA.
|
|
17
|
+
Returns cmcKey and device information.
|
|
18
|
+
"""
|
|
19
|
+
return self.post("selectInitOsdcInfo", self._validate(data, "initialization"))
|
|
20
20
|
|
|
21
21
|
# -----------------------------
|
|
22
22
|
# BASIC DATA ENDPOINTS
|
kra_etims_sdk/schemas.py
CHANGED
|
@@ -14,7 +14,7 @@ from pydantic import (
|
|
|
14
14
|
# =========================================================
|
|
15
15
|
|
|
16
16
|
TIN = Annotated[str, StringConstraints(min_length=1, max_length=20)]
|
|
17
|
-
BHF = Annotated[str, StringConstraints(min_length=1, max_length=
|
|
17
|
+
BHF = Annotated[str, StringConstraints(min_length=1, max_length=20)]
|
|
18
18
|
|
|
19
19
|
YN = Annotated[str, StringConstraints(pattern="^[YN]$")]
|
|
20
20
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kra-etims-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Python SDK for KRA eTIMS OSCU API
|
|
5
5
|
Author: Emmanuel Bartile
|
|
6
6
|
License: MIT
|
|
@@ -41,7 +41,7 @@ Dynamic: license-file
|
|
|
41
41
|
|
|
42
42
|
A production-ready **Python SDK** for integrating with the Kenya Revenue Authority (KRA) **eTIMS OSCU** (Online Sales Control Unit) API. Built to match the official Postman collection specifications with strict header compliance, token management, and comprehensive Pydantic validation.
|
|
43
43
|
|
|
44
|
-
> ⚠️ **Critical Note**: This SDK implements the **new OSCU specification** (KRA-hosted), *not* the
|
|
44
|
+
> ⚠️ **Critical Note**: This SDK implements the **new OSCU specification** (KRA-hosted), *not* the VSCU eTIMS API. OSCU requires device registration, headers, and `cmcKey` lifecycle management.
|
|
45
45
|
|
|
46
46
|
## Author
|
|
47
47
|
**Bartile Emmanuel**
|
|
@@ -73,15 +73,15 @@ A production-ready **Python SDK** for integrating with the Kenya Revenue Authori
|
|
|
73
73
|
|
|
74
74
|
## Introduction to eTIMS OSCU
|
|
75
75
|
|
|
76
|
-
KRA's **Electronic Tax Invoice Management System (eTIMS)** uses **OSCU** (Online Sales Control Unit) – a KRA-hosted software module that validates and signs tax invoices in real-time before issuance. Unlike
|
|
76
|
+
KRA's **Electronic Tax Invoice Management System (eTIMS)** uses **OSCU** (Online Sales Control Unit) – a KRA-hosted software module that validates and signs tax invoices in real-time before issuance. Unlike VSCU, OSCU requires:
|
|
77
77
|
|
|
78
78
|
- Pre-registered device serial numbers (`dvcSrlNo`)
|
|
79
79
|
- Communication key (`cmcKey`) lifecycle management
|
|
80
80
|
- Strict payload schema compliance per KRA specifications
|
|
81
81
|
|
|
82
|
-
### OSCU vs
|
|
82
|
+
### OSCU vs VSCU eTIMS
|
|
83
83
|
|
|
84
|
-
| Feature | OSCU (This SDK) |
|
|
84
|
+
| Feature | OSCU (This SDK) | VSCU eTIMS |
|
|
85
85
|
|---------|-----------------|--------------|
|
|
86
86
|
| **Hosting** | KRA-hosted (cloud) | Self-hosted (on-premise) |
|
|
87
87
|
| **Device Registration** | Mandatory pre-registration | Not required |
|
|
@@ -198,7 +198,7 @@ Before integration, you **MUST** complete these prerequisites:
|
|
|
198
198
|
### 2. Communication Key Lifecycle
|
|
199
199
|
```python
|
|
200
200
|
# 1. Initialize FIRST (returns cmcKey)
|
|
201
|
-
response = etims.
|
|
201
|
+
response = etims.select_init_osdc_info({
|
|
202
202
|
"tin": config.oscu["tin"],
|
|
203
203
|
"bhfId": config.oscu["bhf_id"],
|
|
204
204
|
"dvcSrlNo": "dvcv1130", # KRA-approved serial
|
|
@@ -316,7 +316,7 @@ config = KraEtimsConfig(
|
|
|
316
316
|
|
|
317
317
|
endpoints={
|
|
318
318
|
# INITIALIZATION (ONLY endpoint without tin/bhfId/cmcKey headers)
|
|
319
|
-
"
|
|
319
|
+
"selectInitOsdcInfo": "/selectInitOsdcInfo",
|
|
320
320
|
|
|
321
321
|
# DATA MANAGEMENT
|
|
322
322
|
"selectCodeList": "/selectCodeList",
|
|
@@ -386,12 +386,11 @@ except AuthenticationException as e:
|
|
|
386
386
|
try:
|
|
387
387
|
# ⚠️ MUST use KRA-approved device serial (NOT dynamic!)
|
|
388
388
|
# Common sandbox test value (if pre-provisioned by KRA):
|
|
389
|
-
device_serial = "dvcv1130" # REPLACE with your approved serial
|
|
390
389
|
|
|
391
|
-
response = etims.
|
|
390
|
+
response = etims.select_init_info({
|
|
392
391
|
"tin": config.oscu["tin"],
|
|
393
392
|
"bhfId": config.oscu["bhf_id"],
|
|
394
|
-
"dvcSrlNo": device_serial
|
|
393
|
+
"dvcSrlNo": config.oscu["device_serial"],
|
|
395
394
|
})
|
|
396
395
|
|
|
397
396
|
# Extract cmcKey (sandbox returns at root level)
|
|
@@ -506,7 +505,7 @@ except ApiException as e:
|
|
|
506
505
|
|
|
507
506
|
| Category | Purpose | Endpoints |
|
|
508
507
|
|----------|---------|-----------|
|
|
509
|
-
| **Initialization** | Device registration & cmcKey acquisition | `
|
|
508
|
+
| **Initialization** | Device registration & cmcKey acquisition | `select_init_info` |
|
|
510
509
|
| **Data Management** | Retrieve standard codes & master data | `select_code_list`, `select_item_cls_list`, `select_bhf_list`, `select_taxpayer_info`, `select_customer_list`, `select_notice_list` |
|
|
511
510
|
| **Branch Management** | Manage branch offices & users | `branch_insurance_info`, `branch_user_account`, `branch_send_customer_info` |
|
|
512
511
|
| **Item Management** | Item master data | `save_item`, `item_info` |
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
kra_etims_sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
kra_etims_sdk/auth.py,sha256=_fRE1QhRWjOsHrd8ds9RAu_0kPrR4XFsl8KYrLf1avk,1812
|
|
3
|
+
kra_etims_sdk/base_client.py,sha256=oWZhLWj7PCECW_tGim6U7venX7_OerkvePIyvXw0OCg,2266
|
|
4
|
+
kra_etims_sdk/client.py,sha256=CEfk-DbVbTmSi-Q6pAgS3MHnofb5ejwnyYN-btXyNHA,3853
|
|
5
|
+
kra_etims_sdk/exceptions.py,sha256=Kcwvh7dbsxZ5X2iHcW9p8bxWai2FiZHL6Jb7904u9HE,630
|
|
6
|
+
kra_etims_sdk/schemas.py,sha256=mZEUAIDwrlG8NaE6rpPMHXFoNU2q2NOLj7YBM-gICAc,4585
|
|
7
|
+
kra_etims_sdk/validator.py,sha256=JDBZo5GXuczibIia3XSE_ytjJ5OzqQ8e7QT9Fh7hmtk,1168
|
|
8
|
+
kra_etims_sdk-0.1.1.dist-info/licenses/LICENSE,sha256=Fl2vp3H5372qSizz8VOT8f3H1bSxSqY-YZ8Qb4N25pM,1067
|
|
9
|
+
kra_etims_sdk-0.1.1.dist-info/METADATA,sha256=cNaiUwSzxQ_sJs7dR7aK6Al21-1cJgx345IzgiL8Ya0,29402
|
|
10
|
+
kra_etims_sdk-0.1.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
11
|
+
kra_etims_sdk-0.1.1.dist-info/top_level.txt,sha256=LRqz__wcOsq5Ds_evpPLZ9yHdxvIDCIu_oGSW3fRcTY,14
|
|
12
|
+
kra_etims_sdk-0.1.1.dist-info/RECORD,,
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
kra_etims_sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
kra_etims_sdk/auth.py,sha256=_fRE1QhRWjOsHrd8ds9RAu_0kPrR4XFsl8KYrLf1avk,1812
|
|
3
|
-
kra_etims_sdk/base_client.py,sha256=Wn2esjMcjXsw6wPHIdXp0wmvoKSXWfMg7DLFQpsM8PA,2224
|
|
4
|
-
kra_etims_sdk/client.py,sha256=3LrzXUupVMKQ3efupWJr6_wpK-RAjCYgEGYQFBoJHNM,3861
|
|
5
|
-
kra_etims_sdk/exceptions.py,sha256=Kcwvh7dbsxZ5X2iHcW9p8bxWai2FiZHL6Jb7904u9HE,630
|
|
6
|
-
kra_etims_sdk/schemas.py,sha256=InPS4VWmL0ssUKxUvVzpLjbivXARDb_I0iVuCdjiEoA,4585
|
|
7
|
-
kra_etims_sdk/validator.py,sha256=JDBZo5GXuczibIia3XSE_ytjJ5OzqQ8e7QT9Fh7hmtk,1168
|
|
8
|
-
kra_etims_sdk-0.1.0.dist-info/licenses/LICENSE,sha256=Fl2vp3H5372qSizz8VOT8f3H1bSxSqY-YZ8Qb4N25pM,1067
|
|
9
|
-
kra_etims_sdk-0.1.0.dist-info/METADATA,sha256=HgxEf3SEo_Y__2D8maWVDQbZ8u7fs8tEOz3vREV81co,29440
|
|
10
|
-
kra_etims_sdk-0.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
11
|
-
kra_etims_sdk-0.1.0.dist-info/top_level.txt,sha256=LRqz__wcOsq5Ds_evpPLZ9yHdxvIDCIu_oGSW3fRcTY,14
|
|
12
|
-
kra_etims_sdk-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|