Package: pykuda
PyKudaA python package that simplifies using the Kuda Bank API. This python package makes it seamless and easy to enjoy the beautiful Kuda Bank pen Api. PyKuda uses Kuda's Api v2 which authenticates using anAPI keyand atoken.Getting startedInstall PyKudaTo use this package, install it using the package managerpip:pipinstallpykudaPyKuda has some dependencies which will be installed (requests and python-decouple).requestsis used by PyKuda to make http requests to Kuda's endpoints, while thepython-decoupleis responsible for getting the environmental variables which has to be set for the requests to be authenticated; more to be discussed below.Create Environmental variablesAfter installation, the next thing is to create a.envfile where the environmental variables will be stored. Five variables are to be set in the.envfile, and they are shown in an example below.KUDA_KEY="Your Kuda Api Key"TOKEN_URL="https://kuda-openapi.kuda.com/v2.1/Account/GetToken"# Kuda API v2.1 GetToken URLREQUEST_URL="https://kuda-openapi.kuda.com/v2.1/"# Kuda API v2.1 Request URLEMAIL="Your email used to register for the Kuda account"MAIN_ACCOUNT_NUMBER="Your main Kuda account number"Not setting these in the.envfile will raise a value error as shown below.>>>frompykuda.pykudaimportPyKuda
>>>kuda=PyKuda()Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>File"/path/to/Python/version/lib/python/site-packages/pykuda/pykuda.py",line16,in__init__raiseValueError(response)ValueError:TOKEN_URL,REQUEST_URL,EMAIL,MAIN_ACCOUNT_NUMBERarenotset,pleasesetintheenvironmentorpassthemasadictionarywheninitialisingPyKuda.NB: Please make sure you do not push your.envfile to public repositories as the details here are confidential.Initialize with credentialsIf you do not want to set the credentials in the.envfile, you can also initiaizePyKudawith a dictionary of your credentials.>>>frompykuda.pykudaimportPyKuda
>>>credentials={..."KUDA_KEY":"KUDA_KEY",
..."TOKEN_URL":"TOKEN_URL",
..."REQUEST_URL":"REQUEST_URL",
..."EMAIL":"EMAIL",
..."MAIN_ACCOUNT_NUMBER":"MAIN_ACCOUNT_NUMBER",
...}>>>kuda=PyKuda(credentials)# Will not raise a ValueErrorUsing PyKudaSuccessful requestfrompykuda.pykudaimportPyKudakuda=PyKuda()response=kuda.banks_list()print(response)# Example Response:# PyKudaResponse(status_code=200, data=[list_of_banks], error=False)Failed requestIn case the request wasn't successful, the PyKudaResponse will be different. The data will be aResponseObject which you can check to investigate the cause (Maybe your Token is not correct, or the URL, or something else). Now, let's say the API Key in the .env file was not a correct one and a request was made, the example below shows the response to expect.print(response)# PyKudaResponse(status_code=401, data=<Response [401]>, error=True)print(response.data.text)# 'Invalid Credentials'print(response.data.reason)# 'Unauthorized'Understanding PyKudaResponseWithPyKuda, every interaction with the Kuda API is elevated through thePyKudaResponseobject, enriching the responses from Kuda. This custom response encapsulates three key attributes:status_code,data, anderror.PyKudaResponseserves as a tailored feedback mechanism provided by PyKuda. Its primary purpose is to enhance the interpretation of Kuda's responses and reliably confirm the success of a request. In cases where the request encounters issues, theerrorattribute is set toTrue, signaling that an error has occurred during the interaction. This nuanced approach ensures a more robust and dependable handling of API responses. It is imperative to systematically inspect theerrorattribute to ascertain the success of the method.Example:This illustrative example outlines a conventional approach to leverage PyKuda for verifying the success of a request.importloggingfromrest_framework.responseimportResponsefromrest_framework.viewsimportAPIViewfromrest_frameworkimportstatusfrompykuda.pykudaimportPyKuda,PyKudaResponselogger=logging.getLogger(__name__)# Initialize PyKuda instancekuda=PyKuda()classBanksListView(APIView):"""API view to retrieve a list of banks."""defget(self,request)->Response:"""Handle GET request to retrieve a list of banks.Returns:Response: JSON response containing the list of banks or an error message."""# Retrieve list of banks from Kuda APIresponse=kuda.banks_list()ifnotresponse.error:# The request was successful# Return the list of banks to the frontendreturnResponse(response.data,status=response.status_code)else:# There was an error in the request# Log provider error detailsself.log_kuda_error(response.data)# Return an error and handle it in the frontend or according to your business modelreturnResponse("Your custom error",status="error_code")deflog_kuda_error(self,error_response:PyKudaResponse)->None:"""Log details of Kuda API error.Args:error_response (PyKudaResponse): The PyKudaResponse object containing error details."""# Log error detailslogger.error(f"KUDA ERROR:\n"f"STATUS CODE -{error_response.status_code}\n"f"RESPONSE DATA -{error_response.data}\n"f"ERROR -{error_response.error}")As seen above, the PyKudaResponse returns thestatus_code,dataanderror; the data attribute already contains the appropriate data received from Kuda API. You can access the Kuda response data by executingresponse.data.Important Note on Error Handling:When interacting with the Kuda API, it is not recommended to rely solely on the response.status_code for error handling. The Kuda API may return a 200 status code even in cases where there are errors or typos in the request parameters.For instance, when attempting to purchase airtime, passing an invalid tracking_reference will result in a 200 status code from Kuda, but the request will not be processed successfully.To ensure robust error handling, it is crucial to examine the response data and utilize the error attribute in the PyKudaResponse object.PyKudaintelligently checks that if the request is not successful and was not processed by Kuda, theresponse.errorwill beTrue. This attribute indicates whether the API request was successful or if there were issues.Example:response=kuda.virtual_account_purchase_bill(amount='10000',kuda_biller_item_identifier="KD-VTU-MTNNG",customer_identifier="08030001234",tracking_reference="invalid_tracking_reference",# Invalid tracking_reference)print(response)# PyKudaResponse(status_code=200, data=<Response [200]>, error=True)print(response.data.text)# '{"message":"Invalid Virtual Account.","status":false,"data":null,"statusCode":"k-OAPI-07"}'As shown in theSuccessful requestsection, it is recommended to use response.error to ensure that the request was successful.What else can PyKuda do?PyKuda can be used to make other requests also. Below are examples of how to use the other methods available in theServiceTypeclass.Create Virtual Accountresponse=kuda.create_virtual_account(first_name="Ogbeni",last_name="Lagbaja",phone_number="08011122233",email="ogbeni@temi.com",middle_name="Middle",business_name="ABC Ltd",)print(response)# Example Response:# PyKudaResponse(status_code=200, data=<response_data>, error=False)print(response.data)# {#     "account_number": "2000111222", # Newly generated account number from Kuda#     "tracking_reference": "trackingReference", # Tracking reference# }Virtual Account Balanceresponse=kuda.virtual_account_balance(tracking_reference="your_tracking_reference")print(response.data)# {#     "ledger": "ledgerBalance",#     "available": "availableBalance",#     "withdrawable": "withdrawableBalance",# }Main Account Balanceresponse=kuda.main_account_balance()print(response.data)# {#     "ledger": "ledgerBalance",#     "available": "availableBalance",#     "withdrawable": "withdrawableBalance",# }Fund Virtual Accountresponse=kuda.fund_virtual_account(tracking_reference="your_tracking_reference",amount="1000",narration="Funding virtual account",)print(response.data)# {"reference": "transactionReference"}Withdraw from Virtual Accountresponse=kuda.withdraw_from_virtual_account(tracking_reference="your_tracking_reference",amount="500",narration="Withdrawing from virtual account",)print(response.data)# {"reference": "transactionReference"}Confirm Transfer Recipientresponse=kuda.confirm_transfer_recipient(beneficiary_account_number="recipient_account_number",beneficiary_bank_code="recipient_bank_code",tracking_reference="your_tracking_reference",)print(response.data)# {#     "beneficiary_account_number":#         "beneficiaryAccountNumber"#     ),#     "beneficiary_name": "beneficiaryName",#     "beneficiary_code": "beneficiaryBankCode",#     "session_id": "sessionID",#     "sender_account": "senderAccountNumber",#     "transfer_charge": "transferCharge",#     "name_enquiry_id": "nameEnquiryID",#     "tracking_reference": "SenderTrackingReference",# }Send Funds from Main Accountresponse=kuda.send_funds_from_main_account(client_account_number="sender_account_number",beneficiary_bank_code="recipient_bank_code",beneficiary_account_number="recipient_account_number",beneficiary_name="Recipient Name",amount="1000",naration="Sending funds",name_enquiry_session_id="name_enquiry_session_id",sender_name="Sender Name",)print(response.data)# {#     "transaction_reference": "transactionReference",#     "request_reference": "requestReference",# }Send Funds from Virtual Accountresponse=kuda.send_funds_from_virtual_account(tracking_reference="your_tracking_reference",beneficiary_bank_code="recipient_bank_code",beneficiary_account_number="recipient_account_number",beneficiary_name="Recipient Name",amount="1000",naration="Sending funds",name_enquiry_session_id="name_enquiry_session_id",sender_name="Sender Name",)print(response.data)# {#     "transaction_reference": "transactionReference",#     "request_reference": "requestReference",# }Get Billersresponse=kuda.billers(biller_type="electricity")print(response.data)# {#     "billers": ["list_of_billers"]# }Verify Bill Customerresponse=kuda.verify_bill_customer(kuda_biller_item_identifier="bill_item_identifier",customer_identifier="customer_identifier",)print(response.data)# {#     "customer_name": "customerName,# }Main Account Purchase Billresponse=kuda.p.admin_purchase_bill(amount="500",kuda_biller_item_identifier="bill_item_identifier",customer_identifier="customer_identifier",tracking_reference="your_tracking_reference",client_first_name="Lagbaja",phone_number="customer_phone_number",)print(response.data)# {#     "reference": "reference",# }Virtual Account Purchase Billresponse=kuda.virtual_account_purchase_bill(amount="500",kuda_biller_item_identifier="bill_item_identifier",customer_identifier="customer_identifier",tracking_reference="your_tracking_reference",phone_number="customer_phone_number",)print(response.data)# {#     "reference": "reference",# }Disable Virtual Accountresponse=kuda.disable_virtual_account(tracking_reference="your_tracking_reference",)print(response.data)# {#     "account_number": "accountNumber",# }Enable Virtual Accountresponse=kuda.enable_virtual_account(tracking_reference="your_tracking_reference",)print(response.data)# {#     "account_number": "accountNumber",# }Update Virtual Account Nameresponse=kuda.update_virtual_account_name(tracking_reference="your_tracking_reference",first_name="New_First_Name",last_name="New_Last_Name",)print(response.data)# {#     "account_number": "accountNumber"# }Update Virtual Account Emailresponse=kuda.update_virtual_account_email(tracking_reference="your_tracking_reference",email="new_email@example.com",)print(response.data)# {#     "account_number": "accountNumber"# }Retrieve Single Virtual Accountresponse=kuda.retrieve_single_virtual_account(tracking_reference="customer_tracking_reference",)print(response.data)# {# 	  "accountNumber": "2504205433",#     "email": "08011122233",#     "phoneNumber": "08011111111",#     "lastName": "Lagbaja",#     "firstName": "Ogbeni",#     "middleName": "Middle",#     "bussinessName": "ABC LTD",#     "accountName": "(ABC LTD)-Lagbaja Ogbeni",#     "trackingReference": "tracking_reference",#     "creationDate": "2023-04-24T16:35:23.6033333",#     "isDeleted": false# }Retrieve All Virtual Accountsresponse=kuda.retrieve_all_virtual_accounts()print(response.data)# [# {# 	  "accountNumber": "2504205433",#     "email": "08011122233",#     "phoneNumber": "08011111111",#     "lastName": "Lagbaja",#     "firstName": "Ogbeni",#     "middleName": "Middle",#     "bussinessName": "ABC LTD",#     "accountName": "(ABC LTD)-Lagbaja Ogbeni",#     "trackingReference": "tracking_reference",#     "creationDate": "2023-04-24T16:35:23.6033333",#     "isDeleted": false# },# ........# ]Contributions & IssuesIf you would like to contribute and improve this package or its documentation, please feel free to fork the repository, make changes and open a pull request.If you encounter any issue or bugs, please open an issue.AuthorKayode TemiTope