Containerization
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
|||||||
|
# Use an official Python runtime as a parent image
|
||||||
|
FROM python:3.9-slim
|
||||||
|
|
||||||
|
# Set the working directory in the container
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy the current directory contents into the container at /app
|
||||||
|
COPY . /app
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Expose port 5000 for the Flask app
|
||||||
|
EXPOSE 5000
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV FLASK_APP=app.py
|
||||||
|
ENV FLASK_RUN_HOST=0.0.0.0
|
||||||
|
|
||||||
|
# Run the application
|
||||||
|
CMD ["flask", "run"]
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
---
|
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
|
|
||||||
This guide provides instructions on how to set up and run the Python application in a virtual environment.
|
This guide provides instructions on how to set up and run the application.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
Ensure you have the following installed on your system:
|
Ensure you have the following installed on your system:
|
||||||
- Python 3.x
|
- **Docker**: Install Docker from [docker.com](https://www.docker.com/get-started)
|
||||||
- pip (Python package installer)
|
- **Docker Compose**: Docker Compose is included with Docker Desktop (for macOS/Windows) or can be installed separately on Linux.
|
||||||
|
|
||||||
## Steps to Set Up the Application
|
## Steps to Set Up the Application
|
||||||
|
|
||||||
@@ -21,52 +19,38 @@ git clone https://github.com/username/repository.git
|
|||||||
cd repository
|
cd repository
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Create a Virtual Environment
|
### 2. Run the Application with Docker Compose
|
||||||
|
|
||||||
Create a virtual environment to isolate your dependencies:
|
Once you have the repository cloned, you can easily set up and run the application using Docker Compose. Simply execute the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv venv
|
docker-compose up --build
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Activate the Virtual Environment
|
This command will build the Docker image and start the Flask application in a container. By default, the application will be accessible at `http://localhost:5000`.
|
||||||
|
|
||||||
Activate the virtual environment:
|
### 3. Health Check
|
||||||
|
|
||||||
- **For Windows:**
|
You can check if the Flask application is running by accessing the `/health` endpoint. To perform a health check, run the following command:
|
||||||
```bash
|
|
||||||
venv\Scripts\activate
|
|
||||||
```
|
|
||||||
|
|
||||||
- **For macOS/Linux:**
|
|
||||||
```bash
|
|
||||||
source venv/bin/activate
|
|
||||||
```
|
|
||||||
|
|
||||||
Once activated, you should see `(venv)` at the beginning of your terminal prompt.
|
|
||||||
|
|
||||||
### 4. Install Dependencies
|
|
||||||
|
|
||||||
Install the required dependencies listed in `requirements.txt`:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install -r requirements.txt
|
curl http://localhost:5000/health
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. Run the Application
|
If the application is running properly, you should receive a response similar to this:
|
||||||
|
|
||||||
Start the application:
|
```json
|
||||||
|
{
|
||||||
|
"status": "ok"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Stop the Application
|
||||||
|
|
||||||
|
To stop the application, use:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
flask run
|
docker-compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This will stop and remove the containers created by Docker Compose.
|
||||||
|
|
||||||
### 6. Deactivate the Virtual Environment
|
|
||||||
|
|
||||||
When you're done, deactivate the virtual environment:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
deactivate
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -236,3 +236,18 @@ marshmallow.exceptions.ValidationError: {'lien_amount': ['Missing data for requi
|
|||||||
2025-03-20 17:45:41,511 - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
2025-03-20 17:45:41,511 - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||||
* Running on http://127.0.0.1:5000
|
* Running on http://127.0.0.1:5000
|
||||||
2025-03-20 17:45:41,513 - INFO - [33mPress CTRL+C to quit[0m
|
2025-03-20 17:45:41,513 - INFO - [33mPress CTRL+C to quit[0m
|
||||||
|
2025-03-20 17:51:07,000 - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||||
|
* Running on all addresses (0.0.0.0)
|
||||||
|
* Running on http://127.0.0.1:5000
|
||||||
|
* Running on http://172.20.0.2:5000
|
||||||
|
2025-03-20 17:51:07,001 - INFO - [33mPress CTRL+C to quit[0m
|
||||||
|
2025-03-20 17:51:28,286 - INFO - 172.20.0.1 - - [20/Mar/2025 17:51:28] "[33mGET / HTTP/1.1[0m" 404 -
|
||||||
|
2025-03-20 17:51:28,603 - INFO - 172.20.0.1 - - [20/Mar/2025 17:51:28] "[33mGET /favicon.ico HTTP/1.1[0m" 404 -
|
||||||
|
2025-03-20 17:51:38,063 - INFO - 172.20.0.1 - - [20/Mar/2025 17:51:38] "GET /api/health HTTP/1.1" 200 -
|
||||||
|
2025-03-20 17:52:29,740 - INFO - 172.20.0.1 - - [20/Mar/2025 17:52:29] "[33mGET /health HTTP/1.1[0m" 404 -
|
||||||
|
2025-03-20 17:53:14,937 - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||||
|
* Running on all addresses (0.0.0.0)
|
||||||
|
* Running on http://127.0.0.1:5000
|
||||||
|
* Running on http://172.20.0.2:5000
|
||||||
|
2025-03-20 17:53:14,938 - INFO - [33mPress CTRL+C to quit[0m
|
||||||
|
2025-03-20 17:53:49,208 - INFO - 172.20.0.1 - - [20/Mar/2025 17:53:49] "GET /health HTTP/1.1" 200 -
|
||||||
|
|||||||
+1
-11
@@ -1,14 +1,8 @@
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
# from flask_sqlalchemy import SQLAlchemy
|
|
||||||
from flask_marshmallow import Marshmallow
|
|
||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
from app.config import Config
|
from app.config import Config
|
||||||
from app.routes import api
|
from app.routes import api
|
||||||
|
|
||||||
# Initialize extensions
|
|
||||||
# db = SQLAlchemy()
|
|
||||||
ma = Marshmallow()
|
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
""" Factory function to create a Flask app instance """
|
""" Factory function to create a Flask app instance """
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@@ -16,14 +10,10 @@ def create_app():
|
|||||||
# Load configuration
|
# Load configuration
|
||||||
app.config.from_object(Config)
|
app.config.from_object(Config)
|
||||||
|
|
||||||
# Initialize extensions
|
|
||||||
# db.init_app(app)
|
|
||||||
ma.init_app(app)
|
|
||||||
|
|
||||||
|
|
||||||
CORS(app)
|
CORS(app)
|
||||||
|
|
||||||
# Register blueprints
|
# Register blueprints
|
||||||
app.register_blueprint(api, url_prefix="/api")
|
app.register_blueprint(api)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|||||||
@@ -25,12 +25,23 @@ class DisbursementService:
|
|||||||
|
|
||||||
# Simulated processing logic
|
# Simulated processing logic
|
||||||
response_data = {
|
response_data = {
|
||||||
"disbursement_id": validated_data.get("disbursement_id", "11223"),
|
"transactionId": "T001",
|
||||||
"status": "Completed",
|
"TransactionId": "Tr201712RK9232P115",
|
||||||
"amount": validated_data.get("amount"),
|
"debtId": "273194670",
|
||||||
"recipient_account": validated_data.get("recipient_account"),
|
"customerId": "CN621868",
|
||||||
|
"accountId": "2017821799",
|
||||||
|
"productId": "101",
|
||||||
|
"provideAmount": 100000.0,
|
||||||
|
"collectAmountInterest": 5000,
|
||||||
|
"collectAmountMgtFee": 1000,
|
||||||
|
"collectAmountInsurance": 1000,
|
||||||
|
"collectAmountVAT": 75,
|
||||||
|
"countryId": "01",
|
||||||
|
"resultCode": "00",
|
||||||
|
"resultDescription": "Loan Request Completed Successfully!"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# return ResponseHelper.success(
|
# return ResponseHelper.success(
|
||||||
# data=response_data,
|
# data=response_data,
|
||||||
# message="Disbursement completed successfully"
|
# message="Disbursement completed successfully"
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class RevokeEnableConsentService:
|
|||||||
|
|
||||||
# Simulated processing logic
|
# Simulated processing logic
|
||||||
response_data = {
|
response_data = {
|
||||||
"$type": "RevokeEnableConsentResponse",
|
"type": "RevokeEnableConsentResponse",
|
||||||
"customerId": "CN621868",
|
"customerId": "CN621868",
|
||||||
"accountId": "2017821799",
|
"accountId": "2017821799",
|
||||||
"resultCode": "00",
|
"resultCode": "00",
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class TransactionVerifyService:
|
|||||||
|
|
||||||
# Simulated processing logic
|
# Simulated processing logic
|
||||||
response_data = {
|
response_data = {
|
||||||
"$type": "TransactionCheckResponse",
|
"type": "TransactionCheckResponse",
|
||||||
"nativeId": "FBN20191031104405CN621868",
|
"nativeId": "FBN20191031104405CN621868",
|
||||||
"customerId": "CN621868",
|
"customerId": "CN621868",
|
||||||
"accountId": "2017821799",
|
"accountId": "2017821799",
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -2,7 +2,7 @@ from marshmallow import Schema, fields
|
|||||||
|
|
||||||
# Customer Consent Schema
|
# Customer Consent Schema
|
||||||
class CustomerConsentSchema(Schema):
|
class CustomerConsentSchema(Schema):
|
||||||
type = fields.Str(data_key="$type", required=True)
|
type = fields.Str(required=True)
|
||||||
transactionId = fields.Str(required=True)
|
transactionId = fields.Str(required=True)
|
||||||
customerId = fields.Str(required=True)
|
customerId = fields.Str(required=True)
|
||||||
accountId = fields.Str(required=True)
|
accountId = fields.Str(required=True)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from marshmallow import Schema, fields
|
from marshmallow import Schema, fields
|
||||||
|
|
||||||
class EligibilityCheckSchema(Schema):
|
class EligibilityCheckSchema(Schema):
|
||||||
type = fields.Str(data_key="$type", required=True, description="Request type")
|
type = fields.Str(required=True, description="Request type")
|
||||||
transactionId = fields.Str(data_key="transactionId", required=True, description="Transaction ID")
|
transactionId = fields.Str(data_key="transactionId", required=True, description="Transaction ID")
|
||||||
countryCode = fields.Str(data_key="countryCode", required=True, description="Country code (ISO)")
|
countryCode = fields.Str(data_key="countryCode", required=True, description="Country code (ISO)")
|
||||||
customerId = fields.Str(data_key="customerId", required=True, description="Customer ID")
|
customerId = fields.Str(data_key="customerId", required=True, description="Customer ID")
|
||||||
|
|||||||
+12
-12
@@ -2,15 +2,15 @@ from marshmallow import Schema, fields
|
|||||||
|
|
||||||
# Provide Loan Schema
|
# Provide Loan Schema
|
||||||
class ProvideLoanSchema(Schema):
|
class ProvideLoanSchema(Schema):
|
||||||
type = fields.Str(required=True, data_key="$type")
|
type = fields.Str(required=True)
|
||||||
request_id = fields.Str(required=True, data_key="requestId")
|
requestId = fields.Str(required=True)
|
||||||
transaction_id = fields.Str(required=True, data_key="transactionId")
|
transactionId = fields.Str(required=True)
|
||||||
customer_id = fields.Str(required=True, data_key="customerId")
|
customerId = fields.Str(required=True)
|
||||||
account_id = fields.Str(required=True, data_key="accountId")
|
accountId = fields.Str(required=True)
|
||||||
msisdn = fields.Str(required=False, data_key="msisdn")
|
msisdn = fields.Str(required=False)
|
||||||
product_id = fields.Str(required=True, data_key="productId")
|
productId = fields.Str(required=True)
|
||||||
lien_amount = fields.Float(required=True, data_key="lienAmount")
|
lienAmount = fields.Float(required=True)
|
||||||
requested_amount = fields.Float(required=True, data_key="requestedAmount")
|
requestedAmount = fields.Float(required=True)
|
||||||
collection_type = fields.Int(required=True, data_key="collectionType")
|
collectionType = fields.Int(required=True)
|
||||||
loan_type = fields.Int(required=True, data_key="loanType")
|
loanType = fields.Int(required=True)
|
||||||
channel = fields.Str(required=True, data_key="channel")
|
channel = fields.Str(required=True)
|
||||||
@@ -2,7 +2,7 @@ from marshmallow import Schema, fields
|
|||||||
|
|
||||||
# Repayment Schema
|
# Repayment Schema
|
||||||
class RepaymentSchema(Schema):
|
class RepaymentSchema(Schema):
|
||||||
type = fields.Str(data_key="$type", required=True)
|
type = fields.Str(required=True)
|
||||||
msisdn = fields.Str(required=False) #optional
|
msisdn = fields.Str(required=False) #optional
|
||||||
debtId = fields.Str(required=True)
|
debtId = fields.Str(required=True)
|
||||||
productId = fields.Str(required=True)
|
productId = fields.Str(required=True)
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,11 @@
|
|||||||
|
services:
|
||||||
|
web:
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- "5000:5000"
|
||||||
|
environment:
|
||||||
|
- FLASK_APP=app.py
|
||||||
|
- FLASK_RUN_HOST=0.0.0.0
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
restart: always
|
||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
# Flask and Extensions
|
# Flask and Extensions
|
||||||
Flask==2.3.3
|
Flask==2.3.3
|
||||||
Flask-SQLAlchemy==3.0.5
|
# Flask-SQLAlchemy==3.0.5
|
||||||
Flask-Marshmallow==0.15.0
|
Flask-Marshmallow==0.15.0
|
||||||
marshmallow==3.19.0
|
marshmallow==3.19.0
|
||||||
Flask-Cors==3.0.10
|
Flask-Cors==3.0.10
|
||||||
marshmallow-sqlalchemy==0.29.0
|
# marshmallow-sqlalchemy==0.29.0
|
||||||
# mysqlclient==2.2.0
|
# mysqlclient==2.2.0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user