Skip to content

Commit 5c857f0

Browse files
committed
first stable version
1 parent 2c27335 commit 5c857f0

24 files changed

+624
-1
lines changed

.env.example

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Server Config
2+
3+
DEBUG=SACRET #True or False
4+
ALLOWED_HOSTS=SACRET
5+
SERVER_HOST=SACRET
6+
SERVER_PORT=SACRET
7+
8+
# Database Config
9+
10+
MASTER_DB_NAME=SACRET
11+
MASTER_DB_USER=SACRET
12+
MASTER_DB_PASSWORD=SACRET
13+
MASTER_DB_HOST=SACRET
14+
MASTER_DB_PORT=SACRET
15+
MASTER_DB_LOG_MODE=SACRET #True or False
16+
17+
# Flask Settings
18+
19+
SQLALCHEMY_TRACK_MODIFICATIONS = SACRET
20+
TESTING = SACRET
21+
DEBUG = SACRET
22+
FLASK_ENV = SACRET
23+
JWT_SECRET_KEY = SACRET

.gitignore

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Binaries for programs and plugins
2+
.env
3+
*.exe
4+
*.exe~
5+
*.dll
6+
*.so
7+
*.dylib
8+
*.env
9+
10+
# Test binary, built with `go test -c`
11+
*.test
12+
13+
# Output of the go coverage tool, specifically when used with LiteIDE
14+
*.out
15+
16+
# Dependency directories (remove the comment below to include it)
17+
# vendor/
18+
.idea/
19+
vendor/
20+
.vscode/
21+
tmp/
22+
23+
#Envs
24+
.venv
25+
venv/
26+
27+
#Some python additional
28+
__pycache__
29+
.pytest_cache

README.md

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,103 @@
1-
# python-flask-postgresql-boilerplate
1+
2+
# Project Desc
3+
24
A example Docker powered boilerplate of using postgresql with python flask
5+
6+
7+
## Tech Stack
8+
9+
**Software Language:** Python
10+
11+
**Framework:** Flask Framework
12+
13+
**Database Type:** PostgreSQL
14+
15+
**Extras:** Docker, JWT, Pytest
16+
17+
18+
## License
19+
20+
[MIT](https://choosealicense.com/licenses/mit/)
21+
22+
23+
## API Reference
24+
25+
#### Register
26+
27+
```http
28+
POST /api/v3/merchant/user/register
29+
```
30+
31+
| Parameter | Type | Description |
32+
| :-------- | :------- | :------------------------- |
33+
| `email` | `string` | **Required**. |
34+
| `password`| `string` | **Required**. |
35+
36+
## ##
37+
## ##
38+
39+
#### Login
40+
41+
```http
42+
POST /api/v3/merchant/user/login
43+
```
44+
45+
| Parameter | Type | Description |
46+
| :-------- | :------- | :------------------------- |
47+
| `email` | `string` | **Required**. |
48+
| `password`| `string` | **Required**. |
49+
50+
51+
Response:
52+
```http
53+
{
54+
"status": "APPROVED",
55+
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY3MTAxNjIwMiwianRpIjoiNDkwZDFlMmUtOTUyNS00YTExLTg2ODAtZDRiYWNlMWNiYjBlIiwidHlwZSI6ImFjY2VzcyIsInN1YiI6IntcImNoZWNrX3Bhc3N3b3JkXCI6IG51bGwsIFwiZW1haWxcIjogXCJlbWFpbFwiLCBcImZpbmRfYnlfZW1haWxcIjogbnVsbCwgXCJmaW5kX2J5X2lkXCI6IG51bGwsIFwiaWRcIjogMiwgXCJwYXNzd29yZFwiOiBcInBhc3N3b3JkXCIsIFwicXVlcnlcIjogbnVsbCwgXCJxdWVyeV9jbGFzc1wiOiBudWxsLCBcInJlZ2lzdHJ5XCI6IG51bGwsIFwic2F2ZV90b19kYlwiOiBudWxsfSIsIm5iZiI6MTY3MTAxNjIwMiwiZXhwIjoxNjcxMDE2ODAyfQ.UwclY2gs4SfjROa8r3XW8NeDqdFLFM54JL4aJtGABb4"
56+
}
57+
```
58+
59+
## ##
60+
## ##
61+
62+
#### Transaction
63+
64+
```http
65+
POST /api/items/${id}
66+
```
67+
68+
**NEED JWT BEARER TOKEN (Required, in header)**
69+
70+
| Parameter | Type | Description |
71+
| :-------- | :------- | :-------------------------------- |
72+
| `fromDate` | `string` | **Required**. Ex: "2022-12-11" |
73+
| `toDate` | `string` | **Required**. Ex: "2022-12-14" |
74+
| `merchant` | `integer` | **Required**. Ex: 1 |
75+
| `acquirer` | `integer` | **Required**. Ex: 2 |
76+
77+
Response:
78+
```http
79+
{
80+
"response": [
81+
{
82+
"count": 2,
83+
"currency": "USD",
84+
"total": 33
85+
},
86+
{
87+
"count": 2,
88+
"currency": "GBP",
89+
"total": 85
90+
}
91+
],
92+
"status": "APPROVED"
93+
}
94+
```
95+
## ##
96+
97+
98+
## Example DB
99+
100+
The sample database in the main file of the project in CSV format.
101+
102+
`example.csv`
103+

app/Dockerfile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Start from golang base image
2+
FROM python:3.10-alpine
3+
4+
# Working directory
5+
WORKDIR /app
6+
7+
# Copy requirments files
8+
COPY requirements.txt ./
9+
10+
# Install requirments
11+
RUN pip3 install --no-cache-dir wheel
12+
RUN pip3 install --no-cache-dir -r requirements.txt
13+
14+
# Copy everythings
15+
COPY . .
16+
17+
# Expose port 8080 to the outside world
18+
EXPOSE 5000
19+
20+
# Envs included
21+
ENV PYTHONUNBUFFERED 1
22+
23+
# activate virtual environment
24+
ENV FLASK_APP='app'
25+
ENV FLASK_ENV='development'
26+
ENV FLASK_DEBUG=1
27+
ENV MASTER_DB_NAME=${MASTER_DB_NAME}
28+
ENV MASTER_DB_USER=${MASTER_DB_USER}
29+
ENV MASTER_DB_PASSWORD=${MASTER_DB_PASSWORD}
30+
ENV MASTER_DB_HOST=${MASTER_DB_HOST}
31+
ENV MASTER_DB_PORT=${MASTER_DB_PORT}
32+
ENV MASTER_DB_LOG_MODE=${MASTER_DB_LOG_MODE}
33+
34+
#Command to run the executable
35+
CMD ["flask", "run","--host=0.0.0.0"]

app/__init__.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# from datetime import timedelta
2+
# from flask import Flask
3+
# from flask_jwt_extended import JWTManager
4+
# from flask_restful import Api
5+
6+
# from app.resources.transaction import TransactionList
7+
# from app.resources.user import UserRegister, UserLogin
8+
# from app.config.config import postgresqlConfig
9+
10+
# def create_app():
11+
# app = Flask(__name__)
12+
13+
# app.config['SQLALCHEMY_DATABASE_URI'] = postgresqlConfig
14+
# app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
15+
# app.config["JWT_SECRET_KEY"] = "JWT123SACRETKEY"
16+
# app.config['JWT_TOKEN_LOCATION'] = ['headers']
17+
# app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(minutes=50)
18+
19+
# app.config.from_pyfile('config/config.py')
20+
21+
# jwt = JWTManager(app)
22+
# api = Api(app, prefix="/api/v3")
23+
24+
25+
# @app.before_first_request
26+
# def create_tables():
27+
# from app.config.db import db
28+
# db.init_app(app)
29+
# db.create_all()
30+
31+
32+
# api.add_resource(UserRegister, '/register', methods=['POST'])
33+
# api.add_resource(UserLogin, '/merchant/user/login', methods=['POST'])
34+
# api.add_resource(TransactionList, '/transactions/report', methods=['POST'])
35+
36+
# return app
37+
38+
# app = create_app()
39+
40+
# if __name__ == '__main__':
41+
# app.run(host='0.0.0.0', port='5000',debug=True)

app/app.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from datetime import timedelta
2+
from flask import Flask
3+
from flask_jwt_extended import JWTManager
4+
from flask_restful import Api
5+
6+
from app.resources.transaction import TransactionList
7+
from app.resources.user import UserRegister, UserLogin
8+
from app.config.config import postgresqlConfig
9+
10+
app = Flask(__name__)
11+
12+
app.config['SQLALCHEMY_DATABASE_URI'] = postgresqlConfig
13+
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
14+
app.config["JWT_SECRET_KEY"] = "JWT123SACRETKEY"
15+
app.config['JWT_TOKEN_LOCATION'] = ['headers']
16+
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(minutes=10)
17+
18+
app.config.from_pyfile('config/config.py')
19+
20+
jwt = JWTManager(app)
21+
api = Api(app, prefix="/api/v3")
22+
23+
24+
@app.before_first_request
25+
def create_tables():
26+
from app.config.db import db
27+
db.init_app(app)
28+
db.create_all()
29+
30+
31+
api.add_resource(UserRegister, '/register', methods=['POST'])
32+
api.add_resource(UserLogin, '/merchant/user/login', methods=['POST'])
33+
api.add_resource(TransactionList, '/transactions/report', methods=['POST'])
34+
35+
if __name__ == '__main__':
36+
app.run(host='0.0.0.0', port='5000',debug=True)

app/config/config.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import os
2+
3+
postgresql = {'host': os.environ["MASTER_DB_HOST"],
4+
'user': os.environ["MASTER_DB_USER"],
5+
'passwd': os.environ["MASTER_DB_PASSWORD"],
6+
'db': os.environ["MASTER_DB_NAME"]}
7+
8+
postgresqlConfig = "postgresql+psycopg2://{}:{}@{}/{}".format(
9+
postgresql['user'], postgresql['passwd'], postgresql['host'], postgresql['db'])
10+
11+
12+
class Config(object):
13+
SQLALCHEMY_TRACK_MODIFICATIONS = os.environ["SQLALCHEMY_TRACK_MODIFICATIONS"]
14+
TESTING = os.environ["TESTING"]
15+
DEBUG = os.environ["DEBUG"]
16+
FLASK_ENV = os.environ["FLASK_ENV"]
17+
JWT_SECRET_KEY = os.environ["JWT_SECRET_KEY"]
18+
MASTER_DB_HOST = os.environ["MASTER_DB_HOST"]
19+
MASTER_DB_USER = os.environ["MASTER_DB_USER"]
20+
MASTER_DB_PASSWORD = os.environ["MASTER_DB_PASSWORD"]
21+
MASTER_DB_NAME = os.environ["MASTER_DB_NAME"]

app/config/db.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from flask_sqlalchemy import SQLAlchemy
2+
3+
db = SQLAlchemy()
4+

app/models/__init__.py

Whitespace-only changes.

app/models/transaction.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from app.config.db import db
2+
3+
4+
class TransactionModel(db.Model):
5+
__tablename__ = 'transaction'
6+
7+
id = db.Column(db.Integer, primary_key=True)
8+
merchant = db.Column(db.Integer)
9+
acquirer = db.Column(db.Integer)
10+
currency = db.Column(db.String())
11+
amount = db.Column(db.Integer)
12+
transactiondate = db.Column(db.DateTime(timezone=False))
13+
14+
def __init__(self, alert):
15+
self.alert = alert
16+
17+
def json(self):
18+
return {'data': self.alert}
19+
20+
def save_to_db(self):
21+
db.session.add(self)
22+
db.session.commit()
23+
24+
def delete_from_db(self):
25+
db.session.delete(self)
26+
db.session.commit()
27+

app/models/user.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from app.config.db import db
2+
from werkzeug.security import hmac
3+
4+
5+
class UserModel(db.Model):
6+
__tablename__ = 'users'
7+
8+
id = db.Column(db.Integer, primary_key=True)
9+
email = db.Column(db.String(100))
10+
password = db.Column(db.String(100))
11+
12+
def __init__(self, email, password):
13+
self.email = email
14+
self.password = password
15+
16+
def save_to_db(self):
17+
db.session.add(self)
18+
db.session.commit()
19+
20+
def check_password(self, password):
21+
return hmac.compare_digest(self.password, password)
22+
23+
@classmethod
24+
def find_by_email(cls, email):
25+
return cls.query.filter_by(email=email).first()
26+
27+
@classmethod
28+
def find_by_id(cls, _id):
29+
return cls.query.filter_by(id=_id).first()
30+

app/requirements.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Flask==2.2.2
2+
Flask-RESTful==0.3.9
3+
Flask-SQLAlchemy==3.0.2
4+
Jinja2==3.1.2
5+
Flask-JWT-Extended==4.2.1
6+
pytest==7.2.0
7+
python-dateutil==2.8.1
8+
python-dotenv==0.21.0
9+
pytz==2021.1
10+
SQLAlchemy==1.4.45
11+
Werkzeug==2.2.2
12+
psycopg2-binary
13+
rich

app/resources/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)