chamapay 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.
- chamapay-1.0.0/PKG-INFO +97 -0
- chamapay-1.0.0/README.md +74 -0
- chamapay-1.0.0/chamapay/__init__.py +12 -0
- chamapay-1.0.0/chamapay/client.py +36 -0
- chamapay-1.0.0/chamapay/errors.py +27 -0
- chamapay-1.0.0/chamapay/http_client.py +85 -0
- chamapay-1.0.0/chamapay/resources/__init__.py +33 -0
- chamapay-1.0.0/chamapay/resources/accounts.py +4 -0
- chamapay-1.0.0/chamapay/resources/audit.py +3 -0
- chamapay-1.0.0/chamapay/resources/contributions.py +7 -0
- chamapay-1.0.0/chamapay/resources/dividends.py +3 -0
- chamapay-1.0.0/chamapay/resources/document_reminders.py +3 -0
- chamapay-1.0.0/chamapay/resources/documents.py +3 -0
- chamapay-1.0.0/chamapay/resources/election_notices.py +3 -0
- chamapay-1.0.0/chamapay/resources/fines.py +4 -0
- chamapay-1.0.0/chamapay/resources/liabilities.py +4 -0
- chamapay-1.0.0/chamapay/resources/loans.py +5 -0
- chamapay-1.0.0/chamapay/resources/meetings.py +4 -0
- chamapay-1.0.0/chamapay/resources/members.py +7 -0
- chamapay-1.0.0/chamapay/resources/projects.py +4 -0
- chamapay-1.0.0/chamapay/resources/reports.py +3 -0
- chamapay-1.0.0/chamapay/resources/welfare.py +3 -0
- chamapay-1.0.0/chamapay.egg-info/PKG-INFO +97 -0
- chamapay-1.0.0/chamapay.egg-info/SOURCES.txt +27 -0
- chamapay-1.0.0/chamapay.egg-info/dependency_links.txt +1 -0
- chamapay-1.0.0/chamapay.egg-info/requires.txt +1 -0
- chamapay-1.0.0/chamapay.egg-info/top_level.txt +1 -0
- chamapay-1.0.0/pyproject.toml +34 -0
- chamapay-1.0.0/setup.cfg +4 -0
chamapay-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: chamapay
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Official Python SDK for ChamaPay API — Financial Infrastructure for African Savings Groups
|
|
5
|
+
Author-email: ChamaPay <api-support@chamapay.co.ke>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://chamapay.co.ke
|
|
8
|
+
Project-URL: Documentation, https://api.chamapay.co.ke/docs
|
|
9
|
+
Project-URL: Source, https://github.com/chamapay/chamapay-python
|
|
10
|
+
Keywords: chamapay,sacco,savings,mpesa,africa,fintech
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
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
|
+
Requires-Dist: requests>=2.25.0
|
|
23
|
+
|
|
24
|
+
# ChamaPay Python SDK
|
|
25
|
+
|
|
26
|
+
Official Python SDK for the ChamaPay API.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install chamapay
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from chamapay import ChamaPay
|
|
38
|
+
|
|
39
|
+
api = ChamaPay('cpk_live_your_api_key', 'your_api_secret')
|
|
40
|
+
|
|
41
|
+
# List members
|
|
42
|
+
members = api.members.list(status='Active', page=1, limit=20)
|
|
43
|
+
|
|
44
|
+
# Create a contribution (idempotent)
|
|
45
|
+
contribution = api.contributions.create(
|
|
46
|
+
{'member_id': 'MFT001', 'amount': 5000},
|
|
47
|
+
idempotency_key='550e8400-e29b-41d4-a716-446655440000'
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Get loan details
|
|
51
|
+
loan = api.loans.get('LN001')
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## API Reference
|
|
55
|
+
|
|
56
|
+
| Resource | Methods |
|
|
57
|
+
|--------------------|--------------------------------------------|
|
|
58
|
+
| members | list, get, create, update, delete |
|
|
59
|
+
| contributions | list, get, create (with idempotency key) |
|
|
60
|
+
| loans | list, get, create |
|
|
61
|
+
| fines | list, create |
|
|
62
|
+
| meetings | list, create |
|
|
63
|
+
| projects | list, create |
|
|
64
|
+
| accounts | list, get |
|
|
65
|
+
| welfare | list |
|
|
66
|
+
| dividends | list |
|
|
67
|
+
| documents | list |
|
|
68
|
+
| election_notices | list |
|
|
69
|
+
| document_reminders | list |
|
|
70
|
+
| audit | list |
|
|
71
|
+
| liabilities | list, create |
|
|
72
|
+
| reports | get |
|
|
73
|
+
|
|
74
|
+
## Error Handling
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from chamapay import ChamaPayError, ValidationError, RateLimitError
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
api.members.create({...})
|
|
81
|
+
except ValidationError as e:
|
|
82
|
+
print(f"Validation failed: {e.details}")
|
|
83
|
+
except RateLimitError as e:
|
|
84
|
+
print(f"Rate limited. Retry after {e.retry_after}s")
|
|
85
|
+
except ChamaPayError as e:
|
|
86
|
+
print(f"API Error [{e.code}]: {e.message}")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Publishing
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pip install build twine
|
|
93
|
+
python -m build
|
|
94
|
+
twine upload dist/*
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Requires a PyPI account with access to the `chamapay` package.
|
chamapay-1.0.0/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# ChamaPay Python SDK
|
|
2
|
+
|
|
3
|
+
Official Python SDK for the ChamaPay API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install chamapay
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from chamapay import ChamaPay
|
|
15
|
+
|
|
16
|
+
api = ChamaPay('cpk_live_your_api_key', 'your_api_secret')
|
|
17
|
+
|
|
18
|
+
# List members
|
|
19
|
+
members = api.members.list(status='Active', page=1, limit=20)
|
|
20
|
+
|
|
21
|
+
# Create a contribution (idempotent)
|
|
22
|
+
contribution = api.contributions.create(
|
|
23
|
+
{'member_id': 'MFT001', 'amount': 5000},
|
|
24
|
+
idempotency_key='550e8400-e29b-41d4-a716-446655440000'
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Get loan details
|
|
28
|
+
loan = api.loans.get('LN001')
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## API Reference
|
|
32
|
+
|
|
33
|
+
| Resource | Methods |
|
|
34
|
+
|--------------------|--------------------------------------------|
|
|
35
|
+
| members | list, get, create, update, delete |
|
|
36
|
+
| contributions | list, get, create (with idempotency key) |
|
|
37
|
+
| loans | list, get, create |
|
|
38
|
+
| fines | list, create |
|
|
39
|
+
| meetings | list, create |
|
|
40
|
+
| projects | list, create |
|
|
41
|
+
| accounts | list, get |
|
|
42
|
+
| welfare | list |
|
|
43
|
+
| dividends | list |
|
|
44
|
+
| documents | list |
|
|
45
|
+
| election_notices | list |
|
|
46
|
+
| document_reminders | list |
|
|
47
|
+
| audit | list |
|
|
48
|
+
| liabilities | list, create |
|
|
49
|
+
| reports | get |
|
|
50
|
+
|
|
51
|
+
## Error Handling
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from chamapay import ChamaPayError, ValidationError, RateLimitError
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
api.members.create({...})
|
|
58
|
+
except ValidationError as e:
|
|
59
|
+
print(f"Validation failed: {e.details}")
|
|
60
|
+
except RateLimitError as e:
|
|
61
|
+
print(f"Rate limited. Retry after {e.retry_after}s")
|
|
62
|
+
except ChamaPayError as e:
|
|
63
|
+
print(f"API Error [{e.code}]: {e.message}")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Publishing
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install build twine
|
|
70
|
+
python -m build
|
|
71
|
+
twine upload dist/*
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Requires a PyPI account with access to the `chamapay` package.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from .client import ChamaPay
|
|
2
|
+
from .errors import ChamaPayError, AuthenticationError, RateLimitError, ValidationError, NotFoundError, ServerError
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"ChamaPay",
|
|
6
|
+
"ChamaPayError",
|
|
7
|
+
"AuthenticationError",
|
|
8
|
+
"RateLimitError",
|
|
9
|
+
"ValidationError",
|
|
10
|
+
"NotFoundError",
|
|
11
|
+
"ServerError",
|
|
12
|
+
]
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from .http_client import ChamaPayClient
|
|
2
|
+
from .resources.members import MembersResource
|
|
3
|
+
from .resources.contributions import ContributionsResource
|
|
4
|
+
from .resources.loans import LoansResource
|
|
5
|
+
from .resources.fines import FinesResource
|
|
6
|
+
from .resources.meetings import MeetingsResource
|
|
7
|
+
from .resources.projects import ProjectsResource
|
|
8
|
+
from .resources.accounts import AccountsResource
|
|
9
|
+
from .resources.welfare import WelfareResource
|
|
10
|
+
from .resources.dividends import DividendsResource
|
|
11
|
+
from .resources.documents import DocumentsResource
|
|
12
|
+
from .resources.election_notices import ElectionNoticesResource
|
|
13
|
+
from .resources.document_reminders import DocumentRemindersResource
|
|
14
|
+
from .resources.audit import AuditResource
|
|
15
|
+
from .resources.liabilities import LiabilitiesResource
|
|
16
|
+
from .resources.reports import ReportsResource
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ChamaPay:
|
|
20
|
+
def __init__(self, api_key, api_secret, base_url=None, timeout=None):
|
|
21
|
+
client = ChamaPayClient(api_key, api_secret, base_url, timeout)
|
|
22
|
+
self.members = MembersResource(client)
|
|
23
|
+
self.contributions = ContributionsResource(client)
|
|
24
|
+
self.loans = LoansResource(client)
|
|
25
|
+
self.fines = FinesResource(client)
|
|
26
|
+
self.meetings = MeetingsResource(client)
|
|
27
|
+
self.projects = ProjectsResource(client)
|
|
28
|
+
self.accounts = AccountsResource(client)
|
|
29
|
+
self.welfare = WelfareResource(client)
|
|
30
|
+
self.dividends = DividendsResource(client)
|
|
31
|
+
self.documents = DocumentsResource(client)
|
|
32
|
+
self.election_notices = ElectionNoticesResource(client)
|
|
33
|
+
self.document_reminders = DocumentRemindersResource(client)
|
|
34
|
+
self.audit = AuditResource(client)
|
|
35
|
+
self.liabilities = LiabilitiesResource(client)
|
|
36
|
+
self.reports = ReportsResource(client)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
class ChamaPayError(Exception):
|
|
2
|
+
def __init__(self, message, status=0, code=None, details=None):
|
|
3
|
+
super().__init__(message)
|
|
4
|
+
self.status = status
|
|
5
|
+
self.code = code
|
|
6
|
+
self.details = details or {}
|
|
7
|
+
|
|
8
|
+
class AuthenticationError(ChamaPayError):
|
|
9
|
+
def __init__(self, message, details=None):
|
|
10
|
+
super().__init__(message, 401, "authentication_error", details)
|
|
11
|
+
|
|
12
|
+
class RateLimitError(ChamaPayError):
|
|
13
|
+
def __init__(self, message, retry_after=30, details=None):
|
|
14
|
+
super().__init__(message, 429, "rate_limit_error", details)
|
|
15
|
+
self.retry_after = retry_after
|
|
16
|
+
|
|
17
|
+
class ValidationError(ChamaPayError):
|
|
18
|
+
def __init__(self, message, details=None):
|
|
19
|
+
super().__init__(message, 422, "validation_error", details)
|
|
20
|
+
|
|
21
|
+
class NotFoundError(ChamaPayError):
|
|
22
|
+
def __init__(self, message, details=None):
|
|
23
|
+
super().__init__(message, 404, "not_found", details)
|
|
24
|
+
|
|
25
|
+
class ServerError(ChamaPayError):
|
|
26
|
+
def __init__(self, message, details=None):
|
|
27
|
+
super().__init__(message, 500, "server_error", details)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
|
|
3
|
+
from .errors import (
|
|
4
|
+
ChamaPayError,
|
|
5
|
+
AuthenticationError,
|
|
6
|
+
RateLimitError,
|
|
7
|
+
ValidationError,
|
|
8
|
+
NotFoundError,
|
|
9
|
+
ServerError,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
BASE_URL = "https://api.chamapay.co.ke/v1"
|
|
13
|
+
DEFAULT_TIMEOUT = 30
|
|
14
|
+
|
|
15
|
+
_ERROR_MAP = {
|
|
16
|
+
401: AuthenticationError,
|
|
17
|
+
404: NotFoundError,
|
|
18
|
+
422: ValidationError,
|
|
19
|
+
429: RateLimitError,
|
|
20
|
+
500: ServerError,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ChamaPayClient:
|
|
25
|
+
def __init__(self, api_key, api_secret, base_url=None, timeout=None):
|
|
26
|
+
if not api_key or not api_secret:
|
|
27
|
+
raise ChamaPayError("API key and secret are required")
|
|
28
|
+
self.api_key = api_key
|
|
29
|
+
self.api_secret = api_secret
|
|
30
|
+
self.base_url = (base_url or BASE_URL).rstrip("/")
|
|
31
|
+
self.timeout = timeout or DEFAULT_TIMEOUT
|
|
32
|
+
self._session = requests.Session()
|
|
33
|
+
self._session.headers.update({
|
|
34
|
+
"Authorization": f"Bearer {self.api_key}:{self.api_secret}",
|
|
35
|
+
"Content-Type": "application/json",
|
|
36
|
+
"User-Agent": "chamapay-python/1.0.0",
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
def _request(self, method, path, **kwargs):
|
|
40
|
+
url = f"{self.base_url}/{path.lstrip('/')}"
|
|
41
|
+
params = kwargs.get("query")
|
|
42
|
+
body = kwargs.get("body")
|
|
43
|
+
extra_headers = kwargs.get("headers", {})
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
res = self._session.request(
|
|
47
|
+
method=method,
|
|
48
|
+
url=url,
|
|
49
|
+
params=params,
|
|
50
|
+
json=body,
|
|
51
|
+
headers=extra_headers or None,
|
|
52
|
+
timeout=self.timeout,
|
|
53
|
+
)
|
|
54
|
+
except requests.exceptions.Timeout:
|
|
55
|
+
raise ChamaPayError("Request timed out", 0, "timeout")
|
|
56
|
+
except requests.exceptions.ConnectionError as e:
|
|
57
|
+
raise ChamaPayError(f"Connection error: {e}", 0, "connection_error")
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
data = res.json()
|
|
61
|
+
except ValueError:
|
|
62
|
+
data = {"error": {"message": res.text}}
|
|
63
|
+
|
|
64
|
+
if not res.ok:
|
|
65
|
+
err = data.get("error", data)
|
|
66
|
+
msg = err.get("message", f"Request failed with status {res.status_code}")
|
|
67
|
+
err_cls = _ERROR_MAP.get(res.status_code, ChamaPayError)
|
|
68
|
+
raise err_cls(msg, err.get("details"))
|
|
69
|
+
|
|
70
|
+
return data
|
|
71
|
+
|
|
72
|
+
def get(self, path, **opts):
|
|
73
|
+
return self._request("GET", path, **opts)
|
|
74
|
+
|
|
75
|
+
def post(self, path, **opts):
|
|
76
|
+
return self._request("POST", path, **opts)
|
|
77
|
+
|
|
78
|
+
def put(self, path, **opts):
|
|
79
|
+
return self._request("PUT", path, **opts)
|
|
80
|
+
|
|
81
|
+
def patch(self, path, **opts):
|
|
82
|
+
return self._request("PATCH", path, **opts)
|
|
83
|
+
|
|
84
|
+
def delete(self, path, **opts):
|
|
85
|
+
return self._request("DELETE", path, **opts)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from .members import MembersResource
|
|
2
|
+
from .contributions import ContributionsResource
|
|
3
|
+
from .loans import LoansResource
|
|
4
|
+
from .fines import FinesResource
|
|
5
|
+
from .meetings import MeetingsResource
|
|
6
|
+
from .projects import ProjectsResource
|
|
7
|
+
from .accounts import AccountsResource
|
|
8
|
+
from .welfare import WelfareResource
|
|
9
|
+
from .dividends import DividendsResource
|
|
10
|
+
from .documents import DocumentsResource
|
|
11
|
+
from .election_notices import ElectionNoticesResource
|
|
12
|
+
from .document_reminders import DocumentRemindersResource
|
|
13
|
+
from .audit import AuditResource
|
|
14
|
+
from .liabilities import LiabilitiesResource
|
|
15
|
+
from .reports import ReportsResource
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"MembersResource",
|
|
19
|
+
"ContributionsResource",
|
|
20
|
+
"LoansResource",
|
|
21
|
+
"FinesResource",
|
|
22
|
+
"MeetingsResource",
|
|
23
|
+
"ProjectsResource",
|
|
24
|
+
"AccountsResource",
|
|
25
|
+
"WelfareResource",
|
|
26
|
+
"DividendsResource",
|
|
27
|
+
"DocumentsResource",
|
|
28
|
+
"ElectionNoticesResource",
|
|
29
|
+
"DocumentRemindersResource",
|
|
30
|
+
"AuditResource",
|
|
31
|
+
"LiabilitiesResource",
|
|
32
|
+
"ReportsResource",
|
|
33
|
+
]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
class ContributionsResource:
|
|
2
|
+
def __init__(self, client): self._c = client
|
|
3
|
+
def list(self, **q): return self._c.get("/contributions", query=q)
|
|
4
|
+
def get(self, id): return self._c.get(f"/contributions/{id}")
|
|
5
|
+
def create(self, body, idempotency_key=None):
|
|
6
|
+
h = {"Idempotency-Key": idempotency_key} if idempotency_key else {}
|
|
7
|
+
return self._c.post("/contributions", body=body, headers=h)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
class MembersResource:
|
|
2
|
+
def __init__(self, client): self._c = client
|
|
3
|
+
def list(self, **q): return self._c.get("/members", query=q)
|
|
4
|
+
def get(self, id): return self._c.get(f"/members/{id}")
|
|
5
|
+
def create(self, **b): return self._c.post("/members", body=b)
|
|
6
|
+
def update(self, id, **b): return self._c.put(f"/members/{id}", body=b)
|
|
7
|
+
def delete(self, id): return self._c.delete(f"/members/{id}")
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: chamapay
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Official Python SDK for ChamaPay API — Financial Infrastructure for African Savings Groups
|
|
5
|
+
Author-email: ChamaPay <api-support@chamapay.co.ke>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://chamapay.co.ke
|
|
8
|
+
Project-URL: Documentation, https://api.chamapay.co.ke/docs
|
|
9
|
+
Project-URL: Source, https://github.com/chamapay/chamapay-python
|
|
10
|
+
Keywords: chamapay,sacco,savings,mpesa,africa,fintech
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
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
|
+
Requires-Dist: requests>=2.25.0
|
|
23
|
+
|
|
24
|
+
# ChamaPay Python SDK
|
|
25
|
+
|
|
26
|
+
Official Python SDK for the ChamaPay API.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install chamapay
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from chamapay import ChamaPay
|
|
38
|
+
|
|
39
|
+
api = ChamaPay('cpk_live_your_api_key', 'your_api_secret')
|
|
40
|
+
|
|
41
|
+
# List members
|
|
42
|
+
members = api.members.list(status='Active', page=1, limit=20)
|
|
43
|
+
|
|
44
|
+
# Create a contribution (idempotent)
|
|
45
|
+
contribution = api.contributions.create(
|
|
46
|
+
{'member_id': 'MFT001', 'amount': 5000},
|
|
47
|
+
idempotency_key='550e8400-e29b-41d4-a716-446655440000'
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Get loan details
|
|
51
|
+
loan = api.loans.get('LN001')
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## API Reference
|
|
55
|
+
|
|
56
|
+
| Resource | Methods |
|
|
57
|
+
|--------------------|--------------------------------------------|
|
|
58
|
+
| members | list, get, create, update, delete |
|
|
59
|
+
| contributions | list, get, create (with idempotency key) |
|
|
60
|
+
| loans | list, get, create |
|
|
61
|
+
| fines | list, create |
|
|
62
|
+
| meetings | list, create |
|
|
63
|
+
| projects | list, create |
|
|
64
|
+
| accounts | list, get |
|
|
65
|
+
| welfare | list |
|
|
66
|
+
| dividends | list |
|
|
67
|
+
| documents | list |
|
|
68
|
+
| election_notices | list |
|
|
69
|
+
| document_reminders | list |
|
|
70
|
+
| audit | list |
|
|
71
|
+
| liabilities | list, create |
|
|
72
|
+
| reports | get |
|
|
73
|
+
|
|
74
|
+
## Error Handling
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from chamapay import ChamaPayError, ValidationError, RateLimitError
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
api.members.create({...})
|
|
81
|
+
except ValidationError as e:
|
|
82
|
+
print(f"Validation failed: {e.details}")
|
|
83
|
+
except RateLimitError as e:
|
|
84
|
+
print(f"Rate limited. Retry after {e.retry_after}s")
|
|
85
|
+
except ChamaPayError as e:
|
|
86
|
+
print(f"API Error [{e.code}]: {e.message}")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Publishing
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pip install build twine
|
|
93
|
+
python -m build
|
|
94
|
+
twine upload dist/*
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Requires a PyPI account with access to the `chamapay` package.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
chamapay/__init__.py
|
|
4
|
+
chamapay/client.py
|
|
5
|
+
chamapay/errors.py
|
|
6
|
+
chamapay/http_client.py
|
|
7
|
+
chamapay.egg-info/PKG-INFO
|
|
8
|
+
chamapay.egg-info/SOURCES.txt
|
|
9
|
+
chamapay.egg-info/dependency_links.txt
|
|
10
|
+
chamapay.egg-info/requires.txt
|
|
11
|
+
chamapay.egg-info/top_level.txt
|
|
12
|
+
chamapay/resources/__init__.py
|
|
13
|
+
chamapay/resources/accounts.py
|
|
14
|
+
chamapay/resources/audit.py
|
|
15
|
+
chamapay/resources/contributions.py
|
|
16
|
+
chamapay/resources/dividends.py
|
|
17
|
+
chamapay/resources/document_reminders.py
|
|
18
|
+
chamapay/resources/documents.py
|
|
19
|
+
chamapay/resources/election_notices.py
|
|
20
|
+
chamapay/resources/fines.py
|
|
21
|
+
chamapay/resources/liabilities.py
|
|
22
|
+
chamapay/resources/loans.py
|
|
23
|
+
chamapay/resources/meetings.py
|
|
24
|
+
chamapay/resources/members.py
|
|
25
|
+
chamapay/resources/projects.py
|
|
26
|
+
chamapay/resources/reports.py
|
|
27
|
+
chamapay/resources/welfare.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests>=2.25.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
chamapay
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=64", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "chamapay"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Official Python SDK for ChamaPay API — Financial Infrastructure for African Savings Groups"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "ChamaPay", email = "api-support@chamapay.co.ke"}
|
|
14
|
+
]
|
|
15
|
+
keywords = ["chamapay", "sacco", "savings", "mpesa", "africa", "fintech"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 5 - Production/Stable",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.8",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
"requests>=2.25.0",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://chamapay.co.ke"
|
|
33
|
+
Documentation = "https://api.chamapay.co.ke/docs"
|
|
34
|
+
Source = "https://github.com/chamapay/chamapay-python"
|
chamapay-1.0.0/setup.cfg
ADDED