From 999acd662987d3f13125629d79569acf091c21f9 Mon Sep 17 00:00:00 2001 From: VivianDee <115420678+VivianDee@users.noreply.github.com> Date: Thu, 20 Mar 2025 19:00:32 +0100 Subject: [PATCH] Containerization --- Dockerfile | 21 ++++++ README.md | 60 +++++++----------- app.log | 15 +++++ app/__init__.py | 12 +--- app/blueprints/disbursement.py | 19 ++++-- app/blueprints/revoke_enable_consent.py | 2 +- app/blueprints/transaction_verify.py | 2 +- .../__pycache__/__init__.cpython-312.pyc | Bin 191 -> 0 bytes app/routes/__pycache__/main.cpython-312.pyc | Bin 1388 -> 0 bytes app/schemas/customer_consent.py | 2 +- app/schemas/eligibility_check.py | 2 +- app/schemas/provide_loan.py | 24 +++---- app/schemas/repayment.py | 2 +- app/utils/__pycache__/logger.cpython-312.pyc | Bin 596 -> 0 bytes docker-compose.yml | 11 ++++ requirements.txt | 4 +- 16 files changed, 104 insertions(+), 72 deletions(-) create mode 100644 Dockerfile delete mode 100644 app/routes/__pycache__/__init__.cpython-312.pyc delete mode 100644 app/routes/__pycache__/main.cpython-312.pyc delete mode 100644 app/utils/__pycache__/logger.cpython-312.pyc create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3e3f6f1 --- /dev/null +++ b/Dockerfile @@ -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"] diff --git a/README.md b/README.md index 766577a..35a41e4 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,12 @@ ---- - # 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 Ensure you have the following installed on your system: -- Python 3.x -- pip (Python package installer) +- **Docker**: Install Docker from [docker.com](https://www.docker.com/get-started) +- **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 @@ -21,52 +19,38 @@ git clone https://github.com/username/repository.git 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 -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:** - ```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`: +You can check if the Flask application is running by accessing the `/health` endpoint. To perform a health check, run the following command: ```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 -flask run +docker-compose down ``` - - -### 6. Deactivate the Virtual Environment - -When you're done, deactivate the virtual environment: - -```bash -deactivate -``` +This will stop and remove the containers created by Docker Compose. diff --git a/app.log b/app.log index d8a163a..e06d896 100644 --- a/app.log +++ b/app.log @@ -236,3 +236,18 @@ marshmallow.exceptions.ValidationError: {'lien_amount': ['Missing data for requi 2025-03-20 17:45:41,511 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on http://127.0.0.1:5000 2025-03-20 17:45:41,513 - INFO - Press CTRL+C to quit +2025-03-20 17:51:07,000 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * 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 - Press CTRL+C to quit +2025-03-20 17:51:28,286 - INFO - 172.20.0.1 - - [20/Mar/2025 17:51:28] "GET / HTTP/1.1" 404 - +2025-03-20 17:51:28,603 - INFO - 172.20.0.1 - - [20/Mar/2025 17:51:28] "GET /favicon.ico HTTP/1.1" 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] "GET /health HTTP/1.1" 404 - +2025-03-20 17:53:14,937 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * 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 - Press CTRL+C to quit +2025-03-20 17:53:49,208 - INFO - 172.20.0.1 - - [20/Mar/2025 17:53:49] "GET /health HTTP/1.1" 200 - diff --git a/app/__init__.py b/app/__init__.py index f98c555..179b2a7 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,14 +1,8 @@ from flask import Flask -# from flask_sqlalchemy import SQLAlchemy -from flask_marshmallow import Marshmallow from flask_cors import CORS from app.config import Config from app.routes import api -# Initialize extensions -# db = SQLAlchemy() -ma = Marshmallow() - def create_app(): """ Factory function to create a Flask app instance """ app = Flask(__name__) @@ -16,14 +10,10 @@ def create_app(): # Load configuration app.config.from_object(Config) - # Initialize extensions - # db.init_app(app) - ma.init_app(app) - CORS(app) # Register blueprints - app.register_blueprint(api, url_prefix="/api") + app.register_blueprint(api) return app diff --git a/app/blueprints/disbursement.py b/app/blueprints/disbursement.py index 70eb3a0..b2ad0db 100644 --- a/app/blueprints/disbursement.py +++ b/app/blueprints/disbursement.py @@ -25,12 +25,23 @@ class DisbursementService: # Simulated processing logic response_data = { - "disbursement_id": validated_data.get("disbursement_id", "11223"), - "status": "Completed", - "amount": validated_data.get("amount"), - "recipient_account": validated_data.get("recipient_account"), + "transactionId": "T001", + "TransactionId": "Tr201712RK9232P115", + "debtId": "273194670", + "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( # data=response_data, # message="Disbursement completed successfully" diff --git a/app/blueprints/revoke_enable_consent.py b/app/blueprints/revoke_enable_consent.py index e5266b5..4379d7a 100644 --- a/app/blueprints/revoke_enable_consent.py +++ b/app/blueprints/revoke_enable_consent.py @@ -26,7 +26,7 @@ class RevokeEnableConsentService: # Simulated processing logic response_data = { - "$type": "RevokeEnableConsentResponse", + "type": "RevokeEnableConsentResponse", "customerId": "CN621868", "accountId": "2017821799", "resultCode": "00", diff --git a/app/blueprints/transaction_verify.py b/app/blueprints/transaction_verify.py index 63cfe7f..7aea3a0 100644 --- a/app/blueprints/transaction_verify.py +++ b/app/blueprints/transaction_verify.py @@ -26,7 +26,7 @@ class TransactionVerifyService: # Simulated processing logic response_data = { - "$type": "TransactionCheckResponse", + "type": "TransactionCheckResponse", "nativeId": "FBN20191031104405CN621868", "customerId": "CN621868", "accountId": "2017821799", diff --git a/app/routes/__pycache__/__init__.cpython-312.pyc b/app/routes/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index 2016feda0e585ed0923f59edf4ac1bcd37b22a72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 191 zcmX@j%ge<81nnp7)8&BlV-N=hn4pZ$0zk%eh7^Vr#vF!R#wbQchDs()=9i2>VNJ$c zTxFRlsrm6~si`S`noPG?auYN2ikN|ND;Yk6O!#G@pOK%Ns-KoqT2hi)l$M#7r|+0o zk{Mi(pAY2dCl(aw7v-0hq!#PP$7kkcmc+;F6;%G>u*uC&Da}c>E8+ke0 O$jEq)L8gce$N>N(^DoW- diff --git a/app/routes/__pycache__/main.cpython-312.pyc b/app/routes/__pycache__/main.cpython-312.pyc deleted file mode 100644 index 1324572c858c50a1bf0c9e5841362e7f9aaef342..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1388 zcmah|&1)M+6rb5$t=6mWG_BLPUp{a?L+u?`|X%KT!p(OSRbvcQKp~p!R3xh-f zhkx}8!byh*NxV(yZqSi7izS@_0Ucm7OnN;+g%No{e2yJqeE044U7>&dozq8vQo+7@;6rr6(2UE9H`Z%iuBc3q_3}xDF)YP{Q-v3?|5X8MY?~{4} z)$G-WUXQd6Y_(|hc@#EvYC%+C1aUW^2Ebp?nLOtFW2c`)#Oa13&I#=XaqN5^^MDPL z1QtEV8x9?sj5uMAtg|)T7daJ|z609}@Ug2P#^_(eethTAooV&MKa3kM3s)z%W`)Mo zXwVv%5Asf*cp>lqrya6r)s8X%7)R`D0rvH-2BjHW!erdzBPO(D@ai}4pw$Z@W710? zL@|x)cKW0wQe;piCj1I z*nrCN6!W626mB-kDgm(yM7Qo|_ky)pI`b?|xh$<@kCT|eePA>X!9-OmM?45wE4>Qo zj9IQ5dl7M6VebY$N!%_WzR0N|QbVIy0#@U+BE{+jq371EDDg)j`II)`5J?jI8N^)2 z82^QCoS^j+bn^slz|8%O4|+~kKTuFbG>s%f}+ zrX%g6xkPjOjbHPK9Nkl1o2MGa*Q8f#E|K&qjjudjd$jiC-VDDhgIt&9_Y_jyeGSz+ BJl_BS diff --git a/app/schemas/customer_consent.py b/app/schemas/customer_consent.py index b6f567f..09c2d9c 100644 --- a/app/schemas/customer_consent.py +++ b/app/schemas/customer_consent.py @@ -2,7 +2,7 @@ from marshmallow import Schema, fields # Customer Consent Schema class CustomerConsentSchema(Schema): - type = fields.Str(data_key="$type", required=True) + type = fields.Str(required=True) transactionId = fields.Str(required=True) customerId = fields.Str(required=True) accountId = fields.Str(required=True) diff --git a/app/schemas/eligibility_check.py b/app/schemas/eligibility_check.py index 3b75bb2..41e3a3e 100644 --- a/app/schemas/eligibility_check.py +++ b/app/schemas/eligibility_check.py @@ -1,7 +1,7 @@ from marshmallow import Schema, fields 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") countryCode = fields.Str(data_key="countryCode", required=True, description="Country code (ISO)") customerId = fields.Str(data_key="customerId", required=True, description="Customer ID") diff --git a/app/schemas/provide_loan.py b/app/schemas/provide_loan.py index 9de0cb7..ca82352 100644 --- a/app/schemas/provide_loan.py +++ b/app/schemas/provide_loan.py @@ -2,15 +2,15 @@ from marshmallow import Schema, fields # Provide Loan Schema class ProvideLoanSchema(Schema): - type = fields.Str(required=True, data_key="$type") - request_id = fields.Str(required=True, data_key="requestId") - transaction_id = fields.Str(required=True, data_key="transactionId") - customer_id = fields.Str(required=True, data_key="customerId") - account_id = fields.Str(required=True, data_key="accountId") - msisdn = fields.Str(required=False, data_key="msisdn") - product_id = fields.Str(required=True, data_key="productId") - lien_amount = fields.Float(required=True, data_key="lienAmount") - requested_amount = fields.Float(required=True, data_key="requestedAmount") - collection_type = fields.Int(required=True, data_key="collectionType") - loan_type = fields.Int(required=True, data_key="loanType") - channel = fields.Str(required=True, data_key="channel") \ No newline at end of file + type = fields.Str(required=True) + requestId = fields.Str(required=True) + transactionId = fields.Str(required=True) + customerId = fields.Str(required=True) + accountId = fields.Str(required=True) + msisdn = fields.Str(required=False) + productId = fields.Str(required=True) + lienAmount = fields.Float(required=True) + requestedAmount = fields.Float(required=True) + collectionType = fields.Int(required=True) + loanType = fields.Int(required=True) + channel = fields.Str(required=True) \ No newline at end of file diff --git a/app/schemas/repayment.py b/app/schemas/repayment.py index 6168031..535419c 100644 --- a/app/schemas/repayment.py +++ b/app/schemas/repayment.py @@ -2,7 +2,7 @@ from marshmallow import Schema, fields # Repayment Schema class RepaymentSchema(Schema): - type = fields.Str(data_key="$type", required=True) + type = fields.Str(required=True) msisdn = fields.Str(required=False) #optional debtId = fields.Str(required=True) productId = fields.Str(required=True) diff --git a/app/utils/__pycache__/logger.cpython-312.pyc b/app/utils/__pycache__/logger.cpython-312.pyc deleted file mode 100644 index 0b14459e900c173d3f218463af88c0c69447bbcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmYLFziZn-6uy&e>15;3)P+KXX_i0)iIpy$LP~K74U}~7mZ5OLZ@zq&?Qq(mQ}yu-uJ!tzW3w4H5xT!jD39`budD|b5feO z0C!&uxIzpuEYK0M5TN%~S+w*fT3NCZF>7A$lziz&3pme{WxPbpW|f=jXfY|WZk&-_ zPH{l~7f=!}0`=NRL24&&0rE4t%MZAJ8Xl)Hgncno z3S^%rN%$gBygNu!LqfB1I8$ YYW~IJiMKZP*1r4Ow_f|)k*j9JKg`yV7XSbN diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9da065a --- /dev/null +++ b/docker-compose.yml @@ -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 diff --git a/requirements.txt b/requirements.txt index 6c17099..232eb1c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ # Flask and Extensions Flask==2.3.3 -Flask-SQLAlchemy==3.0.5 +# Flask-SQLAlchemy==3.0.5 Flask-Marshmallow==0.15.0 marshmallow==3.19.0 Flask-Cors==3.0.10 -marshmallow-sqlalchemy==0.29.0 +# marshmallow-sqlalchemy==0.29.0 # mysqlclient==2.2.0