Skip to content

Commit c107312

Browse files
authored
Merge pull request #122 from Byte-Barn/feat/async
Feat/async
2 parents 030cb90 + 4ea020f commit c107312

42 files changed

Lines changed: 2118 additions & 171 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

mpesakit/account_balance/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from .account_balance import AccountBalance, AsyncAccountBalance
12
from .schemas import (
23
AccountBalanceIdentifierType,
34
AccountBalanceRequest,
@@ -7,9 +8,9 @@
78
AccountBalanceTimeoutCallback,
89
AccountBalanceTimeoutCallbackResponse,
910
)
10-
from .account_balance import AccountBalance
1111

1212
__all__ = [
13+
"AsyncAccountBalance",
1314
"AccountBalance",
1415
"AccountBalanceRequest",
1516
"AccountBalanceResponse",

mpesakit/account_balance/account_balance.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
"""
66

77
from pydantic import BaseModel, ConfigDict
8-
from mpesakit.auth import TokenManager
9-
from mpesakit.http_client import HttpClient
8+
9+
from mpesakit.auth import AsyncTokenManager, TokenManager
10+
from mpesakit.http_client import AsyncHttpClient, HttpClient
1011

1112
from .schemas import (
1213
AccountBalanceRequest,
@@ -43,5 +44,40 @@ def query(self, request: AccountBalanceRequest) -> AccountBalanceResponse:
4344
"Authorization": f"Bearer {self.token_manager.get_token()}",
4445
"Content-Type": "application/json",
4546
}
46-
response_data = self.http_client.post(url, json=request.model_dump(by_alias=True), headers=headers)
47+
response_data = self.http_client.post(
48+
url, json=request.model_dump(by_alias=True), headers=headers
49+
)
50+
return AccountBalanceResponse(**response_data)
51+
52+
53+
class AsyncAccountBalance(BaseModel):
54+
"""Represents the async Account Balance API client for M-Pesa operations.
55+
56+
Attributes:
57+
http_client (AsyncHttpClient): Async HTTP client for making requests to the M-Pesa API.
58+
token_manager (AsyncTokenManager): Async token manager for authentication.
59+
"""
60+
61+
http_client: AsyncHttpClient
62+
token_manager: AsyncTokenManager
63+
64+
model_config = ConfigDict(arbitrary_types_allowed=True)
65+
66+
async def query(self, request: AccountBalanceRequest) -> AccountBalanceResponse:
67+
"""Queries the account balance asynchronously.
68+
69+
Args:
70+
request (AccountBalanceRequest): The account balance query request.
71+
72+
Returns:
73+
AccountBalanceResponse: Response from the M-Pesa API.
74+
"""
75+
url = "/mpesa/accountbalance/v1/query"
76+
headers = {
77+
"Authorization": f"Bearer {await self.token_manager.get_token()}",
78+
"Content-Type": "application/json",
79+
}
80+
response_data = await self.http_client.post(
81+
url, json=request.model_dump(by_alias=True), headers=headers
82+
)
4783
return AccountBalanceResponse(**response_data)

mpesakit/b2b_express_checkout/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1+
from .b2b_express_checkout import AsyncB2BExpressCheckout, B2BExpressCheckout
12
from .schemas import (
3+
B2BExpressCallbackResponse,
4+
B2BExpressCheckoutCallback,
25
B2BExpressCheckoutRequest,
36
B2BExpressCheckoutResponse,
4-
B2BExpressCheckoutCallback,
5-
B2BExpressCallbackResponse,
67
)
78

8-
from .b2b_express_checkout import B2BExpressCheckout
9-
109
__all__ = [
10+
"AsyncB2BExpressCheckout",
1111
"B2BExpressCheckout",
1212
"B2BExpressCheckoutRequest",
1313
"B2BExpressCheckoutResponse",

mpesakit/b2b_express_checkout/b2b_express_checkout.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
"""
66

77
from pydantic import BaseModel, ConfigDict
8-
from mpesakit.auth import TokenManager
9-
from mpesakit.http_client import HttpClient
8+
9+
from mpesakit.auth import AsyncTokenManager, TokenManager
10+
from mpesakit.http_client import AsyncHttpClient, HttpClient
1011

1112
from .schemas import (
1213
B2BExpressCheckoutRequest,
@@ -49,3 +50,38 @@ def ussd_push(
4950
url, json=request.model_dump(mode="json"), headers=headers
5051
)
5152
return B2BExpressCheckoutResponse(**response_data)
53+
54+
55+
class AsyncB2BExpressCheckout(BaseModel):
56+
"""Represents the async B2B Express Checkout API client for M-Pesa operations.
57+
58+
Attributes:
59+
http_client (AsyncHttpClient): Async HTTP client for making requests to the M-Pesa API.
60+
token_manager (AsyncTokenManager): Async token manager for authentication.
61+
"""
62+
63+
http_client: AsyncHttpClient
64+
token_manager: AsyncTokenManager
65+
66+
model_config = ConfigDict(arbitrary_types_allowed=True)
67+
68+
async def ussd_push(
69+
self, request: B2BExpressCheckoutRequest
70+
) -> B2BExpressCheckoutResponse:
71+
"""Initiates a B2B Express Checkout USSD Push transaction asynchronously.
72+
73+
Args:
74+
request (B2BExpressCheckoutRequest): The B2B Express Checkout request data.
75+
76+
Returns:
77+
B2BExpressCheckoutResponse: Response from the M-Pesa API.
78+
"""
79+
url = "/v1/ussdpush/get-msisdn"
80+
headers = {
81+
"Authorization": f"Bearer {await self.token_manager.get_token()}",
82+
"Content-Type": "application/json",
83+
}
84+
response_data = await self.http_client.post(
85+
url, json=request.model_dump(mode="json"), headers=headers
86+
)
87+
return B2BExpressCheckoutResponse(**response_data)

mpesakit/b2c/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1+
from .b2c import B2C, AsyncB2C
12
from .schemas import (
23
B2CCommandIDType,
34
B2CRequest,
45
B2CResponse,
5-
B2CResultParameter,
6-
B2CResultMetadata,
76
B2CResultCallback,
7+
B2CResultMetadata,
8+
B2CResultParameter,
89
B2CTimeoutCallback,
910
B2CTimeoutCallbackResponse,
1011
)
11-
from .b2c import B2C
1212

1313
__all__ = [
14+
"AsyncB2C",
1415
"B2C",
1516
"B2CCommandIDType",
1617
"B2CRequest",

mpesakit/b2c/b2c.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
"""
66

77
from pydantic import BaseModel, ConfigDict
8-
from mpesakit.auth import TokenManager
9-
from mpesakit.http_client import HttpClient
8+
9+
from mpesakit.auth import AsyncTokenManager, TokenManager
10+
from mpesakit.http_client import AsyncHttpClient, HttpClient
1011

1112
from .schemas import (
1213
B2CRequest,
@@ -43,5 +44,40 @@ def send_payment(self, request: B2CRequest) -> B2CResponse:
4344
"Authorization": f"Bearer {self.token_manager.get_token()}",
4445
"Content-Type": "application/json",
4546
}
46-
response_data = self.http_client.post(url, json=request.model_dump(by_alias=True), headers=headers)
47+
response_data = self.http_client.post(
48+
url, json=request.model_dump(by_alias=True), headers=headers
49+
)
50+
return B2CResponse(**response_data)
51+
52+
53+
class AsyncB2C(BaseModel):
54+
"""Represents the async B2C API client for M-Pesa Business to Customer operations.
55+
56+
Attributes:
57+
http_client (AsyncHttpClient): Async HTTP client for making requests to the M-Pesa API.
58+
token_manager (AsyncTokenManager): Async token manager for authentication.
59+
"""
60+
61+
http_client: AsyncHttpClient
62+
token_manager: AsyncTokenManager
63+
64+
model_config = ConfigDict(arbitrary_types_allowed=True)
65+
66+
async def send_payment(self, request: B2CRequest) -> B2CResponse:
67+
"""Initiates a B2C payment request asynchronously.
68+
69+
Args:
70+
request (B2CRequest): The payment request details.
71+
72+
Returns:
73+
B2CResponse: Response from the M-Pesa API after payment initiation.
74+
"""
75+
url = "/mpesa/b2c/v3/paymentrequest"
76+
headers = {
77+
"Authorization": f"Bearer {await self.token_manager.get_token()}",
78+
"Content-Type": "application/json",
79+
}
80+
response_data = await self.http_client.post(
81+
url, json=request.model_dump(by_alias=True), headers=headers
82+
)
4783
return B2CResponse(**response_data)

mpesakit/b2c_account_top_up/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1+
from .b2c_account_top_up import AsyncB2CAccountTopUp, B2CAccountTopUp
12
from .schemas import (
2-
B2CAccountTopUpRequest,
3-
B2CAccountTopUpResponse,
43
B2CAccountTopUpCallback,
54
B2CAccountTopUpCallbackResponse,
5+
B2CAccountTopUpRequest,
6+
B2CAccountTopUpResponse,
67
B2CAccountTopUpTimeoutCallback,
78
B2CAccountTopUpTimeoutCallbackResponse,
89
)
9-
from .b2c_account_top_up import B2CAccountTopUp
1010

1111
__all__ = [
12+
"AsyncB2CAccountTopUp",
1213
"B2CAccountTopUp",
1314
"B2CAccountTopUpRequest",
1415
"B2CAccountTopUpResponse",

mpesakit/b2c_account_top_up/b2c_account_top_up.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
"""
66

77
from pydantic import BaseModel, ConfigDict
8-
from mpesakit.auth import TokenManager
9-
from mpesakit.http_client import HttpClient
8+
9+
from mpesakit.auth import AsyncTokenManager, TokenManager
10+
from mpesakit.http_client import AsyncHttpClient, HttpClient
1011

1112
from .schemas import (
1213
B2CAccountTopUpRequest,
@@ -47,3 +48,37 @@ def topup(self, request: B2CAccountTopUpRequest) -> B2CAccountTopUpResponse:
4748
url, json=request.model_dump(mode="json"), headers=headers
4849
)
4950
return B2CAccountTopUpResponse(**response_data)
51+
52+
53+
class AsyncB2CAccountTopUp(BaseModel):
54+
"""Represents the async B2C Account TopUp API client for M-Pesa operations.
55+
56+
Attributes:
57+
http_client (AsyncHttpClient): Async HTTP client for making requests to the M-Pesa API.
58+
token_manager (AsyncTokenManager): Async token manager for authentication.
59+
"""
60+
61+
http_client: AsyncHttpClient
62+
token_manager: AsyncTokenManager
63+
64+
model_config = ConfigDict(arbitrary_types_allowed=True)
65+
66+
async def topup(self, request: B2CAccountTopUpRequest) -> B2CAccountTopUpResponse:
67+
"""Initiates a B2C Account TopUp transaction asynchronously.
68+
69+
Args:
70+
request (B2CAccountTopUpRequest): The B2C Account TopUp request data.
71+
72+
Returns:
73+
B2CAccountTopUpResponse: Response from the M-Pesa API.
74+
"""
75+
url = "/mpesa/b2b/v1/paymentrequest"
76+
token = await self.token_manager.get_token()
77+
headers = {
78+
"Authorization": f"Bearer {token}",
79+
"Content-Type": "application/json",
80+
}
81+
response_data = await self.http_client.post(
82+
url, json=request.model_dump(mode="json"), headers=headers
83+
)
84+
return B2CAccountTopUpResponse(**response_data)

mpesakit/bill_manager/__init__.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
1+
from .bill_manager import AsyncBillManager, BillManager
12
from .schemas import (
2-
BillManagerOptInRequest,
3-
BillManagerOptInResponse,
4-
BillManagerUpdateOptInRequest,
5-
BillManagerUpdateOptInResponse,
6-
BillManagerSingleInvoiceRequest,
7-
BillManagerSingleInvoiceResponse,
83
BillManagerBulkInvoiceRequest,
94
BillManagerBulkInvoiceResponse,
10-
BillManagerCancelSingleInvoiceRequest,
115
BillManagerCancelBulkInvoiceRequest,
126
BillManagerCancelInvoiceResponse,
13-
BillManagerPaymentNotificationRequest,
14-
BillManagerPaymentNotificationResponse,
7+
BillManagerCancelSingleInvoiceRequest,
8+
BillManagerOptInRequest,
9+
BillManagerOptInResponse,
1510
BillManagerPaymentAcknowledgmentRequest,
1611
BillManagerPaymentAcknowledgmentResponse,
12+
BillManagerPaymentNotificationRequest,
13+
BillManagerPaymentNotificationResponse,
14+
BillManagerSingleInvoiceRequest,
15+
BillManagerSingleInvoiceResponse,
16+
BillManagerUpdateOptInRequest,
17+
BillManagerUpdateOptInResponse,
1718
InvoiceItem,
1819
)
1920

20-
from .bill_manager import BillManager
21-
2221
__all__ = [
22+
"AsyncBillManager",
23+
"BillManager",
2324
"BillManagerOptInRequest",
2425
"BillManagerOptInResponse",
2526
"BillManagerUpdateOptInRequest",
@@ -35,6 +36,5 @@
3536
"BillManagerPaymentNotificationResponse",
3637
"BillManagerPaymentAcknowledgmentRequest",
3738
"BillManagerPaymentAcknowledgmentResponse",
38-
"BillManager",
3939
"InvoiceItem",
4040
]

0 commit comments

Comments
 (0)