Skip to content

Commit dc1aca3

Browse files
author
meongbego
committed
Add: Boilerplate
0 parents  commit dc1aca3

23 files changed

+580
-0
lines changed

.dockerignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
env
2+
.vscode
3+
.env
4+
__pycache__
5+
.env
6+
.dockerignore

.gitignore

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/ print('\n\n==============')
14+
print(data)
15+
downloads/
16+
eggs/
17+
.eggs/
18+
lib/
19+
lib64/
20+
parts/
21+
sdist/
22+
var/
23+
wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
MANIFEST
28+
29+
# PyInstaller
30+
# Usually these files are written by a python script from a template
31+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
32+
*.manifest
33+
*.spec
34+
35+
# Installer logs
36+
pip-log.txt
37+
pip-delete-this-directory.txt
38+
39+
# Unit test / coverage reports
40+
htmlcov/
41+
.tox/
42+
.coverage
43+
.coverage.*
44+
.cache
45+
nosetests.xml
46+
coverage.xml
47+
*.cover
48+
.hypothesis/
49+
.pytest_cache/
50+
51+
# Translations
52+
*.mo
53+
*.pot
54+
55+
# Django stuff:
56+
*.log
57+
local_settings.py
58+
db.sqlite3
59+
60+
# Flask stuff:
61+
instance/
62+
.webassets-cache
63+
64+
# Scrapy stuff:
65+
.scrapy
66+
67+
# Sphinx documentation
68+
docs/_build/
69+
70+
# PyBuilder
71+
target/
72+
73+
# Jupyter Notebook
74+
.ipynb_checkpoints
75+
76+
# pyenv
77+
.python-version
78+
79+
# celery beat schedule file
80+
celerybeat-schedule
81+
82+
# SageMath parsed files
83+
*.sage.py
84+
85+
# Environments
86+
.env
87+
.venv
88+
env/
89+
venv/
90+
ENV/
91+
env.bak/
92+
venv.bak/
93+
94+
# Spyder project settings
95+
.spyderproject
96+
.spyproject
97+
98+
# Rope project settings
99+
.ropeproject
100+
101+
# mkdocs documentation
102+
/site
103+
104+
# mypy
105+
.mypy_cache/
106+
107+
# visual studio files
108+
.vscode
109+
110+
# Heat Template
111+
app/static/clusters/*
112+
app/static/instances/*
113+
app/static/networks/*
114+
app/static/others/*
115+
app/static/databases/*
116+
117+
# PRODUCTION | GUNICORN
118+
deploy/*
119+
120+
# testing api
121+
app/controllers/api/test.py
122+
123+
# neo-cli testing
124+
lib/*
125+
requirements_lama.txt
126+
127+
production/*
128+
129+
testing.py
130+
131+
coverage_html_report/
132+
.coveragerc
133+
134+
celery_devel.sh
135+
136+
app/static/cluster/slave.yml
137+
app/static/cluster/master.yml

Dockerfile

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM alpine
2+
MAINTAINER Sofyan Saputra "[email protected]"
3+
4+
RUN mkdir /app
5+
WORKDIR /app
6+
COPY . /app
7+
8+
RUN apk update && \
9+
apk --no-cache add gcc linux-headers postgresql-dev musl-dev python3 python3-dev \
10+
&& pip3 install --upgrade pip \
11+
&& pip3 install gunicorn \
12+
&& pip3 install -r requirements.txt \
13+
&& apk del build-base
14+
EXPOSE 5000

app/__init__.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from flask import Flask
2+
from flask_cors import CORS
3+
from . import configs
4+
5+
6+
7+
def create_app():
8+
app = Flask(__name__)
9+
app.config.from_object(configs.Config)
10+
11+
CORS(app, resources={r"/api/*": {"origins": "*"}})
12+
13+
from .controllers import api_blueprint
14+
15+
app.register_blueprint(api_blueprint)
16+
17+
return app

app/configs/__init__.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import os
2+
from dotenv import load_dotenv
3+
from app.libs import MetaFlaskEnv
4+
5+
APP_ROOT = os.path.join(os.path.dirname(__file__), '../..')
6+
dotenv_path = os.path.join(APP_ROOT, '.env')
7+
load_dotenv(dotenv_path)
8+
9+
10+
class Config(MetaFlaskEnv):
11+
ENV_PREFIX = "FLASK_"

app/controllers/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .api import api_blueprint

app/controllers/api/__init__.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from flask import Blueprint
2+
from flask_restful import Api
3+
from .health import *
4+
5+
api_blueprint = Blueprint("api", __name__, url_prefix='/api')
6+
api = Api(api_blueprint)
7+
8+
api.add_resource(HealthCheck, "/health")
9+
10+
11+

app/controllers/api/health.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from flask_restful import Resource
2+
from app.helpers.rest import response
3+
4+
class HealthCheck(Resource):
5+
def get(self):
6+
data = {
7+
"check": "100"
8+
}
9+
return response(200, data=data, message="OK")

app/helpers/__init__.py

Whitespace-only changes.

app/helpers/rest.py

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from flask import Response
2+
import json
3+
4+
def response(status_code, message=None, data=None):
5+
"""Response data helper
6+
7+
Arguments:
8+
status_code {int} -- http status code
9+
10+
Keyword Arguments:
11+
message {string} -- response message (default: {None})
12+
data {dict} -- data to be appended to response (default: {None})
13+
14+
Returns:
15+
dict -- response data
16+
"""
17+
success_status = {
18+
200: 'Operation succeeded',
19+
201: 'Created',
20+
202: 'Accepted',
21+
204: 'Reply does not contain additional content',
22+
304: 'Not modified'
23+
}
24+
25+
failure_status = {
26+
400: 'Internal error occurred - unexpected error caused by request data',
27+
401: 'Unauthorized operation',
28+
403: 'Forbidden operation',
29+
404: 'Specified object not found',
30+
405: 'Method Not Allowed, for example, resource doesn\'t support DELETE method',
31+
406: 'Method Not Acceptable',
32+
409: 'Conflict',
33+
423: 'Locked',
34+
426: 'Upgrade Required',
35+
500: 'Internal Server Error - unexpected server-side error',
36+
501: 'Not Implemented - functionality is not implemented on the server side',
37+
503: 'Service is unavailable'
38+
}
39+
40+
status = {}
41+
status['code'] = status_code
42+
43+
if status_code in success_status:
44+
status['count'] = len(data) if data else 0
45+
status['data'] = data if data else None
46+
status['status'] = 'success'
47+
status['message'] = message if message else success_status[status_code]
48+
elif status_code in failure_status:
49+
status['status'] = 'error'
50+
status['message'] = message if message else failure_status[status_code]
51+
else:
52+
status['status'] = 'error'
53+
status['message'] = message if message else failure_status[400]
54+
55+
response = Response(
56+
response=json.dumps(status),
57+
status=status_code, mimetype='application/json')
58+
59+
return response

app/libs/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .meta_flask_env import *

app/libs/meta_flask_env.py

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import os
2+
3+
4+
class MetaFlaskEnv(type):
5+
def __init__(cls, name, bases, dict):
6+
"""
7+
MetaFlaskEnv class initializer.
8+
9+
This function will get called when a new class which utilizes this metaclass is defined,
10+
as opposed to when it is initialized.
11+
"""
12+
super(MetaFlaskEnv, cls).__init__(name, bases, dict)
13+
14+
# Get our internal settings
15+
prefix = dict.get('ENV_PREFIX', '')
16+
17+
# Override default configuration from environment variables
18+
for key, value in os.environ.items():
19+
# Only include environment keys that start with our prefix (if we have one)
20+
if not key.startswith(prefix):
21+
continue
22+
23+
# Strip the prefix from the environment variable name
24+
key = key[len(prefix):]
25+
26+
# If value is "true" or "false", parse as a boolean
27+
# Otherwise, if it contains a "." then try to parse as a float
28+
# Otherwise, try to parse as an integer
29+
# If all else fails, just keep it a string
30+
if 'PASSWORD' in key:
31+
value = str(value)
32+
elif value.lower() in ('true', 'false'):
33+
value = True if value.lower() == 'true' else False
34+
elif '.' in value:
35+
try:
36+
value = float(value)
37+
except ValueError:
38+
pass
39+
else:
40+
try:
41+
value = int(value)
42+
except ValueError:
43+
pass
44+
45+
# Update our config with the value from `os.environ`
46+
setattr(cls, key, value)

app/libs/utils.py

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import requests
2+
import json
3+
import os
4+
import logging
5+
import coloredlogs
6+
7+
8+
def log_rep(stdin):
9+
coloredlogs.install()
10+
logging.info(stdin)
11+
12+
def log_err(stdin):
13+
coloredlogs.install()
14+
logging.error(stdin)
15+
16+
def send_http(url, data, headers=None):
17+
json_data = json.dumps(data)
18+
try:
19+
send = requests.post(url, data=json_data, headers=headers)
20+
respons = send.json()
21+
response_time = send.elapsed.total_seconds()
22+
except requests.exceptions.RequestException:
23+
respons = {
24+
"result": False,
25+
"Error": "Failed to establish a new connection",
26+
"description": None
27+
}
28+
return respons
29+
else:
30+
result = {
31+
"result": respons['result'],
32+
"time": response_time,
33+
"data": respons['data'],
34+
"status": respons['status']
35+
}
36+
return result
37+
38+
def get_http(url, params = None):
39+
try:
40+
response = requests.get(url, params)
41+
except requests.exceptions.RequestException as e:
42+
log_err(e)
43+
return False
44+
except Exception as a:
45+
log_err(a)
46+
return False
47+
else:
48+
data = response.json()
49+
return data

app/middlewares/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)