From 02272863967094357582454b4885d09f7e02dd37 Mon Sep 17 00:00:00 2001 From: Andreas Berthoud Date: Tue, 6 Jul 2021 18:28:35 +0200 Subject: [PATCH] backend: Add basic structure --- .gitignore | 1 + backend/__init__.py | 36 ++++++++++++++++++++++++++ backend/command.py | 62 +++++++++++++++++++++++++++++++++++++++++++++ backend/runsever.py | 3 +++ requirements.txt | 1 + 5 files changed, 103 insertions(+) create mode 100644 backend/__init__.py create mode 100644 backend/command.py create mode 100644 backend/runsever.py diff --git a/.gitignore b/.gitignore index 1ee3cdf..96189e7 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,4 @@ Debug/ Release/ .vscode/ venv*/ +*.pyc diff --git a/backend/__init__.py b/backend/__init__.py new file mode 100644 index 0000000..68d6812 --- /dev/null +++ b/backend/__init__.py @@ -0,0 +1,36 @@ +import os +from logging.config import dictConfig + +from flask_api import FlaskAPI + +from . import command + + +def create_app() -> FlaskAPI: + app = FlaskAPI(__name__) + app.register_blueprint(command.bp) + + dictConfig( + { + "version": 1, + "formatters": { + "default": { + "format": "[%(asctime)s] %(levelname)s in %(module)s: %(message)s", + }, + }, + "handlers": { + "wsgi": { + "class": "logging.StreamHandler", + "stream": "ext://flask.logging.wsgi_errors_stream", + "formatter": "default", + }, + }, + "root": {"level": "INFO", "handlers": ["wsgi"]}, + }, + ) + + if os.environ.get("WERKZEUG_RUN_MAIN") != "true": + # prevent from be called twice in debug mode + command.start_backgroup_process() + + return app diff --git a/backend/command.py b/backend/command.py new file mode 100644 index 0000000..a9d3398 --- /dev/null +++ b/backend/command.py @@ -0,0 +1,62 @@ +import atexit +import logging +import os +import time +from multiprocessing import Process +from multiprocessing import Queue +from typing import Optional + +from flask import Response +from flask import blueprints +from flask import request +from flask_api import status + +bp = blueprints.Blueprint("command", __name__) + +_process: Optional[Process] = None +_queue: Queue = Queue() +_logger = logging.getLogger(__name__) + + +@bp.route("/command", methods=["POST", "GET"]) +def command(): + logger = logging.getLogger("test") + command_id = request.args.get("command-id") + + if _queue is not None and command_id is not None: + logger.info(f"put in queue: {command_id}") + _queue.put(command_id) + + return Response(status=status.HTTP_200_OK) + + +def _end_running_process(): + if _process is not None: + _process.kill() + + +def poll_from_usb(queue: Queue): + logging.basicConfig( + level=logging.DEBUG, + format="[%(asctime)s] [%(levelname)-8s] --- %(message)s", + ) + logger = logging.getLogger("poll_from_usb") + counter = 1 + while True: + logger.info(f"Ping {counter} {os.getpid()}") + counter += 1 + time.sleep(1) + + if queue is not None: + while not queue.empty(): + command_id = queue.get() + logger.info(f"would execute command: {command_id}") + + +def start_backgroup_process(): + _logger.warning("start_backgroup_process called") + global _process + + _process = Process(target=poll_from_usb, args=(_queue,)) + _process.start() + atexit.register(_end_running_process) diff --git a/backend/runsever.py b/backend/runsever.py new file mode 100644 index 0000000..a316945 --- /dev/null +++ b/backend/runsever.py @@ -0,0 +1,3 @@ +from . import create_app + +application = create_app() diff --git a/requirements.txt b/requirements.txt index 8d4a90a..98765ef 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ +flask-api>=3.0.post1,<4 pre-commit pyserial>=3.5,<4