from flask import Flask, request, jsonify from flask_sqlalchemy import SQLAlchemy from flask_marshmallow import Marshmallow from flask_restful import Resource, Api from sqlalchemy import func from datetime import datetime #https://betterdatascience.com/develop-database-driven-rest-api-with-python-in-10-minutes/ #Initializations for DB and JSON app = Flask(__name__) api = Api(app) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///jobs.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) ma = Marshmallow(app) #Create class for the Jobs, also allows for SQLAlchemy to create the table ##If you need to create another table do these commands: ### from main import app, db ### app.app_context().push() ### db.create_all() class Job(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(32), unique=True) status = db.Column(db.String(32)) lastUpdated = db.Column(db.DateTime(timezone=True), server_default=func.now()) def __init__(self, name, status, lastUpdated): self.name = name self.status = status self.lastUpdated = lastUpdated #Parses the JSON gathered from the DB class jobSchema(ma.Schema): class Meta: fields = ('id', 'name', 'status', 'lastUpdated') job_schema = jobSchema() jobs_schema = jobSchema(many=True) #Main class for handling jobs class jobManager(Resource): #Logic for fetching one/all jobs ##Check if id was provided as a parameter, if not pull for all jobs ##makes a query and returns the result in json format @staticmethod def get(): try: id = request.args['id'] except Exception as _: id = None if not id: jobs = Job.query.all() return jsonify(jobs_schema.dump(jobs)) job = Job.query.get(id) return jsonify(job_schema.dump(job)) #Insert new Job ##Fetch provided json data for name, status, and last updated ##Create instance of the Job class with the provided data ##Add to the DB and commit ##Return message stating success @staticmethod def post(): name = request.json['name'] status = request.json['status'] #lastUpdated = request.json['lastUpdated'] lastUpdated = datetime.now() job = Job(name, status, lastUpdated) db.session.add(job) db.session.commit() return jsonify({ 'Message': f'Job {name} has been added' }) #Update existing job ##check if a job id was passed in the call, if not return an error message ##fecth json data ##set values to the db according to provided data ##return message that it was updated @staticmethod def put(): try: id = request.args['id'] except Exception as _: id = None if not id: return jsonify({ 'Message': 'Must provide a job ID'}) job = Job.query.get(id) name = request.json['name'] status = request.json['status'] #lastUpdated = request.json['lastUpdated'] lastUpdated = datetime.now() job.name = name job.status = status job.lastUpdated = lastUpdated db.session.commit() return jsonify({ 'Message': f'Job {name} has been altered' }) #Delete Job @staticmethod def delete(): try: id = request.args['id'] except Exception as _: id = None if not id: return jsonify({ 'Message': 'Must provide the job ID' }) job = Job.query.get(id) db.session.delete(job) db.session.commit() return jsonify({ 'Message': f'Job {str(id)} deleted.' }) #Attach Job manager class to an endpoint, /api/jobs api.add_resource(jobManager, '/api/jobs') #Runs the Flask app if __name__ == '__main__': app.run(debug=True)