Python SDK for Bank of Maldives Connect API with synchronous and asynchronous support
Project description
BML Connect Python SDK
Python SDK for Bank of Maldives Connect API with synchronous and asynchronous support.
Compatible with all Python frameworks including Django, Flask, FastAPI, and Sanic.
Features
- 🔄 Sync/Async Support: Choose your preferred programming style
- 🎯 Full API Coverage: Transactions, webhooks, and signature verification
- 📝 Type Annotations: Full type hint support for better development experience
- 🛡️ Error Handling: Comprehensive error hierarchy for easy debugging
- 🚀 Framework Agnostic: Works with any Python web framework
- 📄 MIT Licensed: Open source and free to use
Installation
pip install bml-connect-python
Quick Start
Synchronous Usage
from bml_connect import BMLConnect, Environment
client = BMLConnect(
api_key="your_api_key",
app_id="your_app_id",
environment=Environment.SANDBOX
)
try:
transaction = client.transactions.create_transaction({
"amount": 1500, # 15.00 MVR
"currency": "MVR",
"provider": "alipay",
"redirectUrl": "https://yourstore.com/success",
"localId": "order_123",
"customerReference": "Customer #456"
})
print(f"Transaction ID: {transaction.transaction_id}")
print(f"Payment URL: {transaction.url}")
except Exception as e:
print(f"Error: {e}")
finally:
client.close()
Asynchronous Usage
import asyncio
from bml_connect import BMLConnect, Environment
async def main():
client = BMLConnect(
api_key="your_api_key",
app_id="your_app_id",
environment=Environment.SANDBOX,
async_mode=True
)
try:
transaction = await client.transactions.create_transaction({
"amount": 2000,
"currency": "MVR",
"provider": "wechat",
"redirectUrl": "https://yourstore.com/success"
})
print(f"Transaction ID: {transaction.transaction_id}")
finally:
await client.aclose()
asyncio.run(main())
Framework Integration Examples
Flask Integration
from flask import Flask, request, jsonify
from bml_connect import BMLConnect
app = Flask(__name__)
client = BMLConnect(api_key="your_api_key", app_id="your_app_id")
@app.route('/webhook', methods=['POST'])
def webhook():
payload = request.get_json()
signature = payload.get('signature')
if client.verify_webhook_signature(payload, signature):
# Process webhook
return jsonify({"status": "success"}), 200
else:
return jsonify({"error": "Invalid signature"}), 403
FastAPI Integration
from fastapi import FastAPI, Request, HTTPException
from bml_connect import BMLConnect
app = FastAPI()
client = BMLConnect(api_key="your_api_key", app_id="your_app_id")
@app.post("/webhook")
async def handle_webhook(request: Request):
payload = await request.json()
signature = payload.get("signature")
if client.verify_webhook_signature(payload, signature):
return {"status": "success"}
else:
raise HTTPException(403, "Invalid signature")
Sanic Integration
from sanic import Sanic, response
from bml_connect import BMLConnect
app = Sanic("BMLWebhook")
client = BMLConnect(api_key="your_api_key", app_id="your_app_id")
@app.post('/webhook')
async def webhook(request):
payload = request.json
signature = payload.get('signature')
if client.verify_webhook_signature(payload, signature):
return response.json({"status": "success"})
else:
return response.json({"error": "Invalid signature"}, status=403)
API Reference
Core Classes
BMLConnect: Main entry point for the SDKTransaction: Transaction object with all transaction detailsQRCode: QR code details for payment processingPaginatedResponse: For paginated transaction listsEnvironment: Enum forSANDBOXandPRODUCTIONenvironmentsSignMethod: Enum for signature methodsTransactionState: Enum for transaction states
Exception Hierarchy
BMLConnectError
├── AuthenticationError
├── ValidationError
├── NotFoundError
├── ServerError
└── RateLimitError
Signature Utilities
from bml_connect import SignatureUtils
# Generate signature
signature = SignatureUtils.generate_signature(data, api_key, method)
# Verify signature
is_valid = SignatureUtils.verify_signature(data, signature, api_key, method)
Advanced Usage
Transaction Management
# Create a transaction
transaction = client.transactions.create_transaction({
"amount": 5000,
"currency": "MVR",
"provider": "alipay",
"redirectUrl": "https://yourstore.com/success",
"localId": "order_456"
})
# Get transaction details
details = client.transactions.get_transaction(transaction.transaction_id)
# List transactions with pagination
transactions = client.transactions.list_transactions(
page=1,
per_page=10,
status="completed"
)
Webhook Handling
@app.route('/webhook', methods=['POST'])
def handle_webhook():
payload = request.get_json()
# Verify webhook signature
if not client.verify_webhook_signature(payload, payload.get('signature')):
return {"error": "Invalid signature"}, 403
# Process different webhook events
event_type = payload.get('event_type')
if event_type == 'transaction.completed':
# Handle completed transaction
transaction_id = payload.get('transaction_id')
# Your business logic here
elif event_type == 'transaction.failed':
# Handle failed transaction
pass
return {"status": "success"}
Requirements
- Python 3.7+
- See
requirements.txtandrequirements-dev.txtfor dependencies
Development
Setup Development Environment
# Clone the repository
git clone https://github.com/quillfires/bml-connect-python.git
cd bml-connect-python
# Install in development mode
pip install -e .[dev]
Running Tests
pytest
Code Quality
# Format code
black .
# Lint code
flake8 .
# Type checking
mypy .
Project Structure
bml-connect-python/
├── src/bml_connect/ # Source code
├── tests/ # Test files
├── examples/ # Usage examples
├── pyproject.toml # Build configuration
├── requirements.txt # Runtime dependencies
├── requirements-dev.txt # Development dependencies
└── README.md # This file
Contributing
We welcome contributions! Please see our Contributing Guidelines for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
Changelog
See CHANGELOG.md for a detailed history of changes.
Security
If you discover any security-related issues, please email fayaz.quill@gmail.com instead of using the issue tracker.
Made with ❤️ for the Maldivian developer community
Project details
Release history Release notifications | RSS feed
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 bml_connect_python-1.1.1.tar.gz.
File metadata
- Download URL: bml_connect_python-1.1.1.tar.gz
- Upload date:
- Size: 12.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
32f7ffe6e3dd3729b407b3165cf29d9d665772149989aa17c5484db69b21fffe
|
|
| MD5 |
5571bd16f07d60f6db495cf3a876a759
|
|
| BLAKE2b-256 |
f35c0aa7893c5c0d506b8441252842cabeec36f1aa6d65368009d9c23e9245f8
|
Provenance
The following attestation bundles were made for bml_connect_python-1.1.1.tar.gz:
Publisher:
release.yml on quillfires/bml-connect-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bml_connect_python-1.1.1.tar.gz -
Subject digest:
32f7ffe6e3dd3729b407b3165cf29d9d665772149989aa17c5484db69b21fffe - Sigstore transparency entry: 999988284
- Sigstore integration time:
-
Permalink:
quillfires/bml-connect-python@09e27c22372a6ecb236329736481246234aeb9c0 -
Branch / Tag:
refs/tags/v1.1.1 - Owner: https://github.com/quillfires
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@09e27c22372a6ecb236329736481246234aeb9c0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file bml_connect_python-1.1.1-py3-none-any.whl.
File metadata
- Download URL: bml_connect_python-1.1.1-py3-none-any.whl
- Upload date:
- Size: 10.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bbb91a47aeaca05031732d1fab77edd4cb5b479f7496204cf70ca967e1ec1c04
|
|
| MD5 |
7c2f6403f5ccaa08b4dc84b7e5f155fc
|
|
| BLAKE2b-256 |
8e393d83748e038cc9d81944a105b00a65e25c9bf7a830837d8551770a970b77
|
Provenance
The following attestation bundles were made for bml_connect_python-1.1.1-py3-none-any.whl:
Publisher:
release.yml on quillfires/bml-connect-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bml_connect_python-1.1.1-py3-none-any.whl -
Subject digest:
bbb91a47aeaca05031732d1fab77edd4cb5b479f7496204cf70ca967e1ec1c04 - Sigstore transparency entry: 999988292
- Sigstore integration time:
-
Permalink:
quillfires/bml-connect-python@09e27c22372a6ecb236329736481246234aeb9c0 -
Branch / Tag:
refs/tags/v1.1.1 - Owner: https://github.com/quillfires
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@09e27c22372a6ecb236329736481246234aeb9c0 -
Trigger Event:
push
-
Statement type: