diff --git a/app.py b/app.py index 660dfcc..fc8d730 100644 --- a/app.py +++ b/app.py @@ -1,4 +1,4 @@ -"""Runs the development web server.""" +"""Runs the production web server.""" import waitress diff --git a/dev.py b/dev.py new file mode 100644 index 0000000..69f019e --- /dev/null +++ b/dev.py @@ -0,0 +1,7 @@ +"""Runs the development web server.""" + +from test_api import create_app + +app = create_app() + +app.run(debug=True) diff --git a/test_api/api/routes.py b/test_api/api/routes.py index ec2505f..2536db6 100644 --- a/test_api/api/routes.py +++ b/test_api/api/routes.py @@ -1,45 +1,95 @@ """Endpoints for the API.""" -import json import secrets -import flask +from flask import abort, Blueprint, request -from test_api.models import db, Application +from test_api.models import Message, db, Application -api = flask.Blueprint('api', __name__) +api = Blueprint('api', __name__) -@api.route('/', methods=['GET', 'POST']) +@api.route('/apps/', methods=['GET', 'POST']) def home(app_name): - """Home route of API.""" + """Route to generate and test API keys.""" - response = None - - if flask.request.method == 'GET': - app = Application.query.filter_by(name=app_name).first_or_404() - if app.api_key and flask.request.headers.get('x-api-key') == app.api_key: - response = {'success': True} - else: - flask.abort( + if request.method == 'GET': + app = db.session.query(Application).filter_by( # pylint: disable=no-member + name=app_name).first_or_404() + if request.headers.get('x-api-key') != app.api_key: + abort( 401, description='Missing or invalid app key.' ) - elif flask.request.method == 'POST': + return {'success': True} + + if request.method == 'POST': app = Application.query.filter_by(name=app_name).first() api_key = secrets.token_hex(32) while Application.query.filter_by(api_key=api_key).first(): api_key = secrets.token_hex(32) + if not app: app = Application( name=app_name, api_key=api_key ) - db.session.add(app) # pylint: disable=no-member + db.session.add(app) # pylint: disable=no-member + else: app.api_key = api_key + + db.session.commit() # pylint: disable=no-member + return {'app-name': app.name, 'api-key': app.api_key} + + return None + + +@api.route('/messages') +def get_all_messages(): + """Route to get all messages in a list.""" + + if not db.session.query(Application.id).filter_by( # pylint: disable=no-member + api_key=request.headers.get('X-Api-Key')).first(): + abort(401) + + return { + 'messages': [ + { + 'application': str(message.application), + 'title': message.title, + 'text': message.text + } for message in db.session.query(Message).all() # pylint: disable=no-member + ] + } + + +@api.route('/messages/', methods=['GET', 'POST']) +def message(message_title: str): + """Route to read or create a message.""" + + application = db.session.query(Application).filter_by( # pylint: disable=no-member + api_key=request.headers.get('X-Api-Key')).first() + if not application: + abort(401) + + if request.method == 'GET': + _message = db.session.query(Message).filter_by( # pylint: disable=no-member + title=message_title).first_or_404() + + if request.method == 'POST': + _message = Message( + title=message_title, + text=request.data.decode(), + application=application + ) + db.session.add(_message) # pylint: disable=no-member db.session.commit() # pylint: disable=no-member - response = json.loads(str(app)) - return response + data = { + 'application': str(_message.application), + 'title': _message.title, + 'text': _message.text + } + return data diff --git a/test_api/models.py b/test_api/models.py index 2af96fe..d26a0e6 100644 --- a/test_api/models.py +++ b/test_api/models.py @@ -1,25 +1,30 @@ """Models for api persistent data.""" +# pylint: disable=no-member,too-few-public-methods -import json +from flask_sqlalchemy import SQLAlchemy -import flask_sqlalchemy - -db = flask_sqlalchemy.SQLAlchemy() +db = SQLAlchemy() class Application(db.Model): """ORM object for Application.""" - # pylint: disable=no-member,too-few-public-methods id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(32), unique=True, nullable=False) - api_key = db.Column(db.String(64)) + api_key = db.Column(db.String(64), unique=True, nullable=False) + messages = db.relationship('Message', backref='application', lazy=True) + + def __repr__(self): + return str(self.name) + + +class Message(db.Model): + """ORM object for saving messages.""" + + id = db.Column(db.Integer, primary_key=True) + title = db.Column(db.String(32), nullable=False) + text = db.Column(db.Text(), nullable=False) + application_id = db.Column(db.Integer, db.ForeignKey('application.id'), nullable=False) def __repr__(self): - return json.dumps( - { - 'name': self.name, - 'api_key': self.api_key - }, - indent=4 - ) + return str(self.title)