From 4c62bfd9cf908207b7f597ff4b5aa0559ed75170 Mon Sep 17 00:00:00 2001 From: Matthew Horridge Date: Fri, 23 Jan 2026 13:42:18 -0800 Subject: [PATCH 1/2] Migrate API from Flask to FastAPI - Replace Flask app/blueprints with FastAPI app and router - Update health endpoint to FastAPI - Replace run script with uvicorn-based run_api.sh - Drop Flask dependencies and add fastapi/uvicorn - Update API docs to use new run script --- requirements.txt | 4 ++-- scripts/run_api.sh | 1 + scripts/run_flask.sh | 4 ---- src/harmonization_framework/api/app.py | 14 +++++--------- src/harmonization_framework/api/extensions.py | 4 ---- .../api/harmonization_api_examples.md | 2 +- src/harmonization_framework/api/routes/__init__.py | 4 ++-- src/harmonization_framework/api/routes/health.py | 8 ++++---- 8 files changed, 15 insertions(+), 26 deletions(-) create mode 100755 scripts/run_api.sh delete mode 100755 scripts/run_flask.sh delete mode 100644 src/harmonization_framework/api/extensions.py diff --git a/requirements.txt b/requirements.txt index dfe100b..9cad308 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -flask==3.1.1 -flask-cors==6.0.1 +fastapi==0.115.6 +uvicorn==0.30.6 flexcache==0.3 flexparser==0.3.1 ipykernel==6.29.5 diff --git a/scripts/run_api.sh b/scripts/run_api.sh new file mode 100755 index 0000000..109fec2 --- /dev/null +++ b/scripts/run_api.sh @@ -0,0 +1 @@ +uvicorn harmonization_framework.api.app:app --reload diff --git a/scripts/run_flask.sh b/scripts/run_flask.sh deleted file mode 100755 index f27e785..0000000 --- a/scripts/run_flask.sh +++ /dev/null @@ -1,4 +0,0 @@ -export FLASK_APP=src/harmonization_framework/api/app.py -export FLASK_ENV=development - -flask run diff --git a/src/harmonization_framework/api/app.py b/src/harmonization_framework/api/app.py index 35ab300..d5548f4 100644 --- a/src/harmonization_framework/api/app.py +++ b/src/harmonization_framework/api/app.py @@ -1,11 +1,7 @@ -from flask import Flask -from harmonization_framework.api.extensions import register_extensions -from harmonization_framework.api.routes.health import health_blueprint +from fastapi import FastAPI -def create_app(config_name=None): - app = Flask(__name__, instance_relative_config=True) - - register_extensions(app) +from harmonization_framework.api.routes.health import router as health_router - app.register_blueprint(health_blueprint, url_prefix="/health") - return app +app = FastAPI(title="Harmonization Framework API") + +app.include_router(health_router, prefix="/health") diff --git a/src/harmonization_framework/api/extensions.py b/src/harmonization_framework/api/extensions.py deleted file mode 100644 index 6f65660..0000000 --- a/src/harmonization_framework/api/extensions.py +++ /dev/null @@ -1,4 +0,0 @@ -from flask_cors import CORS - -def register_extensions(app): - CORS(app) diff --git a/src/harmonization_framework/api/harmonization_api_examples.md b/src/harmonization_framework/api/harmonization_api_examples.md index 3a4851f..bc5de40 100644 --- a/src/harmonization_framework/api/harmonization_api_examples.md +++ b/src/harmonization_framework/api/harmonization_api_examples.md @@ -7,7 +7,7 @@ The following is a demo for using `curl` to interact with the Harmonization Fram ## Start API ```bash -./scripts/run_flask.sh +./scripts/run_api.sh ``` ## Example Usage diff --git a/src/harmonization_framework/api/routes/__init__.py b/src/harmonization_framework/api/routes/__init__.py index 30b3e31..58055d8 100644 --- a/src/harmonization_framework/api/routes/__init__.py +++ b/src/harmonization_framework/api/routes/__init__.py @@ -1,7 +1,7 @@ # src/api/routes/__init__.py -from .health import health_blueprint +from .health import router as health_router __all__ = [ - "health_blueprint", + "health_router", ] diff --git a/src/harmonization_framework/api/routes/health.py b/src/harmonization_framework/api/routes/health.py index 16cfdbd..7fa43db 100644 --- a/src/harmonization_framework/api/routes/health.py +++ b/src/harmonization_framework/api/routes/health.py @@ -1,7 +1,7 @@ -from flask import Blueprint, jsonify +from fastapi import APIRouter -health_blueprint = Blueprint("health", __name__) +router = APIRouter() -@health_blueprint.route("/", methods=["GET"]) +@router.get("/") def health_check(): - return jsonify(status="ok", message="API is available"), 200 + return {"status": "ok", "message": "API is available"} From 384e5da18641be736498153c0ab36dfb7eedee96 Mon Sep 17 00:00:00 2001 From: Matthew Horridge Date: Fri, 23 Jan 2026 13:51:57 -0800 Subject: [PATCH 2/2] Add response model for health endpoint - Define HealthResponse schema for FastAPI --- src/harmonization_framework/api/routes/health.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/harmonization_framework/api/routes/health.py b/src/harmonization_framework/api/routes/health.py index 7fa43db..46e2245 100644 --- a/src/harmonization_framework/api/routes/health.py +++ b/src/harmonization_framework/api/routes/health.py @@ -1,7 +1,14 @@ from fastapi import APIRouter +from pydantic import BaseModel router = APIRouter() + +class HealthResponse(BaseModel): + status: str + message: str + + @router.get("/") -def health_check(): - return {"status": "ok", "message": "API is available"} +def health_check() -> HealthResponse: + return HealthResponse(status="ok", message="The harmonization API is available")