initial commit
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
./vscode
|
||||||
Vendored
+24
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"editor.lineNumbers": "off",
|
||||||
|
"editor.padding.top": 3,
|
||||||
|
"editor.padding.bottom": 3,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.formatOnPaste": true,
|
||||||
|
"editor.fontSize": 14,
|
||||||
|
"editor.lineHeight": 4.5,
|
||||||
|
"editor.suggestFontSize": 15,
|
||||||
|
// "editor.suggestLineHeight": 4,
|
||||||
|
"breadcrumbs.enabled": false,
|
||||||
|
"workbench.tips.enabled": false,
|
||||||
|
"workbench.statusBar.visible": false,
|
||||||
|
// "workbench.editor.showTabs": "single",
|
||||||
|
"git.enableSmartCommit": true,
|
||||||
|
"workbench.editor.editorActionsLocation": "hidden",
|
||||||
|
// "workbench.activityBar.location": "hidden",
|
||||||
|
"workbench.editor.enablePreviewFromQuickOpen": false,
|
||||||
|
"editor.lightbulb.enabled": "off",
|
||||||
|
"editor.selectionHighlight": false,
|
||||||
|
"editor.overviewRulerBorder": false,
|
||||||
|
"editor.renderLineHighlight": "none",
|
||||||
|
"editor.occurrencesHighlight": "off"
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
# Use Python base image
|
||||||
|
FROM python:3.10
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy files to container
|
||||||
|
COPY . /app
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Expose port 5000
|
||||||
|
EXPOSE 5000
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV FLASK_APP=app.py
|
||||||
|
ENV FLASK_RUN_HOST=0.0.0.0
|
||||||
|
|
||||||
|
# Run the application
|
||||||
|
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "wsgi:wsgi_app"]
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,6 @@
|
|||||||
|
from app import create_app
|
||||||
|
|
||||||
|
app = create_app()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(host="0.0.0.0", port=5000, debug=True)
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
from flask import Flask
|
||||||
|
from flask_cors import CORS
|
||||||
|
from app.config import Config
|
||||||
|
from app.routes import auth_bp, eligibility_bp
|
||||||
|
from app.errors import method_not_allowed, unsupported_media_type
|
||||||
|
|
||||||
|
|
||||||
|
def create_app():
|
||||||
|
"""Factory function to create a Flask app instance"""
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# Load configuration
|
||||||
|
app.config.from_object(Config)
|
||||||
|
|
||||||
|
CORS(app)
|
||||||
|
|
||||||
|
# Register blueprints
|
||||||
|
app.register_blueprint(auth_bp)
|
||||||
|
# app.register_blueprint(loan_bp)
|
||||||
|
app.register_blueprint(eligibility_bp, url_prefix="/eligibility")
|
||||||
|
# app.register_blueprint(repayment_bp)
|
||||||
|
|
||||||
|
# Error Handlers
|
||||||
|
app.register_error_handler(405, method_not_allowed)
|
||||||
|
app.register_error_handler(415, unsupported_media_type)
|
||||||
|
|
||||||
|
return app
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,9 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
"""Base configuration for Flask app"""
|
||||||
|
|
||||||
|
SECRET_KEY = os.getenv("SECRET_KEY", "supersecretkey")
|
||||||
|
API_BASE_URL = "https://coreapi.dev.simbrellang.net/v1/api/salary"
|
||||||
|
JWT_SECRET_KEY = os.getenv("JWT_SECRET_KEY", "your_jwt_secret")
|
||||||
|
DEBUG = True
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
from .handlers import method_not_allowed, unsupported_media_type
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,18 @@
|
|||||||
|
from flask import jsonify
|
||||||
|
from app.helpers.response_helper import ResponseHelper
|
||||||
|
|
||||||
|
|
||||||
|
def method_not_allowed(error):
|
||||||
|
return ResponseHelper.method_not_allowed(message="Method Not Allowed")
|
||||||
|
|
||||||
|
|
||||||
|
def not_found(error):
|
||||||
|
return ResponseHelper.not_found(message="URL Not Found")
|
||||||
|
|
||||||
|
|
||||||
|
def bad_request(error):
|
||||||
|
return ResponseHelper.bad_request(message="Bad Request")
|
||||||
|
|
||||||
|
|
||||||
|
def unsupported_media_type(error):
|
||||||
|
return ResponseHelper.error(message="Unsupported Media Type", status_code=415)
|
||||||
Binary file not shown.
@@ -0,0 +1,251 @@
|
|||||||
|
from flask import jsonify
|
||||||
|
from typing import List, Dict, Union, Optional, Any
|
||||||
|
|
||||||
|
|
||||||
|
class ResponseHelper:
|
||||||
|
"""
|
||||||
|
A helper class for building standardized JSON responses in Flask.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def build_response(
|
||||||
|
status: bool,
|
||||||
|
message: str,
|
||||||
|
data: Optional[Union[Dict, List, str]] = None,
|
||||||
|
status_code: int = 200,
|
||||||
|
error: Optional[Union[Dict, str]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Build a standardized JSON response.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
status (bool): Indicates whether the request was successful.
|
||||||
|
message (str): A message describing the result of the request.
|
||||||
|
data (Optional[Union[Dict, List, str]]): The data to return in the response.
|
||||||
|
status_code (int): The HTTP status code for the response.
|
||||||
|
error (Optional[Union[Dict, str]]): Any error details to include in the response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: A dictionary representing the JSON response.
|
||||||
|
"""
|
||||||
|
response = {
|
||||||
|
"status": status,
|
||||||
|
"statusCode": status_code,
|
||||||
|
"message": message,
|
||||||
|
"data": data if data is not None else {},
|
||||||
|
"error": error if error is not None else {},
|
||||||
|
}
|
||||||
|
return jsonify(response), status_code
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def success(
|
||||||
|
data: Optional[Union[Dict, List, str]] = None,
|
||||||
|
message: str = "Successful",
|
||||||
|
status_code: int = 200,
|
||||||
|
error: Optional[Union[Dict, str]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Return a success response.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (Optional[Union[Dict, List, str]]): The data to return in the response.
|
||||||
|
message (str): A message describing the result of the request.
|
||||||
|
status_code (int): The HTTP status code for the response.
|
||||||
|
error (Optional[Union[Dict, str]]): Any error details to include in the response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: A dictionary representing the JSON response.
|
||||||
|
"""
|
||||||
|
return ResponseHelper.build_response(True, message, data, status_code, error)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def error(
|
||||||
|
message: str = "An error occurred",
|
||||||
|
status_code: int = 400,
|
||||||
|
data: Optional[Union[Dict, List, str]] = None,
|
||||||
|
error: Optional[Union[Dict, str]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Return an error response.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): A message describing the error.
|
||||||
|
status_code (int): The HTTP status code for the response.
|
||||||
|
data (Optional[Union[Dict, List, str]]): The data to return in the response.
|
||||||
|
error (Optional[Union[Dict, str]]): Any error details to include in the response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: A dictionary representing the JSON response.
|
||||||
|
"""
|
||||||
|
return ResponseHelper.build_response(False, message, data, status_code, error)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def created(
|
||||||
|
data: Optional[Union[Dict, List, str]] = None,
|
||||||
|
message: str = "Resource created successfully",
|
||||||
|
error: Optional[Union[Dict, str]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Return a response for a created resource.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (Optional[Union[Dict, List, str]]): The data to return in the response.
|
||||||
|
message (str): A message describing the result of the request.
|
||||||
|
error (Optional[Union[Dict, str]]): Any error details to include in the response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: A dictionary representing the JSON response.
|
||||||
|
"""
|
||||||
|
return ResponseHelper.build_response(True, message, data, 201, error)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def updated(
|
||||||
|
data: Optional[Union[Dict, List, str]] = None,
|
||||||
|
message: str = "Resource updated successfully",
|
||||||
|
error: Optional[Union[Dict, str]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Return a response for an updated resource.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (Optional[Union[Dict, List, str]]): The data to return in the response.
|
||||||
|
message (str): A message describing the result of the request.
|
||||||
|
error (Optional[Union[Dict, str]]): Any error details to include in the response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: A dictionary representing the JSON response.
|
||||||
|
"""
|
||||||
|
return ResponseHelper.build_response(True, message, data, 200, error)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def internal_server_error(
|
||||||
|
message: str = "Internal Server Error",
|
||||||
|
data: Optional[Union[Dict, List, str]] = None,
|
||||||
|
error: Optional[Union[Dict, str]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Return a response for an internal server error.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): A message describing the error.
|
||||||
|
data (Optional[Union[Dict, List, str]]): The data to return in the response.
|
||||||
|
error (Optional[Union[Dict, str]]): Any error details to include in the response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: A dictionary representing the JSON response.
|
||||||
|
"""
|
||||||
|
return ResponseHelper.build_response(False, message, data, 500, error)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def unauthorized(
|
||||||
|
message: str = "Unauthorized",
|
||||||
|
data: Optional[Union[Dict, List, str]] = None,
|
||||||
|
error: Optional[Union[Dict, str]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Return a response for an unauthorized request.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): A message describing the error.
|
||||||
|
data (Optional[Union[Dict, List, str]]): The data to return in the response.
|
||||||
|
error (Optional[Union[Dict, str]]): Any error details to include in the response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: A dictionary representing the JSON response.
|
||||||
|
"""
|
||||||
|
return ResponseHelper.build_response(False, message, data, 401, error)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def forbidden(
|
||||||
|
message: str = "Forbidden",
|
||||||
|
data: Optional[Union[Dict, List, str]] = None,
|
||||||
|
error: Optional[Union[Dict, str]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Return a response for a forbidden request.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): A message describing the error.
|
||||||
|
data (Optional[Union[Dict, List, str]]): The data to return in the response.
|
||||||
|
error (Optional[Union[Dict, str]]): Any error details to include in the response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: A dictionary representing the JSON response.
|
||||||
|
"""
|
||||||
|
return ResponseHelper.build_response(False, message, data, 403, error)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def not_found(
|
||||||
|
message: str = "Resource not found",
|
||||||
|
data: Optional[Union[Dict, List, str]] = None,
|
||||||
|
error: Optional[Union[Dict, str]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Return a response for a not found resource.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): A message describing the error.
|
||||||
|
data (Optional[Union[Dict, List, str]]): The data to return in the response.
|
||||||
|
error (Optional[Union[Dict, str]]): Any error details to include in the response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: A dictionary representing the JSON response.
|
||||||
|
"""
|
||||||
|
return ResponseHelper.build_response(False, message, data, 404, error)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def unprocessable_entity(
|
||||||
|
message: str = "Unprocessable entity",
|
||||||
|
data: Optional[Union[Dict, List, str]] = None,
|
||||||
|
error: Optional[Union[Dict, str]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Return a response for an unprocessable entity.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): A message describing the error.
|
||||||
|
data (Optional[Union[Dict, List, str]]): The data to return in the response.
|
||||||
|
error (Optional[Union[Dict, str]]): Any error details to include in the response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: A dictionary representing the JSON response.
|
||||||
|
"""
|
||||||
|
return ResponseHelper.build_response(False, message, data, 422, error)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def method_not_allowed(
|
||||||
|
message: str = "Method Not Allowed",
|
||||||
|
data: Optional[Union[Dict, List, str]] = None,
|
||||||
|
error: Optional[Union[Dict, str]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Return a response for a method not allowed error.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): A message describing the error.
|
||||||
|
data (Optional[Union[Dict, List, str]]): The data to return in the response.
|
||||||
|
error (Optional[Union[Dict, str]]): Any error details to include in the response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: A dictionary representing the JSON response.
|
||||||
|
"""
|
||||||
|
return ResponseHelper.build_response(False, message, data, 405, error)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def bad_request(
|
||||||
|
message: str = "Bad Request",
|
||||||
|
data: Optional[Union[Dict, List, str]] = None,
|
||||||
|
error: Optional[Union[Dict, str]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Return a response for a bad request error.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): A message describing the error.
|
||||||
|
data (Optional[Union[Dict, List, str]]): The data to return in the response.
|
||||||
|
error (Optional[Union[Dict, str]]): Any error details to include in the response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: A dictionary representing the JSON response.
|
||||||
|
"""
|
||||||
|
return ResponseHelper.build_response(False, message, data, 400, error)
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
from .authentication import auth_bp
|
||||||
|
from .eligibility import eligibility_bp
|
||||||
|
# from .loan import loan_bp
|
||||||
|
# from .repayment import repayment_bp
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
from flask import Blueprint, request, jsonify
|
||||||
|
import requests
|
||||||
|
from app.utils.auth import get_headers
|
||||||
|
|
||||||
|
auth_bp = Blueprint("auth", __name__)
|
||||||
|
|
||||||
|
@auth_bp.route("/health", methods=["GET"])
|
||||||
|
def health():
|
||||||
|
return jsonify({"status": "Up"})
|
||||||
|
|
||||||
|
@auth_bp.route("/login", methods=["POST"])
|
||||||
|
def login():
|
||||||
|
data = request.json
|
||||||
|
api_url = "https://coreapi.dev.simbrellang.net/api/auth/login"
|
||||||
|
|
||||||
|
response = requests.post(api_url, json=data)
|
||||||
|
if response.status_code == 200:
|
||||||
|
return jsonify(response.json()), 200
|
||||||
|
return jsonify({"error": "Invalid credentials"}), response.status_code
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
from flask import Blueprint, request, jsonify, current_app
|
||||||
|
import requests
|
||||||
|
from app.utils.auth import get_headers
|
||||||
|
|
||||||
|
eligibility_bp = Blueprint("eligibility", __name__)
|
||||||
|
|
||||||
|
|
||||||
|
@eligibility_bp.route("/check", methods=["POST"])
|
||||||
|
def eligibility_check():
|
||||||
|
data = request.json
|
||||||
|
api_url = f"{current_app.config['API_BASE_URL']}/EligibilityCheck"
|
||||||
|
|
||||||
|
print(api_url)
|
||||||
|
|
||||||
|
# response = requests.post(api_url, json=data, headers=get_headers())
|
||||||
|
# return jsonify(response.json()), response.status_code
|
||||||
|
response = {
|
||||||
|
"customerId": "CN621868",
|
||||||
|
"transactionId": "Tr201712RK9232P115",
|
||||||
|
"countryCode": "NGR",
|
||||||
|
"msisdn": "2348012345678",
|
||||||
|
"eligibleOffers": [
|
||||||
|
{
|
||||||
|
"offerId": 101,
|
||||||
|
"minAmount": 5000,
|
||||||
|
"maxAmount": 20000,
|
||||||
|
"productId": 2030,
|
||||||
|
"tenor": 30,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"offerId": 102,
|
||||||
|
"minAmount": 20000,
|
||||||
|
"maxAmount": 50000,
|
||||||
|
"productId": 2090,
|
||||||
|
"tenor": 90,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"resultCode": "00",
|
||||||
|
"resultDescription": "Successful",
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonify(response), 200
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
|||||||
|
import requests
|
||||||
|
from flask import current_app
|
||||||
|
|
||||||
|
def get_headers():
|
||||||
|
return {
|
||||||
|
"Authorization": f"Bearer {current_app.config['JWT_SECRET_KEY']}",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
# Configure logging
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format="%(asctime)s - %(levelname)s - %(message)s",
|
||||||
|
handlers=[
|
||||||
|
# logging.StreamHandler(), # Log to console
|
||||||
|
logging.FileHandler("app.log", mode='a') # Log to file
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
logger = logging.getLogger("DetectionService")
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
flask:
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- "5000:5000"
|
||||||
|
environment:
|
||||||
|
- FLASK_APP=app.py
|
||||||
|
- FLASK_RUN_HOST=0.0.0.0
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- digital
|
||||||
|
|
||||||
|
swagger:
|
||||||
|
image: swaggerapi/swagger-ui
|
||||||
|
ports:
|
||||||
|
- "9000:8080"
|
||||||
|
volumes:
|
||||||
|
- ./openapi.yml:/usr/local/openapi.yml
|
||||||
|
environment:
|
||||||
|
- SWAGGER_JSON=/usr/local/openapi.yml
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- digital
|
||||||
|
networks:
|
||||||
|
digital:
|
||||||
|
driver: bridge
|
||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
openapi: 3.0.3
|
||||||
|
info:
|
||||||
|
title: Sample Flask API
|
||||||
|
description: A simple Flask API with Swagger documentation running in Docker
|
||||||
|
version: 1.0.0
|
||||||
|
contact:
|
||||||
|
name: API Support
|
||||||
|
email: support@example.com
|
||||||
|
license:
|
||||||
|
name: MIT
|
||||||
|
url: https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
servers:
|
||||||
|
- url: http://localhost:5000
|
||||||
|
description: Local development server
|
||||||
|
|
||||||
|
paths:
|
||||||
|
/health:
|
||||||
|
get:
|
||||||
|
summary: Returns a health message
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: A successful response
|
||||||
|
/eligibility/check:
|
||||||
|
post:
|
||||||
|
summary: Performs eligibility check on a user
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
transactionId:
|
||||||
|
type: string
|
||||||
|
description: The transaction ID
|
||||||
|
example: Tr201712RK9232P115
|
||||||
|
customerId:
|
||||||
|
type: string
|
||||||
|
description: The customer ID
|
||||||
|
example: CN621868
|
||||||
|
countryCode:
|
||||||
|
type: string
|
||||||
|
description: The country code
|
||||||
|
example: NGR
|
||||||
|
accountId:
|
||||||
|
type: string
|
||||||
|
description: The account ID
|
||||||
|
example: ACN8263457
|
||||||
|
msisdn:
|
||||||
|
type: string
|
||||||
|
description: The MSISDN
|
||||||
|
example: 8012345678
|
||||||
|
channel:
|
||||||
|
type: string
|
||||||
|
description: The channel
|
||||||
|
example: 100
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: A successful response
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Flask and Extensions
|
||||||
|
Flask==2.3.3
|
||||||
|
Flask-Marshmallow==0.15.0
|
||||||
|
marshmallow==3.19.0
|
||||||
|
Flask-Cors==3.0.10
|
||||||
|
gunicorn
|
||||||
|
requests
|
||||||
Reference in New Issue
Block a user