From 31839d421d9bcb262d45fb8da62815eb71c4bd60 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Tue, 1 Dec 2020 01:33:57 +0100 Subject: [PATCH] consolidate api endpoints into own module and flask Blueprint --- WebHostLib/__init__.py | 3 +- WebHostLib/api/__init__.py | 6 ++++ WebHostLib/api/generate.py | 73 ++++++++++++++++++++++++++++++++++++++ WebHostLib/generate.py | 64 --------------------------------- 4 files changed, 81 insertions(+), 65 deletions(-) create mode 100644 WebHostLib/api/__init__.py create mode 100644 WebHostLib/api/generate.py diff --git a/WebHostLib/__init__.py b/WebHostLib/__init__.py index 277e22ca..4d56927a 100644 --- a/WebHostLib/__init__.py +++ b/WebHostLib/__init__.py @@ -147,4 +147,5 @@ def favicon(): from WebHostLib.customserver import run_server_process -from . import tracker, upload, landing, check, generate, downloads # to trigger app routing picking up on it +from . import tracker, upload, landing, check, generate, downloads, api # to trigger app routing picking up on it +app.register_blueprint(api.api_endpoints) \ No newline at end of file diff --git a/WebHostLib/api/__init__.py b/WebHostLib/api/__init__.py new file mode 100644 index 00000000..3b2700b4 --- /dev/null +++ b/WebHostLib/api/__init__.py @@ -0,0 +1,6 @@ +"""API endpoints package.""" +from flask import Blueprint + +api_endpoints = Blueprint('api', __name__, url_prefix="/api") + +from . import generate \ No newline at end of file diff --git a/WebHostLib/api/generate.py b/WebHostLib/api/generate.py new file mode 100644 index 00000000..4b5ea710 --- /dev/null +++ b/WebHostLib/api/generate.py @@ -0,0 +1,73 @@ +import pickle +from uuid import UUID + +from . import api_endpoints +from flask import request, session, url_for +from pony.orm import commit + +from WebHostLib import app, Generation, STATE_QUEUED, Seed, STATE_ERROR +from WebHostLib.check import get_yaml_data, roll_options + + +@api_endpoints.route('/generate', methods=['POST']) +def generate_api(): + try: + options = {} + race = False + + if 'file' in request.files: + file = request.files['file'] + options = get_yaml_data(file) + if type(options) == str: + return {"text": options}, 400 + if "race" in request.form: + race = bool(0 if request.form["race"] in {"false"} else int(request.form["race"])) + + json_data = request.get_json() + if json_data: + if 'weights' in json_data: + # example: options = {"player1weights" : {}} + options = json_data["weights"] + if "race" in json_data: + race = bool(0 if json_data["race"] in {"false"} else int(json_data["race"])) + if not options: + return {"text": "No options found. Expected file attachment or json weights." + }, 400 + + if len(options) > app.config["MAX_ROLL"]: + return {"text": "Max size of multiworld exceeded", + "detail": app.config["MAX_ROLL"]}, 409 + + results, gen_options = roll_options(options) + if any(type(result) == str for result in results.values()): + return {"text": str(results), + "detail": results}, 400 + else: + gen = Generation( + options=pickle.dumps({name: vars(options) for name, options in gen_options.items()}), + # convert to json compatible + meta=pickle.dumps({"race": race}), state=STATE_QUEUED, + owner=session["_id"]) + commit() + return {"text": f"Generation of seed {gen.id} started successfully.", + "detail": gen.id, + "encoded": app.url_map.converters["suuid"].to_url(None, gen.id), + "wait_api_url": url_for("wait_seed_api", seed=gen.id, _external=True), + "url": url_for("wait_seed", seed=gen.id, _external=True)}, 201 + except Exception as e: + return {"text": "Uncaught Exception:" + str(e)}, 500 + + +@api_endpoints.route('/status/') +def wait_seed_api(seed: UUID): + seed_id = seed + seed = Seed.get(id=seed_id) + if seed: + return {"text": "Generation done"}, 201 + generation = Generation.get(id=seed_id) + + if not generation: + return {"text": "Generation not found"}, 404 + elif generation.state == STATE_ERROR: + return {"text": "Generation failed"}, 500 + return {"text": "Generation running"}, 202 diff --git a/WebHostLib/generate.py b/WebHostLib/generate.py index a3397234..46ac6f42 100644 --- a/WebHostLib/generate.py +++ b/WebHostLib/generate.py @@ -52,55 +52,6 @@ def generate(race=False): return render_template("generate.html", race=race) -@app.route('/api/generate', methods=['POST']) -def generate_api(): - try: - options = {} - race = False - - if 'file' in request.files: - file = request.files['file'] - options = get_yaml_data(file) - if type(options) == str: - return {"text": options}, 400 - if "race" in request.form: - race = bool(0 if request.form["race"] in {"false"} else int(request.form["race"])) - - json_data = request.get_json() - if json_data: - if 'weights' in json_data: - # example: options = {"player1weights" : {}} - options = json_data["weights"] - if "race" in json_data: - race = bool(0 if json_data["race"] in {"false"} else int(json_data["race"])) - if not options: - return {"text": "No options found. Expected file attachment or json weights." - }, 400 - - if len(options) > app.config["MAX_ROLL"]: - return {"text": "Max size of multiworld exceeded", - "detail": app.config["MAX_ROLL"]}, 409 - - results, gen_options = roll_options(options) - if any(type(result) == str for result in results.values()): - return {"text": str(results), - "detail": results}, 400 - else: - gen = Generation( - options=pickle.dumps({name: vars(options) for name, options in gen_options.items()}), - # convert to json compatible - meta=pickle.dumps({"race": race}), state=STATE_QUEUED, - owner=session["_id"]) - commit() - return {"text": f"Generation of seed {gen.id} started successfully.", - "detail": gen.id, - "encoded": app.url_map.converters["suuid"].to_url(None, gen.id), - "wait_api_url": url_for("wait_seed_api", seed=gen.id, _external=True), - "url": url_for("wait_seed", seed=gen.id, _external=True)}, 201 - except Exception as e: - return {"text": "Uncaught Exception:" + str(e)}, 500 - - def gen_game(gen_options, race=False, owner=None, sid=None): try: target = tempfile.TemporaryDirectory() @@ -168,21 +119,6 @@ def wait_seed(seed: UUID): return render_template("wait_seed.html", seed_id=seed_id) -@app.route('/api/status/') -def wait_seed_api(seed: UUID): - seed_id = seed - seed = Seed.get(id=seed_id) - if seed: - return {"text": "Generation done"}, 201 - generation = Generation.get(id=seed_id) - - if not generation: - return {"text": "Generation not found"}, 404 - elif generation.state == STATE_ERROR: - return {"text": "Generation failed"}, 500 - return {"text": "Generation running"}, 202 - - def upload_to_db(folder, owner, sid, race:bool): patches = set() spoiler = ""