First files
This commit is contained in:
parent
12103a7946
commit
0a6d0b941c
9 changed files with 128 additions and 0 deletions
2
backend/.gitignore
vendored
Normal file
2
backend/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.venv/
|
||||||
|
__pycache__/
|
11
backend/.pylintrc
Normal file
11
backend/.pylintrc
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[MAIN]
|
||||||
|
|
||||||
|
disable=
|
||||||
|
too-many-instance-attributes,
|
||||||
|
too-few-public-methods,
|
||||||
|
too-many-arguments,
|
||||||
|
missing-module-docstring,
|
||||||
|
missing-function-docstring,
|
||||||
|
missing-class-docstring,
|
||||||
|
too-few-public-methods,
|
||||||
|
line-too-long,
|
4
backend/requirements.txt
Normal file
4
backend/requirements.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
flask~=2.3.3
|
||||||
|
flask-smorest~=0.42.1
|
||||||
|
marshmallow~=3.20.1
|
||||||
|
gevent~=23.9.1
|
34
backend/src/app.py
Normal file
34
backend/src/app.py
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# pylint: disable=too-few-public-methods
|
||||||
|
|
||||||
|
from flask import Flask
|
||||||
|
from flask_smorest import Api
|
||||||
|
from config.api_settings import DefaultSettings
|
||||||
|
|
||||||
|
class IsSingletonException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Application:
|
||||||
|
"""
|
||||||
|
This is a singleton that can be accessed using get_instance()
|
||||||
|
|
||||||
|
It has 2 properties
|
||||||
|
|
||||||
|
- app: Used for WSGI servers and such
|
||||||
|
- api: Used for Blueprints
|
||||||
|
"""
|
||||||
|
__instance = None
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.config.from_object(DefaultSettings)
|
||||||
|
api = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_instance():
|
||||||
|
if Application.__instance is None:
|
||||||
|
Application()
|
||||||
|
return Application.__instance
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
if Application.__instance is not None:
|
||||||
|
raise IsSingletonException("This class is a singleton")
|
||||||
|
Application.__instance = self
|
||||||
|
self.api = Api(self.app)
|
28
backend/src/config/api_settings.py
Normal file
28
backend/src/config/api_settings.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# pylint: disable=too-few-public-methods
|
||||||
|
import os
|
||||||
|
class DefaultSettings:
|
||||||
|
API_TITLE = "Support Organizer"
|
||||||
|
API_VERSION = 0.1
|
||||||
|
OPENAPI_VERSION = "3.1.0"
|
||||||
|
|
||||||
|
# openapi.json settings
|
||||||
|
OPENAPI_URL_PREFIX = "/"
|
||||||
|
OPENAPI_JSON_PATH = "openapi.json"
|
||||||
|
|
||||||
|
# swagger settings
|
||||||
|
OPENAPI_SWAGGER_UI_PATH = "/swagger"
|
||||||
|
OPENAPI_SWAGGER_UI_URL = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"
|
||||||
|
SWAGGER_UI_DOC_EXPANSION = "list"
|
||||||
|
|
||||||
|
# redoc settings
|
||||||
|
OPENAPI_REDOC_PATH = "/redoc"
|
||||||
|
OPENAPI_REDOC_URL = "https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"
|
||||||
|
|
||||||
|
# Info settings
|
||||||
|
API_SPEC_OPTIONS = {
|
||||||
|
'info': {
|
||||||
|
'description': 'Support Organizer for FGO'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE_SAVE_DIRECTORY = f"{os.getcwd()}/temp"
|
2
backend/src/config/config.ini
Normal file
2
backend/src/config/config.ini
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[server]
|
||||||
|
port=5000
|
6
backend/src/routes/__init__.py
Normal file
6
backend/src/routes/__init__.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# pylint: disable=wrong-import-position,cyclic-import
|
||||||
|
from flask_smorest import Blueprint
|
||||||
|
|
||||||
|
routes = Blueprint("support-organizer", "support-organizer", url_prefix="/", description="")
|
||||||
|
|
||||||
|
from . import apiversion # avoids circular imports problem
|
15
backend/src/routes/apiversion.py
Normal file
15
backend/src/routes/apiversion.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
from flask.views import MethodView
|
||||||
|
import marshmallow as ma
|
||||||
|
|
||||||
|
from config.api_settings import DefaultSettings
|
||||||
|
from . import routes as blp
|
||||||
|
|
||||||
|
class ApiVersionGet(ma.Schema):
|
||||||
|
version = ma.fields.String(example="0.1")
|
||||||
|
|
||||||
|
@blp.route("/version")
|
||||||
|
class ApiVersion(MethodView):
|
||||||
|
@blp.doc(summary="Get the REST interface version identification.")
|
||||||
|
@blp.response(200, ApiVersionGet, description="Successful operation")
|
||||||
|
def get(self):
|
||||||
|
return { "version": DefaultSettings.API_VERSION }
|
26
backend/src/server.py
Normal file
26
backend/src/server.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# pylint: disable=multiple-statements,wrong-import-position,wrong-import-order
|
||||||
|
from gevent.monkey import patch_all; patch_all()
|
||||||
|
from gevent.pywsgi import WSGIServer
|
||||||
|
import configparser
|
||||||
|
|
||||||
|
from app import Application
|
||||||
|
from routes import routes
|
||||||
|
|
||||||
|
instance = Application.get_instance()
|
||||||
|
app = instance.app
|
||||||
|
api = instance.api
|
||||||
|
api.register_blueprint(routes)
|
||||||
|
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read('config/config.ini')
|
||||||
|
|
||||||
|
port = int(config['server']['port']) or 5000
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
http_Server = WSGIServer(("127.0.0.1", port), app)
|
||||||
|
try:
|
||||||
|
print(f"Server available on http://127.0.0.1:{port}/")
|
||||||
|
print(f"View docs on http://127.0.0.1:{port}/swagger")
|
||||||
|
http_Server.serve_forever()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Keyboard interrupt received, stopping...")
|
Loading…
Reference in a new issue