[go: up one dir, main page]

0% found this document useful (0 votes)
9 views5 pages

Ecinetwireless Backend Code4

This document outlines a Flask application that interacts with the Econet XML-RPC API for various operations such as loading airtime, purchasing data bundles, deducting value, checking account balances, and validating MSISDNs. It includes environment variable validation, request handling, and response validation for each API endpoint. The application also implements logging and basic validation for input parameters.

Uploaded by

emeliamakore
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views5 pages

Ecinetwireless Backend Code4

This document outlines a Flask application that interacts with the Econet XML-RPC API for various operations such as loading airtime, purchasing data bundles, deducting value, checking account balances, and validating MSISDNs. It includes environment variable validation, request handling, and response validation for each API endpoint. The application also implements logging and basic validation for input parameters.

Uploaded by

emeliamakore
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

from flask import Flask, request, jsonify

import xmlrpc.client
import xmltodict
import os
import logging
import re

# Initialize Flask app


app = Flask(__name__)

# Configure logging
logging.basicConfig(level=logging.DEBUG)

# Load environment variables


ECONET_USERNAME = os.environ.get("ECONET_USERNAME")
ECONET_PASSWORD = os.environ.get("ECONET_PASSWORD")
ECONET_API_URL = os.environ.get("ECONET_API_URL",
"https://your_econet_api_url/xmlrpc")

# Validate environment variables


if not ECONET_USERNAME or not ECONET_PASSWORD:
raise ValueError("Econet username and password must be set as environment
variables.")
if not ECONET_API_URL or ECONET_API_URL == "https://your_econet_api_url/xmlrpc":
raise ValueError("ECONET_API_URL must be set to a valid endpoint.")

# Helper function to validate MSISDN format (basic validation)


def validate_msisdn_format(msisdn):
pattern = r"^\+?1?\d{9,15}$" # Adjust pattern as per the MSISDN format
return re.match(pattern, msisdn)

# Common function to handle API request and response validation


def common_api_request(method_name, api_params, required_fields):
"""Handles API request and validates response structure."""
response = call_econet_api(method_name, api_params)
if validate_response(response, required_fields):
return jsonify(response), 200
return jsonify({"error": "Invalid response structure from Econet API"}), 500

def call_econet_api(method_name, params):


"""Calls the Econet XML-RPC API."""
try:
server = xmlrpc.client.ServerProxy(ECONET_API_URL)
api_params = [ECONET_USERNAME, ECONET_PASSWORD]
api_params.append(params)
result = getattr(server, method_name)(*api_params)

if isinstance(result, str):
# Use xmltodict for simplified XML parsing
try:
response_data = xmltodict.parse(result)
return response_data
except Exception as e:
logging.error(f"Failed to parse XML: {e}")
return None
else:
logging.error(f"Unexpected response from Econet API: {result}")
return None
except xmlrpc.client.Fault as e:
logging.error(f"XML-RPC Fault: {e}")
return None
except Exception as e:
logging.error(f"An error occurred: {e}")
return None

def validate_response(response, required_fields):


"""Validates that the response contains the required fields."""
if not response:
return False
for field in required_fields:
if field not in response:
return False
return True

@app.route("/api/airtime/load", methods=["POST"])
def load_airtime():
"""Loads airtime to a specified MSISDN."""
data = request.get_json()
msisdn = data.get("msisdn")
amount = data.get("amount")
reference = data.get("reference")
currency = data.get("currency", 840) # Default to USD (840) if not provided

# Validate required fields


if not msisdn or not amount or not reference:
return jsonify({"error": "Missing msisdn, amount, or reference"}), 400

# Validate MSISDN format


if not validate_msisdn_format(msisdn):
return jsonify({"error": "Invalid MSISDN format"}), 400

# Validate amount and currency


try:
amount = int(amount)
currency = int(currency)
except ValueError:
return jsonify({"error": "Amount and Currency must be valid integers"}),
400

api_params = {
"MSISDN": str(msisdn),
"Amount": amount,
"Reference": str(reference),
"Currency": currency # Defaults to 840 (USD)
}

return common_api_request("load_value", api_params, ["Status", "StatusCode",


"Description"])

@app.route("/api/bundle/load", methods=["POST"])
def load_bundle():
"""Purchases a data bundle for a specified MSISDN."""
data = request.get_json()
msisdn = data.get("msisdn")
provider_code = data.get("provider_code")
amount = data.get("amount")
currency = data.get("currency", 840) # Default to USD (840) if not provided
account_type = data.get("account_type")
quantity = data.get("quantity")
reference = data.get("reference")
product_code = data.get("product_code")

# Validate required fields


if not msisdn or not provider_code or not amount or not currency or not
account_type or not quantity or not reference or not product_code:
return jsonify({"error": "Missing required parameters for load_bundle"}),
400

# Validate MSISDN format


if not validate_msisdn_format(msisdn):
return jsonify({"error": "Invalid MSISDN format"}), 400

# Validate amount, currency, and quantity


try:
amount = int(amount)
currency = int(currency)
quantity = int(quantity)
except ValueError:
return jsonify({"error": "Amount, Currency, and Quantity must be valid
integers"}), 400

api_params = {
"MSISDN": str(msisdn),
"ProviderCode": int(provider_code),
"Amount": amount,
"Currency": currency, # Defaults to 840 (USD)
"AccountType": int(account_type),
"Quantity": quantity,
"Reference": str(reference),
"ProductCode": str(product_code)
}

return common_api_request("load_bundle", api_params, ["Status", "StatusCode",


"Description"])

@app.route("/api/value/deduct", methods=["POST"])
def deduct_value():
"""Deducts airtime value from a specified MSISDN."""
data = request.get_json()
msisdn = data.get("msisdn")
provider_code = data.get("provider_code")
amount = data.get("amount")
reference = data.get("reference")

# Validate required fields


if not msisdn or not provider_code or not amount or not reference:
return jsonify({"error": "Missing required parameters for deduct_value"}),
400

# Validate MSISDN format


if not validate_msisdn_format(msisdn):
return jsonify({"error": "Invalid MSISDN format"}), 400

# Validate amount
try:
amount = int(amount)
except ValueError:
return jsonify({"error": "Amount must be a valid integer"}), 400

api_params = {
"MSISDN": str(msisdn),
"ProviderCode": int(provider_code),
"Amount": amount,
"Reference": str(reference)
}

return common_api_request("deduct_value", api_params, ["Status", "StatusCode",


"Description"])

@app.route("/api/balance", methods=["POST"])
def account_balance_enquiry():
"""Enquires the balance of a specified MSISDN."""
data = request.get_json()
msisdn = data.get("msisdn")
provider_code = data.get("provider_code")

# Validate required fields


if not msisdn or not provider_code:
return jsonify({"error": "Missing msisdn and provider_code"}), 400

# Validate MSISDN format


if not validate_msisdn_format(msisdn):
return jsonify({"error": "Invalid MSISDN format"}), 400

api_params = {
"MSISDN": str(msisdn),
"ProviderCode": int(provider_code)
}

return common_api_request("account_balance_enquiry", api_params,


["AccountType", "Currency", "Amount"])

@app.route("/api/msisdn/validate", methods=["POST"])
def validate_msisdn():
"""Validates a specified MSISDN."""
data = request.get_json()
msisdn = data.get("msisdn")
provider_code = data.get("provider_code")

# Validate required fields


if not msisdn or not provider_code:
return jsonify({"error": "Missing msisdn and provider_code"}), 400

# Validate MSISDN format


if not validate_msisdn_format(msisdn):
return jsonify({"error": "Invalid MSISDN format"}), 400

api_params = {
"MSISDN": str(msisdn),
"ProviderCode": int(provider_code)
}

return common_api_request("validate_msisdn", api_params, ["Status",


"StatusCode", "Description"])
@app.route("/api/transaction/status", methods=["POST"])
def get_transaction_status():
"""Checks the status of a previously submitted transaction."""
data = request.get_json()
reference = data.get("reference")

# Validate required fields


if not reference:
return jsonify({"error": "Missing reference"}), 400

api_params = {
"Reference": str(reference)
}

return common_api_request("get_transaction_status", api_params, ["Status",


"StatusCode", "Description"])

@app.route("/api/account/transfer", methods=["POST"])
def account_transfer():
"""Transfers funds between company accounts."""
data = request.get_json()
from_company_id = data.get("from_company_id")
to_company_id = data.get("to_company_id")
currency = data.get("currency", 840) # Default to USD (840) if not provided
amount = data.get("amount")
reference = data.get("reference")

# Validate required fields


if not from_company_id or not to_company_id or not currency or not amount or
not reference:
return jsonify({"error": "Missing required parameters for
account_transfer"}), 400

# Validate amount and currency


try:
amount = int(amount)
currency = int(currency)
except ValueError:
return jsonify({"error": "Amount and Currency must be valid integers"}),
400

api_params = {
"FromCompanyID": int(from_company_id),
"ToCompanyID": int(to_company_id),
"Currency": currency, # Defaults to 840 (USD)
"Amount": amount,
"Reference": str(reference)
}

return common_api_request("account_transfer", api_params, ["Status",


"StatusCode", "Description"])

if __name__ == "__main__":
app.run(debug=True)

You might also like