From 770d90c6f2d864bfda247c58b06c77e42e07ce23 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Tue, 21 Jul 2026 15:18:40 +0200 Subject: [PATCH 1/5] save wip [skip ci] --- src/opengeodeweb_back/app.py | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/opengeodeweb_back/app.py b/src/opengeodeweb_back/app.py index 2da06e51..53a112ab 100644 --- a/src/opengeodeweb_back/app.py +++ b/src/opengeodeweb_back/app.py @@ -14,6 +14,11 @@ from opengeodeweb_back.routes.create import blueprint_create from opengeodeweb_microservice.database import connection +import queue +import threading +import json +from typing import Any, Dict, Generator, Tuple + def create_app(name: str) -> flask.Flask: app = flask.Flask(name) @@ -29,6 +34,40 @@ def before_request() -> flask.Response | None: utils_functions.before_request(flask.current_app) return None + def wants_event_stream() -> bool: + accept = flask.request.headers.get("Accept", "") + return "text/event-stream" in accept + + _event_queue: queue.Queue[tuple[str, dict[str, Any]]] = queue.Queue() + _lock = threading.Lock() + + def publish_event(event: str, data: dict[str, Any]) -> None: + _event_queue.put((event, data)) + + def stream_events() -> Generator[str, None, None]: + while True: + event, data = _event_queue.get() + yield f"event: {event}\ndata: {json.dumps(data)}\n\n" + + @app.after_request + def after_request(response: flask.Response) -> flask.Response: + if flask.request.endpoint == "events": + return response + + if wants_event_stream(): + event_name = flask.request.endpoint + print("wants_event_stream", wants_event_stream(), event_name, flush=True) + if event_name is None: + return response + + payload: dict[str, Any] + try: + payload = response.get_json() + except Exception: + payload = {"status": response.status_code} + publish_event(event_name, payload) + return response + @app.teardown_request def teardown_request(exception: BaseException | None) -> None: utils_functions.teardown_request(flask.current_app, exception) @@ -46,6 +85,10 @@ def handle_generic_exception(exception: Exception) -> Response: "/error", methods=["POST"], ) + + @app.route("/events") + def events() -> flask.Response: + return flask.Response(stream_events(), mimetype="text/event-stream") def return_error() -> Response: flask.abort(500, f"Test") return flask.make_response({}, 500) From f9184d4304b41fd9d8ba684a47ea19947528f1f7 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Fri, 31 Jul 2026 13:43:28 +0200 Subject: [PATCH 2/5] v0 working From 38bff732e363295ec9113c8913c29e701bc94c50 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Fri, 31 Jul 2026 13:51:05 +0200 Subject: [PATCH 3/5] feat(App): handle event publishing cleanup --- src/opengeodeweb_back/app.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/opengeodeweb_back/app.py b/src/opengeodeweb_back/app.py index 53a112ab..58ebae29 100644 --- a/src/opengeodeweb_back/app.py +++ b/src/opengeodeweb_back/app.py @@ -56,7 +56,6 @@ def after_request(response: flask.Response) -> flask.Response: if wants_event_stream(): event_name = flask.request.endpoint - print("wants_event_stream", wants_event_stream(), event_name, flush=True) if event_name is None: return response From 0f479761be041fe6526382cffbb2efa4e67324e7 Mon Sep 17 00:00:00 2001 From: JulienChampagnol <91873154+JulienChampagnol@users.noreply.github.com> Date: Fri, 31 Jul 2026 11:52:13 +0000 Subject: [PATCH 4/5] Apply prepare changes --- requirements.txt | 1 - src/opengeodeweb_back/app.py | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 26be316f..d1953d29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -66,4 +66,3 @@ werkzeug==3.1.8 # flask # flask-cors -opengeodeweb-microservice==1.*,>=1.1.4 diff --git a/src/opengeodeweb_back/app.py b/src/opengeodeweb_back/app.py index 58ebae29..21522072 100644 --- a/src/opengeodeweb_back/app.py +++ b/src/opengeodeweb_back/app.py @@ -47,7 +47,7 @@ def publish_event(event: str, data: dict[str, Any]) -> None: def stream_events() -> Generator[str, None, None]: while True: event, data = _event_queue.get() - yield f"event: {event}\ndata: {json.dumps(data)}\n\n" + yield f"event: {event}\ndata: {json.dumps(data)}\n\n" @app.after_request def after_request(response: flask.Response) -> flask.Response: @@ -84,10 +84,10 @@ def handle_generic_exception(exception: Exception) -> Response: "/error", methods=["POST"], ) - @app.route("/events") def events() -> flask.Response: return flask.Response(stream_events(), mimetype="text/event-stream") + def return_error() -> Response: flask.abort(500, f"Test") return flask.make_response({}, 500) From f9dc1aa1a4272350ec70f0498f51cc6c546d9d43 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Fri, 31 Jul 2026 15:58:30 +0200 Subject: [PATCH 5/5] pr comments --- src/opengeodeweb_back/app.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/opengeodeweb_back/app.py b/src/opengeodeweb_back/app.py index 21522072..429dd5d6 100644 --- a/src/opengeodeweb_back/app.py +++ b/src/opengeodeweb_back/app.py @@ -51,20 +51,17 @@ def stream_events() -> Generator[str, None, None]: @app.after_request def after_request(response: flask.Response) -> flask.Response: - if flask.request.endpoint == "events": + endpoint = flask.request.endpoint + if endpoint == "events" or endpoint == None: return response if wants_event_stream(): - event_name = flask.request.endpoint - if event_name is None: - return response - payload: dict[str, Any] try: payload = response.get_json() except Exception: payload = {"status": response.status_code} - publish_event(event_name, payload) + publish_event(endpoint, payload) return response @app.teardown_request