From bb2f4ac37e116f1c7661369ba1d35c9d77faf4ef Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Mar 2026 07:19:53 +0100 Subject: [PATCH 1/3] fix: migrate from add_event_handler to lifespan add_event_handler was removed in starlette 1.0.0 --- freqtrade/rpc/api_server/webserver.py | 33 ++++++++++++--------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/freqtrade/rpc/api_server/webserver.py b/freqtrade/rpc/api_server/webserver.py index 905eced14..2dcbb54e9 100644 --- a/freqtrade/rpc/api_server/webserver.py +++ b/freqtrade/rpc/api_server/webserver.py @@ -1,3 +1,4 @@ +from contextlib import asynccontextmanager import logging from ipaddress import ip_address from typing import Any @@ -100,6 +101,19 @@ class FTJSONResponse(JSONResponse): return orjson.dumps(content, option=orjson.OPT_SERIALIZE_NUMPY) +@asynccontextmanager +async def lifespan(app: FastAPI): + # Startup logic + if not ApiServer._message_stream: + # Creates the MessageStream class on startup so it has access to the same event loop + # as uvicorn + ApiServer._message_stream = MessageStream() + yield + # Shutdown logic + if ApiServer._message_stream: + ApiServer._message_stream = None + + class ApiServer(RPCHandler): __instance = None __initialized = False @@ -137,6 +151,7 @@ class ApiServer(RPCHandler): redoc_url=None, default_response_class=FTJSONResponse, openapi_tags=_OPENAPI_TAGS, + lifespan=lifespan, ) self.configure_app(self.app, self._config) self.start_api() @@ -261,24 +276,6 @@ class ApiServer(RPCHandler): ) app.add_exception_handler(RPCException, self.handle_rpc_exception) - app.add_event_handler(event_type="startup", func=self._api_startup_event) - app.add_event_handler(event_type="shutdown", func=self._api_shutdown_event) - - async def _api_startup_event(self): - """ - Creates the MessageStream class on startup - so it has access to the same event loop - as uvicorn - """ - if not ApiServer._message_stream: - ApiServer._message_stream = MessageStream() - - async def _api_shutdown_event(self): - """ - Removes the MessageStream class on shutdown - """ - if ApiServer._message_stream: - ApiServer._message_stream = None def start_api(self): """ From cea1700eaaa536d8b4a08ef2e436917afad7f754 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Mar 2026 07:20:08 +0100 Subject: [PATCH 2/3] chore: drop starlette upper version bound --- requirements.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 345b39d5e..166505a08 100644 --- a/requirements.txt +++ b/requirements.txt @@ -38,8 +38,6 @@ sdnotify==0.3.2 # API Server fastapi==0.135.1 -# TODO: starlette should not be pinned, but had breaking changes in 1.0.0. -starlette<1.0.0 pydantic==2.12.5 uvicorn==0.41.0 pyjwt==2.12.0 From 143d9a90c6f6c10dbc4456a5aa641d16b068ba7e Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2026 06:33:57 +0100 Subject: [PATCH 3/3] chore: import sorting --- freqtrade/rpc/api_server/webserver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/rpc/api_server/webserver.py b/freqtrade/rpc/api_server/webserver.py index 2dcbb54e9..1403da883 100644 --- a/freqtrade/rpc/api_server/webserver.py +++ b/freqtrade/rpc/api_server/webserver.py @@ -1,5 +1,5 @@ -from contextlib import asynccontextmanager import logging +from contextlib import asynccontextmanager from ipaddress import ip_address from typing import Any