Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flask Backend Module for WebCAS #8

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

*.log
venv/
*.pyc
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,11 @@
Web application for sepsis clinical assessment scores using batch ICU patient data
Backend of the application will be in Flask and the project will be completely python based
Frontend will be purely based on html, css and may be on javascript.

# Dependencies
1. Python 3.7

# Installation
1. Setup virtualenv for the project by running `virtualenv -p python3 venv`
2. Activate the environment by `source venv/bin/activate`
3. Install project requirements using `pip install -r requirements.txt`
Empty file added __init__.py
Empty file.
10 changes: 10 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Click==7.0
Flask==1.1.1
Flask-Cors==3.0.8
Flask-SQLAlchemy==2.4.0
itsdangerous==1.1.0
Jinja2==2.10.1
MarkupSafe==1.1.1
six==1.12.0
SQLAlchemy==1.3.6
Werkzeug==0.15.5
10 changes: 10 additions & 0 deletions run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

# Import app and run
#####################

from scasBackend import app

if __name__ == '__main__':
app.run()

###############################################################################
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these!

82 changes: 82 additions & 0 deletions scasBackend/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@

# Imports
##########
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unnecessary octothorps


from flask import abort, Flask, request

from scasBackend.utils import get_instance_folder_path
from scasBackend.api_routes import *
from scasBackend.config import configure_app
from scasBackend.models import db
from flask_cors import CORS

###############################################################################


# Initialise
#############

app = Flask(
__name__,
instance_path=get_instance_folder_path(),
instance_relative_config=True)

configure_app(app) # load configurations
db.init_app(app) # init app to db
CORS(app) #Cross Origin Resource Sharing Plugin

###############################################################################


# Error Handling
#################

@app.errorhandler(404)
def page_not_found(error):
app.logger.error('Page not found: %s', (request.path, error))
return "404"

@app.errorhandler(500)
def internal_server_error(error):
app.logger.error('Server Error: %s', (error))
return "500"

@app.errorhandler(Exception)
def unhandled_exception(error):
app.logger.exception(error)
app.logger.error('Unhandled Exception: %s', (error))
return "500"

###############################################################################


# Pre/Post Request Processing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to write proper comments then replace these octothorps with proper comments.

##############################

@app.before_first_request
def initialize_database():
db.create_all()

@app.after_request
def after_request(response):
header = response.headers
header['Access-Control-Allow-Origin'] = '*'
return response

###############################################################################


# Routings
###########

@app.route('/')
@app.route('/<lang_code>/')
def home(lang_code=None):
return "homepage"
abort(404)


# register all routes
app.register_blueprint(api_routes, url_prefix='/api/v1')

###############################################################################
16 changes: 16 additions & 0 deletions scasBackend/api_routes/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

# Import and Set
#################

from flask import Blueprint
api_routes = Blueprint('api_routes', __name__)

###############################################################################


# List of all router files
###########################

from .index import *

###############################################################################
18 changes: 18 additions & 0 deletions scasBackend/api_routes/index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

# Imports
##########

from flask import current_app
from . import api_routes

###############################################################################

# Routes
#########

@api_routes.route('/')
def index():
current_app.logger.info('/api/v1/')
return "this is /api/v1/"

###############################################################################
66 changes: 66 additions & 0 deletions scasBackend/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

# Imports
##########

from scasBackend.models import db
import os
import logging

###############################################################################


# Configs
##########

# Base
class BaseConfig(object):
DEBUG = False
TESTING = False
# sqlite :memory: identifier is the default if no filepath is present
SQLALCHEMY_DATABASE_URI = 'sqlite://'
SECRET_KEY = '123'
LOGGING_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
LOGGING_LOCATION = 'scasBackend.log'
LOGGING_LEVEL = logging.DEBUG
SECURITY_CONFIRMABLE = False
SUPPORTED_LANGUAGES = {'en': 'English'}

# Development
class DevelopmentConfig(BaseConfig):
DEBUG = True
TESTING = False
SQLALCHEMY_DATABASE_URI = 'sqlite:///scasBackend.sqlite3'
SECRET_KEY = '456'

# Testing
class TestingConfig(BaseConfig):
DEBUG = False
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite://scasBackend.sqlite3'
SECRET_KEY = '789'

config = {
"development": "scasBackend.config.DevelopmentConfig",
"testing": "scasBackend.config.TestingConfig",
"default": "scasBackend.config.DevelopmentConfig"
}

###############################################################################


# Set configiuration
#####################
def configure_app(app):
# Configure above configuraton
config_name = os.getenv('FLASK_CONFIGURATION', 'default')
app.config.from_object(config[config_name])
app.config.from_pyfile('config.cfg', silent=True) # if it exists (for production)

# Configure logging
handler = logging.FileHandler(app.config['LOGGING_LOCATION'])
handler.setLevel(app.config['LOGGING_LEVEL'])
formatter = logging.Formatter(app.config['LOGGING_FORMAT'])
handler.setFormatter(formatter)
app.logger.addHandler(handler)

###############################################################################
8 changes: 8 additions & 0 deletions scasBackend/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

# Imports and Initialise db object
###################################

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

###############################################################################
34 changes: 34 additions & 0 deletions scasBackend/models/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

# Imports
##########

from . import db

###############################################################################


# Base Class
#############

class Base(db.Model):
__abstract__ = True

created_on = db.Column(db.DateTime, default=db.func.now())
updated_on = db.Column(db.DateTime, default=db.func.now(), onupdate=db.func.now())

def serialize(self, return_fields=[]):
serialize_exclude = getattr(self, '__serialize_exclude__', set())
return_fields = self.__dict__.keys() if not return_fields else return_fields
return {
key: value for key, value in self.__dict__.items()
# Do not serialize 'private' attributes
# (SQLAlchemy-internal attributes are among those, too)
if not key.startswith('_')
and key in return_fields
and key not in serialize_exclude}

def create(self):
db.session.add(self)
db.session.commit()

###############################################################################
19 changes: 19 additions & 0 deletions scasBackend/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

# Imports
##########

import os

###############################################################################


# Utility Methods
##################

def get_app_base_path():
return os.path.dirname(os.path.realpath(__file__))

def get_instance_folder_path():
return os.path.join(get_app_base_path(), 'instance')

###############################################################################