Skip to content
This repository has been archived by the owner on Jan 20, 2024. It is now read-only.

Commit

Permalink
Use blueprints instead of manually adding URI rules
Browse files Browse the repository at this point in the history
  • Loading branch information
tdemin committed Dec 27, 2019
1 parent 53625a8 commit 3119a77
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 41 deletions.
40 changes: 12 additions & 28 deletions project_amber/app.py
Expand Up @@ -6,14 +6,13 @@
from project_amber.config import config
from project_amber.db import db
from project_amber.errors import HTTPError
from project_amber.helpers import handleLogin, middleware as checkRequest
from project_amber.handlers.auth import login, logout
from project_amber.handlers.session import handle_session_req, \
handle_session_id_req
from project_amber.handlers.misc import version as handle_version_request
from project_amber.handlers.task import handle_task_id_request, \
handle_task_request
from project_amber.handlers.users import signup, update_user_data
from project_amber.helpers import handleLogin, middleware as check_request
from project_amber.handlers.const import API_V0
from project_amber.handlers.auth import auth_handlers as auth
from project_amber.handlers.session import session_handlers as session
from project_amber.handlers.misc import misc_handlers as misc
from project_amber.handlers.task import task_handlers as task
from project_amber.handlers.users import user_handlers as user

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = config["database"]
Expand All @@ -23,26 +22,11 @@

@app.before_request
def middleware():
if checkRequest().authenticated: request.user = handleLogin()


app.add_url_rule("/v0/login", "login", login, methods=["POST"])
app.add_url_rule("/v0/logout", "logout", logout, methods=["POST"])
app.add_url_rule("/v0/task", "task", handle_task_request, \
methods=["GET", "POST"])
app.add_url_rule("/v0/task/<task_id>", "task_id", handle_task_id_request, \
methods=["GET", "PATCH", "DELETE"])
app.add_url_rule("/v0/user", "user", update_user_data, methods=["PATCH"])
app.add_url_rule(
"/v0/session", "session", handle_session_req, methods=["GET"]
)
app.add_url_rule("/v0/session/<session_id>", "session_id", \
handle_session_id_req, methods=["GET", "DELETE"])
app.add_url_rule("/v0/version", "version", handle_version_request, \
methods=["GET"])

if config["allow_signup"]:
app.add_url_rule("/v0/signup", "signup", signup, methods=["POST"])
if check_request().authenticated: request.user = handleLogin()


for blueprint in (auth, session, misc, task, user):
app.register_blueprint(blueprint, url_prefix=API_V0)


@app.before_first_request
Expand Down
1 change: 1 addition & 0 deletions project_amber/const.py
Expand Up @@ -13,6 +13,7 @@
MSG_USER_NOT_FOUND = "This user does not exist"
MSG_USER_EXISTS = "The user with this name already exists"
MSG_IMMATURE_SESSION = "This session is too new, and cannot remove others"
MSG_SIGNUP_FORBIDDEN = "Signup is disabled on this server"

MSG_TASK_NOT_FOUND = "This task does not exist"
MSG_TEXT_NOT_SPECIFIED = "No text specified"
Expand Down
6 changes: 5 additions & 1 deletion project_amber/handlers/auth.py
@@ -1,14 +1,17 @@
from json import dumps

from flask import request
from flask import request, Blueprint

from project_amber.const import EMPTY_RESP, MSG_MISSING_AUTH_INFO
from project_amber.errors import BadRequest
from project_amber.handlers.const import API_PASSWORD, API_USER, API_TOKEN
from project_amber.helpers.auth import removeSession, createSession
from project_amber.logging import log

auth_handlers = Blueprint("auth_handlers", __name__)


@auth_handlers.route("/login", methods=["POST"])
def login():
"""
Login handler. Accepts this JSON:
Expand All @@ -32,6 +35,7 @@ def login():
return dumps({API_TOKEN: token})


@auth_handlers.route("/logout", methods=["POST"])
def logout():
"""
Logout handler. Accepts empty JSON. Returns HTTP 200 on success.
Expand Down
2 changes: 2 additions & 0 deletions project_amber/handlers/const.py
Expand Up @@ -14,3 +14,5 @@
API_QUERY = "query"
API_VERSION = "version"
API_SIGNUP = "signup"

API_V0 = "/v0"
5 changes: 5 additions & 0 deletions project_amber/handlers/misc.py
@@ -1,12 +1,17 @@
from json import dumps

from flask import Blueprint

from project_amber.config import config
from project_amber.const import VERSION
from project_amber.handlers.const import API_VERSION, API_SIGNUP

signup_allowed = False
if config["allow_signup"]: signup_allowed = True

misc_handlers = Blueprint("misc_handlers", __name__)


@misc_handlers.route("/version", methods=["GET"])
def version():
return dumps({API_VERSION: VERSION, API_SIGNUP: signup_allowed})
10 changes: 7 additions & 3 deletions project_amber/handlers/session.py
@@ -1,6 +1,6 @@
from json import dumps

from flask import request
from flask import request, Blueprint

from project_amber.const import MATURE_SESSION, MSG_IMMATURE_SESSION, EMPTY_RESP
from project_amber.errors import Forbidden
Expand All @@ -9,8 +9,11 @@
from project_amber.helpers.auth import getSessions, getSession, removeSessionById
from project_amber.logging import log

session_handlers = Blueprint("session_handlers", __name__)

def handle_session_req():

@session_handlers.route("/session", methods=["GET"])
def session():
"""
Request handler for `/api/session`. Only accepts GET requests. Returns a
list of sessions like the one below:
Expand Down Expand Up @@ -40,7 +43,8 @@ def handle_session_req():
return dumps(sessionList)


def handle_session_id_req(session_id: int):
@session_handlers.route("/session/<session_id>", methods=["GET", "DELETE"])
def session_by_id(session_id: int):
"""
Login handler for `/api/session/<id>`. Accepts GET and DELETE
requests. Returns 404 if this session does not exist. On successful
Expand Down
10 changes: 7 additions & 3 deletions project_amber/handlers/task.py
@@ -1,14 +1,17 @@
from json import dumps

from flask import request
from flask import request, Blueprint

from project_amber.const import EMPTY_RESP
from project_amber.handlers.const import API_QUERY
from project_amber.helpers.task import addTask, getTask, getTasks, \
updateTask, removeTask

task_handlers = Blueprint("task_handlers", __name__)

def handle_task_request():

@task_handlers.route("/task", methods=["GET", "POST"])
def task_request():
"""
Handles requests to `/api/task`. Accepts GET and POST.
The request JSON may contain a `query` parameter in a GET request, in this
Expand Down Expand Up @@ -57,7 +60,8 @@ def handle_task_request():
return EMPTY_RESP


def handle_task_id_request(task_id: int):
@task_handlers.route("/task/<task_id>", methods=["GET", "PATCH", "DELETE"])
def task_id_request(task_id: int):
"""
Handles requests to `/api/task/<id>`. Accepts GET, PATCH, and DELETE.
On GET, the user gets this response with HTTP 200 (or 404, if the task
Expand Down
22 changes: 16 additions & 6 deletions project_amber/handlers/users.py
@@ -1,12 +1,19 @@
from flask import request
from flask import request, Blueprint

from project_amber.const import EMPTY_RESP, MSG_MISSING_AUTH_INFO
from project_amber.errors import BadRequest
from project_amber.config import config
from project_amber.const import EMPTY_RESP, MSG_MISSING_AUTH_INFO, MSG_SIGNUP_FORBIDDEN
from project_amber.errors import BadRequest, Forbidden
from project_amber.handlers.const import API_PASSWORD, API_USER
from project_amber.helpers.auth import addUser, updateUser

user_handlers = Blueprint("user_handlers", __name__)

def update_user_data():
signup_allowed = False
if config["allow_signup"]: signup_allowed = True


@user_handlers.route("/user", methods=["PATCH"])
def user_data():
"""
User data PATCH request handler. Accepts JSON with these parameters:
```
Expand All @@ -21,6 +28,7 @@ def update_user_data():
return EMPTY_RESP


@user_handlers.route("/signup", methods=["POST"])
def signup():
"""
Signup request handler. Accepts this JSON:
Expand All @@ -30,9 +38,11 @@ def signup():
"password": "some_password"
}
```
Returns HTTP 200 with empty JSON on success, 400 on missing params, 500
otherwise.
Returns HTTP 200 with empty JSON on success, 400 on missing params, 403 if
the method is disabled by a config parameter.
"""
if not signup_allowed:
raise Forbidden(MSG_SIGNUP_FORBIDDEN)
if not API_USER in request.json or not API_PASSWORD in request.json:
raise BadRequest(MSG_MISSING_AUTH_INFO)
addUser(request.json[API_USER], request.json[API_PASSWORD])
Expand Down

0 comments on commit 3119a77

Please sign in to comment.