From c70954e85a119dc5ef3e33e96012f62f9e8d893f Mon Sep 17 00:00:00 2001 From: Cody Baker Date: Fri, 24 May 2024 14:50:17 -0400 Subject: [PATCH] debugging --- src/__init__.py | 0 src/pyflask/__init__.py | 0 src/pyflask/apis/_dandi.py | 6 +-- src/pyflask/apis/_neurosift.py | 4 +- src/pyflask/apis/_system.py | 4 +- src/pyflask/apis/data.py | 3 +- src/pyflask/{ => apis}/utils/__init__.py | 0 src/pyflask/{ => apis}/utils/_flask_errors.py | 0 src/pyflask/app.py | 37 ++++---------- src/pyflask/manageNeuroconv/info/__init__.py | 3 +- src/pyflask/manageNeuroconv/info/urls.py | 50 ++++++++++++------- 11 files changed, 54 insertions(+), 53 deletions(-) create mode 100644 src/__init__.py create mode 100644 src/pyflask/__init__.py rename src/pyflask/{ => apis}/utils/__init__.py (100%) rename src/pyflask/{ => apis}/utils/_flask_errors.py (100%) diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/pyflask/__init__.py b/src/pyflask/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/pyflask/apis/_dandi.py b/src/pyflask/apis/_dandi.py index df8584acb..003852c3a 100644 --- a/src/pyflask/apis/_dandi.py +++ b/src/pyflask/apis/_dandi.py @@ -2,9 +2,9 @@ from typing import List, Tuple, Union -import flask.restx +import flask_restx -from ..utils import catch_exception_and_abort, server_error_responses +from .utils import catch_exception_and_abort, server_error_responses dandi_api = flask_restx.Namespace( name="dandi", description="Request various static listings from the DANDI Python API." @@ -14,7 +14,7 @@ @dandi_api.route(rule="/get-recommended-species") class SupportedSpecies(flask_restx.Resource): - @neurosift_api.doc( + @dandi_api.doc( description="Request the list of currently supported species (by Latin Binomial name) for DANDI. Note that any " "explicit NCBI taxonomy link is also supported.", responses=server_error_responses(codes=[200, 500]), diff --git a/src/pyflask/apis/_neurosift.py b/src/pyflask/apis/_neurosift.py index e1e28e988..e43f89746 100644 --- a/src/pyflask/apis/_neurosift.py +++ b/src/pyflask/apis/_neurosift.py @@ -4,9 +4,9 @@ from typing import Union import flask -import flask.restx +import flask_restx -from ..utils import ( +from .utils import ( abort_if_not_nwb_file, catch_exception_and_abort, server_error_responses, diff --git a/src/pyflask/apis/_system.py b/src/pyflask/apis/_system.py index 605852320..d384362d9 100644 --- a/src/pyflask/apis/_system.py +++ b/src/pyflask/apis/_system.py @@ -2,9 +2,9 @@ from typing import Dict, Union -import flask.restx +import flask_restx -from ..utils import catch_exception_and_abort, server_error_responses +from .utils import catch_exception_and_abort, server_error_responses system_api = flask_restx.Namespace(name="system", description="Request various system specific information.") diff --git a/src/pyflask/apis/data.py b/src/pyflask/apis/data.py index a3e05f985..30de92ba1 100644 --- a/src/pyflask/apis/data.py +++ b/src/pyflask/apis/data.py @@ -4,7 +4,8 @@ from flask_restx import Namespace, Resource, reqparse from manageNeuroconv import generate_dataset, generate_test_data -from utils import catch_exception_and_abort, server_error_responses + +from .utils import catch_exception_and_abort, server_error_responses data_api = Namespace(name="data", description="API route for dataset generation in the NWB GUIDE.") diff --git a/src/pyflask/utils/__init__.py b/src/pyflask/apis/utils/__init__.py similarity index 100% rename from src/pyflask/utils/__init__.py rename to src/pyflask/apis/utils/__init__.py diff --git a/src/pyflask/utils/_flask_errors.py b/src/pyflask/apis/utils/_flask_errors.py similarity index 100% rename from src/pyflask/utils/_flask_errors.py rename to src/pyflask/apis/utils/_flask_errors.py diff --git a/src/pyflask/app.py b/src/pyflask/app.py index e8e2edb89..d1344ecf9 100644 --- a/src/pyflask/app.py +++ b/src/pyflask/app.py @@ -7,11 +7,8 @@ from datetime import datetime from logging import DEBUG, Formatter from logging.handlers import RotatingFileHandler -from os.path import isabs from pathlib import Path from signal import SIGINT -from typing import Union -from urllib.parse import unquote # https://stackoverflow.com/questions/32672596/pyinstaller-loads-script-multiple-times#comment103216434_32677108 multiprocessing.freeze_support() @@ -25,16 +22,11 @@ startup_api, system_api, ) -from flask import Flask, Response, send_file, send_from_directory +from apis.utils import catch_exception_and_abort, server_error_responses +from flask import Flask from flask_cors import CORS from flask_restx import Api, Resource -from manageNeuroconv.info import ( - CONVERSION_SAVE_FOLDER_PATH, - GUIDE_ROOT_FOLDER, - STUB_SAVE_FOLDER_PATH, - resource_path, -) -from utils import catch_exception_and_abort, server_error_responses +from manageNeuroconv.info import GUIDE_ROOT_FOLDER, get_project_root_path all_apis = [data_api, neuroconv_api, startup_api, neurosift_api, dandi_api, system_api] @@ -51,8 +43,8 @@ LOG_FILE_PATH = Path(LOG_FOLDER) / f"{timestamp}.log" # Fetch version from package.json -package_json_file_path = resource_path("package.json") -with open(file=package_json_file_path) as fp: +package_json_file_path = get_project_root_path() / "package.json" +with open(file=package_json_file_path, mode="r") as fp: package_json = json.load(fp=fp) # Initialize top-level API and set namespaces @@ -89,21 +81,14 @@ def post(self): selected_logger(message) -@flask_app.route("/cpus") -def get_cpu_count(): - from psutil import cpu_count - - physical = cpu_count(logical=False) - logical = cpu_count() - - return dict(physical=physical, logical=logical) - - @flask_api.route("/server_shutdown", endpoint="shutdown") -@neurosift_api.doc( - description="Handle adding and fetching NWB files from the global file registry.", -) +@flask_api.doc(description="Close the Flask server.") class Shutdown(Resource): + + @flask_api.doc( + description="To trigger a shutdown, set a GET request to this endpoint. It will not return a response.", + responses=server_error_responses(codes=[200, 500]), + ) def get(self) -> None: werkzeug_shutdown_function = flask.request.environ.get("werkzeug.server.shutdown") flask_api.logger.info("Shutting down server...") diff --git a/src/pyflask/manageNeuroconv/info/__init__.py b/src/pyflask/manageNeuroconv/info/__init__.py index edde04113..fdf5a36ba 100644 --- a/src/pyflask/manageNeuroconv/info/__init__.py +++ b/src/pyflask/manageNeuroconv/info/__init__.py @@ -3,5 +3,6 @@ CONVERSION_SAVE_FOLDER_PATH, GUIDE_ROOT_FOLDER, STUB_SAVE_FOLDER_PATH, - resource_path, + get_project_root_path, + get_source_base_path, ) diff --git a/src/pyflask/manageNeuroconv/info/urls.py b/src/pyflask/manageNeuroconv/info/urls.py index bf8a65116..7bb586235 100644 --- a/src/pyflask/manageNeuroconv/info/urls.py +++ b/src/pyflask/manageNeuroconv/info/urls.py @@ -1,36 +1,50 @@ import json import os +import pathlib import sys -from pathlib import Path -def resource_path(relative_path): - """Get absolute path to resource, works for dev and for PyInstaller""" - try: +def get_source_base_path() -> pathlib.Path: + """Get absolute path of a relative resource to the app; works for both dev mode and for PyInstaller.""" + # Production: PyInstaller creates a temp folder and stores path in _MEIPASS + if hasattr(sys, "_MEIPASS"): # PyInstaller creates a temp folder and stores path in _MEIPASS - base_path = sys._MEIPASS - except Exception: - base_path = Path(__file__).parent.parent.parent.parent + base_path = pathlib.Path(sys._MEIPASS) - return Path(base_path) / relative_path + # Dev mode: base is the root of the `src` directory for the project + else: + base_path = pathlib.Path(__file__).parent.parent.parent.parent + + return base_path + + +def get_project_root_path() -> pathlib.Path: + """Get absolute path of a relative resource to the app; works for both dev mode and for PyInstaller.""" + # Production: PyInstaller creates a temp folder and stores path in _MEIPASS + if hasattr(sys, "_MEIPASS"): + # PyInstaller creates a temp folder and stores path in _MEIPASS + base_path = pathlib.Path(sys._MEIPASS).parent + + # Dev mode: base is the root of the `src` directory for the project + else: + base_path = pathlib.Path(__file__).parent.parent.parent.parent.parent + + return base_path is_test_environment = os.environ.get("VITEST") -path_config = resource_path( - "paths.config.json" -) # NOTE: Must have pyflask for running the GUIDE as a whole, but errors for just the server -f = path_config.open() -data = json.load(f) -GUIDE_ROOT_FOLDER = Path(Path.home(), data["root"]) + +path_config_file_path = get_source_base_path() / "paths.config.json" +with open(file=path_config_file_path, mode="r") as fp: + path_config = json.load(fp=fp) +GUIDE_ROOT_FOLDER = pathlib.Path.home() / path_config["root"] if is_test_environment: GUIDE_ROOT_FOLDER = GUIDE_ROOT_FOLDER / ".test" -STUB_SAVE_FOLDER_PATH = Path(GUIDE_ROOT_FOLDER, *data["subfolders"]["preview"]) -CONVERSION_SAVE_FOLDER_PATH = Path(GUIDE_ROOT_FOLDER, *data["subfolders"]["conversions"]) - -f.close() +STUB_SAVE_FOLDER_PATH = pathlib.Path(GUIDE_ROOT_FOLDER, *path_config["subfolders"]["preview"]) +CONVERSION_SAVE_FOLDER_PATH = pathlib.Path(GUIDE_ROOT_FOLDER, *path_config["subfolders"]["conversions"]) # Create all nested home folders STUB_SAVE_FOLDER_PATH.mkdir(exist_ok=True, parents=True)