| from flask_sqlalchemy import SQLAlchemy | from flask_sqlalchemy import SQLAlchemy | ||||
| from flask_login import LoginManager | from flask_login import LoginManager | ||||
| from flask_moment import Moment | from flask_moment import Moment | ||||
| from flask_marshmallow import Marshmallow | |||||
| import os | import os | ||||
| # initiate SQLAlchemy so we can use it later in our models | # initiate SQLAlchemy so we can use it later in our models | ||||
| db = SQLAlchemy() | db = SQLAlchemy() | ||||
| # initiate Marshmallow | |||||
| ma = Marshmallow() | |||||
| # initiate Moment for datetime functions | # initiate Moment for datetime functions | ||||
| moment = Moment() | moment = Moment() | ||||
| app.config['SQLALCHEMY_ECHO'] = False | app.config['SQLALCHEMY_ECHO'] = False | ||||
| app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False | app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False | ||||
| # for sorting API output correctly | |||||
| app.config ['JSON_SORT_KEYS'] = False | |||||
| app.url_map.strict_slashes = False | app.url_map.strict_slashes = False | ||||
| db.init_app(app) | db.init_app(app) | ||||
| from .create import create as create_blueprint | from .create import create as create_blueprint | ||||
| app.register_blueprint(create_blueprint) | app.register_blueprint(create_blueprint) | ||||
| # blueprint for API parts of app | |||||
| from .api import api as api_blueprint | |||||
| app.register_blueprint(api_blueprint) | |||||
| return app | return app |
| # @name: api.py | |||||
| # @creation_date: 2023-01-12 | |||||
| # @license: The MIT License <https://opensource.org/licenses/MIT> | |||||
| # @author: Simon Bowie <ad7588@coventry.ac.uk> | |||||
| # @purpose: Exposes database data as exportable JSON for an API | |||||
| # @acknowledgements: | |||||
| from flask import Blueprint, render_template, request, flash, redirect, url_for, jsonify | |||||
| from flask_login import login_required, current_user | |||||
| from .models import Resource, User | |||||
| from .schemas import UserSchema, ToolSchema, PracticeSchema, BookSchema | |||||
| api = Blueprint('api', __name__) | |||||
| # route for exporting all users in database | |||||
| @api.route('/api/users') | |||||
| @login_required | |||||
| def get_users(): | |||||
| users = User.query.all() | |||||
| users_schema = UserSchema(many=True) | |||||
| result = users_schema.dump(users) | |||||
| # return all rows as a JSON array of objects | |||||
| return jsonify(result) | |||||
| # route for exporting all tools in database | |||||
| @api.route('/api/tools') | |||||
| def get_tools(): | |||||
| type = 'tool' | |||||
| resources = Resource.query.filter_by(type=type) | |||||
| resources_schema = ToolSchema(many=True) | |||||
| result = resources_schema.dump(resources) | |||||
| # return all rows as a JSON array of objects | |||||
| return jsonify(result) | |||||
| # route for exporting all practices in database | |||||
| @api.route('/api/practices') | |||||
| def get_practices(): | |||||
| type = 'practice' | |||||
| resources = Resource.query.filter_by(type=type) | |||||
| resources_schema = PracticeSchema(many=True) | |||||
| result = resources_schema.dump(resources) | |||||
| # return all rows as a JSON array of objects | |||||
| return jsonify(result) | |||||
| # route for exporting all books in database | |||||
| @api.route('/api/books') | |||||
| def get_books(): | |||||
| type = 'book' | |||||
| resources = Resource.query.filter_by(type=type) | |||||
| resources_schema = BookSchema(many=True) | |||||
| result = resources_schema.dump(resources) | |||||
| # return all rows as a JSON array of objects | |||||
| return jsonify(result) |
| from flask_login import UserMixin | from flask_login import UserMixin | ||||
| from . import db | from . import db | ||||
| from . import ma | |||||
| from datetime import datetime | from datetime import datetime | ||||
| from marshmallow import Schema | |||||
| # table for users | # table for users | ||||
| class User(UserMixin, db.Model): | class User(UserMixin, db.Model): | ||||
| id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy | id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy | ||||
| first_resource_id = db.Column(db.Integer) | first_resource_id = db.Column(db.Integer) | ||||
| second_resource_id = db.Column(db.Integer) | |||||
| second_resource_id = db.Column(db.Integer) |
| # @name: schemas.py | |||||
| # @creation_date: 2023-01-16 | |||||
| # @license: The MIT License <https://opensource.org/licenses/MIT> | |||||
| # @author: Simon Bowie <ad7588@coventry.ac.uk> | |||||
| # @purpose: Data schemas for API export | |||||
| # @acknowledgements: | |||||
| from . import ma | |||||
| from marshmallow import Schema | |||||
| # schema for JSON transformation of User table via Marshmallow | |||||
| class UserSchema(ma.Schema): | |||||
| class Meta: | |||||
| fields = ('id', 'email', 'name') | |||||
| ordered = True | |||||
| # schema for JSON transformation of Resource table via Marshmallow | |||||
| class ToolSchema(ma.Schema): | |||||
| class Meta: | |||||
| fields = ('id', 'name', 'description', 'developer', 'developerUrl', 'projectUrl', 'repositoryUrl', 'license', 'scriptingLanguage', 'expertiseToUse', 'expertiseToHost', 'dependencies', 'ingestFormats', 'outputFormats', 'status') | |||||
| ordered = True | |||||
| class PracticeSchema(ma.Schema): | |||||
| class Meta: | |||||
| fields = ('id', 'name', 'description', 'experimental', 'lessonsLearned', 'references') | |||||
| ordered = True | |||||
| class BookSchema(ma.Schema): | |||||
| class Meta: | |||||
| fields = ('id', 'name', 'description', 'author', 'year', 'bookUrl', 'isbn') | |||||
| ordered = True | |||||
| # subschemas for nested fields | |||||
| class DeveloperSchema(ma.Schema): | |||||
| class Meta: | |||||
| fields = ('developer', 'developerUrl') | |||||
| ordered = True |
| pymysql | pymysql | ||||
| markdown | markdown | ||||
| isbntools | isbntools | ||||
| requests | |||||
| requests | |||||
| marshmallow | |||||
| flask-marshmallow |