No project description provided
Project description
decide-python-package
Table of contents
About
Decide helps users make risk-free decisions based on an analysis of their banking transactions using extracted financial data. The Decide SDK helps developers plug into the functionalities of Decide from their python projects.
- Website: https://developers.indicina.co
- Documentation: https://developers.indicina.co/docs/decide-python-library
Using the App
Installation
In your python project use the command pip install indicina-decide to install the Decide SDK
Authorization
sh
export INDICINA_CLIENT_ID=my_id
export INDICINA_CLIENT_SECRET=my_secret
Python
import os
os.environ["INDICINA_CLIENT_ID"] = "my_id"
os.environ["INDICINA_CLIENT_SECRET"] = "my_secret"
You can get your INDICINA_CLIENT_ID and INDICINA_CLIENT_SECRET from GitHub Pages.
Sample Code
JSON STATEMENT
from decide.models.analysis import Analysis
from decide.models.customer import Customer
from decide.models.statement import JSONStatement
import json
statement = json.loads("""{
"paging": {
"total": 190,
"page": 2,
"previous": "https://api.withmono.com/accounts/:id/transactions?page=2",
"next": "https://api.withmono.com/accounts/:id/transactions?page=3"
},
"data": [
{
"_id": "12345",
"amount": 10000,
"date": "2020-07-21T00:00:00.000Z",
"narration": "TRANSFER from *************",
"type": "debit",
"category": "E-CHANNELS"
},
{
"_id": "12345",
"amount": 20000,
"date": "2020-07-21T00:00:00.000Z",
"narration": "TRANSFER from ***********",
"type": "debit",
"category": "E-CHANNELS"
}
]
}""")
statement = JSONStatement(statement_format=StatementFormat.MONO, statement=json_statement, customer=customer)
analyis: Analysis = statement.analyze()
print(analysis)
print(f"Analysis status is: {analysis.status}")
PDF Statement
from decide import PDFStatement
from decide.models.analysis import Analysis
...
statement = PDFStatement(customer=customer,
pdf_path="statement.pdf",
bank=Bank.ACCESS,
currency=Currency.NGN)
analyis: Analysis = statement.analyze()
print(analysis)
print(f"Analysis status is: {analysis.status}")
CSV Statement
from decide import CSVStatement
from decide.models.analysis import Analysis
...
statement = CSVStatement(csv_path="AverageOtherIncome.csv",
customer=customer)
analyis: Analysis = statement.analyze()
print(analysis)
print(f"Analysis status is: {analysis.status}")
Sample Response
{
"status": "success",
"data": {
"country": "Nigeria",
"currency": "NGN",
"behaviouralAnalysis": {
"accountSweep": "No",
"gamblingRate": 0,
"inflowOutflowRate": "Neutral Cash Flow",
"loanAmount": 2000,
"loanInflowRate": 0,
"loanRepaymentInflowRate": 0,
"loanRepayments": 54500,
"topIncomingTransferAccount": "The",
"topTransferRecipientAccount": "Day"
},
"cashFlowAnalysis": {
"accountActivity": 0.84,
"averageBalance": 1815942.46,
"averageCredits": 153741.4861589404,
"averageDebits": 31563.282248447216,
"closingBalance": -202978.97,
"firstDay": "2022-05-18",
"lastDay": "2022-10-18",
"monthPeriod": "May - October",
"netAverageMonthlyEarnings": -1875144.8599999999,
"noOfTransactingMonths": 6,
"totalCreditTurnover": 23214964.409999996,
"totalDebitTurnover": 25408442.21000001,
"yearInStatement": "2022",
"maxEmiEligibility": 48871,
"emiConfidenceScore": 0.04
},
"incomeAnalysis": {
"salaryEarner": "Yes",
"medianIncome": 83150,
"averageOtherIncome": 69187.43,
"expectedSalaryDay": 25,
"lastSalaryDate": "2022-08-25",
"averageSalary": 2290408.08,
"confidenceIntervalonSalaryDetection": 1,
"salaryFrequency": "1",
"numberSalaryPayments": 3,
"numberOtherIncomePayments": 15,
"gigWorker": "No"
},
"spendAnalysis": {
"averageRecurringExpense": 360140.42,
"hasRecurringExpense": "Yes",
"averageMonthlyExpenses": 4234740.37,
"expenseChannels": `expenseChannels`,(bills, entertainment,savingsAndInvestments,gambling,airtime,bankCharges,chequeWithdrawal,cashWithdrawal,shopping, eatingOut)
"expenseCategories": `expenseCategories`
},
"transactionPatternAnalysis": {
"MAWWZeroBalanceInAccount": {
"month": null,
"week_of_month": 0
},
"NODWBalanceLess5000": 35,
"NODWBalanceLess": {
"amount": 5000,
"count": 35
},
"highestMAWOCredit": {
"month": "August",
"week_of_month": 3
},
"highestMAWODebit": {
"month": "August",
"week_of_month": 5
},
"lastDateOfCredit": "2022-10-17",
"lastDateOfDebit": "2022-10-18",
"mostFrequentBalanceRange": ">500000",
"mostFrequentTransactionRange": "<10000",
"recurringExpense": [
{
"amount": 1650,
"description": "spend and save"
},
{
"amount": 4000,
"description": "airtime purchase 2347049215992"
},
{
"amount": 5000,
"description": "fuel"
}
],
"transactionsBetween100000And500000": 39,
"transactionsBetween10000And100000": 176,
"transactionsGreater500000": 24,
"transactionsLess10000": 717,
"transactionRanges": [
{
"min": 10000,
"max": 100000,
"count": 176
},
{
"min": 100000,
"max": 500000,
"count": 39
},
{
"min": null,
"max": 10000,
"count": 717
},
{
"min": 500000,
"max": null,
"count": 24
}
]
}
}
}
Supported Banks
In selecting a bank to use for analysis, we maintain an ENUM of supported banks here. We have also provided a convenient method to fetch a current list of supported banks.
from decide import PDFStatement, Bank
# Enum selection of Bank
statement = PDFStatement(
...,
bank=Bank.GTB,
...)
from decide import Bank
# Get bank list
supported_bank_list = Bank.get_bank_list()
print(supported_bank_list)
output: A list of tuples [(bank_name, bank_code)]
[('Guaranty Trust Bank', '058'), ('Access Bank', '044')...]
Analysis
When the Decide API sends a response, the response is represented in the Analysis class.
Anatomy of an Analysis
Analysis
|
|-- behaviouralAnalysis: `BehaviouralAnalysis`
| |-- accountSweep
| |-- gamblingRate
| |-- inflowOutflowRate
| |-- loanInflowRate
| |-- loanRepaymentInflowRate
| |-- loanRepayments
| |-- topIncomingTransferAccount
| |-- topTransferRecipientAccount
|-- loanAmount
|
|-- cashFlowAnalysis: `CashFlowAnalysis`
| |-- accountActivity
| |-- averageBalance
| |-- averageCredits
| |-- averageDebits
| |-- closingBalance
| |-- firstDay
| |-- lastDay
| |-- monthPeriod
| |-- netAverageMonthlyEarnings
| |-- noOfTransactingMonths
| |-- totalCreditTurnover
| |-- totalDebitTurnover
| |-- yearInStatement
|
|-- incomeAnalysis: `IncomeAnalysis`
| |-- averageOtherIncome
| |-- averageSalary
| |-- confidenceIntervalOnSalaryDetection
| |-- expectedSalaryDay
| |-- lastSalaryDate
| |-- medianIncome
| |-- numberOtherIncomePayments
| |-- numberOfSalaryPayments
| |-- salaryEarner
| |-- salaryFrequency
| |-- gigWorker
|
|-- spendAnalysis: `SpendAnalysis`
| |-- expenseChannels: `ExpenseChannels`
| | |-- atmSpend
| | |-- webSpend
| | |-- posSpend
| | |-- ussdTransactions
| | |-- mobileSpend
| | |-- spendOnTransfers
| | |-- internationalTransactionsSpend
| |-- expenseCategories: `ExpenseCategories`
| | |-- bills
| | |-- entertainment
| | |-- savingsAndInvestments
| | |-- gambling
| | |-- airtime
| | |-- bankCharges
| |-- averageRecurringExpense
| |-- hasRecurringExpense
| |-- totalExpenses
|-- transactionPatternAnalysis: `TransactionPatternAnalysis`
| |-- highestMAWOCredit
| |-- highestMAWODebit
| |-- lastDateOfCredit
| |-- lastDateOfDebit
| |-- MAWWZeroBalanceInAccount
| |-- mostFrequentBalanceRange
| |-- mostFrequentTransactionRange
| |-- NODWBalanceLess5000
| |-- recurringExpense
| |-- transactionsBetween100000And500000
| |-- transactionsBetween10000And100000
| |-- transactionsGreater500000
| |-- transactionsLess10000
| |-- transactionRanges
| |-- NODWBalanceLess
|-- status
Analysis Status
Some bank statement analyses (e.g. PDF) are asynchronous. You may not get the results of the analysis immediately.
You may need to get the status of an analysis.
PDFStatus could take one of the following values.
| Status | Value | Description |
|---|---|---|
| DONE | DONE | The analysis is done |
| FAILED | FAILED | The analysis failed |
| IN_PROGRESS | IN_PROGRESS | The analysis is still in progress |
# Example usage on accessing the analysis response
analysis = statement.analyze()
print(f"Analysis status is: {analysis.status}")
# wait for analysis to be done
time.sleep(3)
print(analysis)
print(f"Analysis status is: {analysis.status}")
print(f"Credit turnover is: {analysis.cashFlowAnalysis.totalCreditTurnover}")
print(f"Average salary is: {analysis.incomeAnalysis.averageSalary}")
print(f"{analysis.behaviouralAnalysis}")
print(analysis.transaction_tags)
Contribution
Setup Project
The link for this projects's repository can be found here
Cloning the project
For HTTPS
Use this command git clone https://github.com/indicina-dev/decide-python.git
For SSH
Use this command git clone git@github.com:indicina-dev/decide-python.git
Running the project
- Create virtual enviroment
- Install the requirements.txt file
pip install -r requirements.txt - Run files
Contribute to Project
Do you find the project interesting and you would like to contribute to our project?
- Fork the repository to your github account
- Clone the repository to your local machine
- Create a new branch for your fix (preferably descriptive to your contribution)
- Make appropriate changes and tests for the changes
- Use
git add insert-paths-of-changed-files-hereto add the file contents of the changed files to the "snapshot" git uses for project management - Committing: As a means to create a seamless development and contribution flow, we require that commits be standardized, following the conventional commits guideline:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
We have included the hook script to verify your commits, you will need to install it as follows:
pip install pre-commit
pre-commit install --hook-type commit-msg
Examples of good commits:
-
adding a new feature:
git commit -m "feat: allow provided config object to extend other configs" -
adding a breaking change, take note of the ! :
git commit -m "feat!: send an email to the customer when a product is shipped"
- Push the changes to the remote repository using
git push origin branch-name-here - Submit a pull request to the upstream repository
- Title the pull request with a short description of the changes made and the issue or bug number associated with your change. For example, you can title an issue like so
Added more log outputting to resolve #4352. - Wait for our in-house developers to approve the merge requests or update the merge requests if changes were requested,
Issues
To create an issue, simply click on the issues tab on the menu and create a new issue.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file indicina-decide-0.4.0.tar.gz.
File metadata
- Download URL: indicina-decide-0.4.0.tar.gz
- Upload date:
- Size: 17.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.9.6 readme-renderer/37.3 requests/2.28.2 requests-toolbelt/0.10.1 urllib3/1.26.14 tqdm/4.65.0 importlib-metadata/6.0.0 keyring/23.13.1 rfc3986/2.0.0 colorama/0.4.6 CPython/3.10.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f98aaf4a3fd532f6bfc9a0ef295e142563dfc9335fb0876dd3a7dd2f6f6db22
|
|
| MD5 |
27dcbadb51004edf09335ff3e1a57b3a
|
|
| BLAKE2b-256 |
efbe527c6d0164ea78b4838a5d7dd615bcf4cd2e31f88c39d2b511a172a54af4
|
File details
Details for the file indicina_decide-0.4.0-py3-none-any.whl.
File metadata
- Download URL: indicina_decide-0.4.0-py3-none-any.whl
- Upload date:
- Size: 17.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.9.6 readme-renderer/37.3 requests/2.28.2 requests-toolbelt/0.10.1 urllib3/1.26.14 tqdm/4.65.0 importlib-metadata/6.0.0 keyring/23.13.1 rfc3986/2.0.0 colorama/0.4.6 CPython/3.10.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5507e7a6e3f02adc4b59c4d49d3f28a08dde33fd9c735cfa7fe4ea996c8d05a
|
|
| MD5 |
3e8aaad7e584878361e2a59a00d83335
|
|
| BLAKE2b-256 |
fd83821d77ad7102ddbc51a1eae83cf8e279fc2f164d35ed2043d18a8f800b8b
|