Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ keywords = ["web", "framework"]
requires-python = ">=3.10,<4.0"
dependencies = [
"alembic >=1.15.2,<2.0",
"fastapi >=0.115.0",
"starlette >=0.47.0",
"granian[reload] >=2.4.0",
"httpx >=0.28.0,<1.0",
"jinja2 >=3.1.2,<4.0",
Expand Down
26 changes: 6 additions & 20 deletions reflex/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from types import SimpleNamespace
from typing import TYPE_CHECKING, Any, BinaryIO, ParamSpec, get_args, get_type_hints

from fastapi import FastAPI
from rich.progress import MofNCompleteColumn, Progress, TimeElapsedColumn
from socketio import ASGIApp as EngineIOApp
from socketio import AsyncNamespace, AsyncServer
Expand Down Expand Up @@ -441,9 +440,6 @@ class App(MiddlewareMixin, LifespanMixin):
| None
) = None

# FastAPI app for compatibility with FastAPI.
_cached_fastapi_app: FastAPI | None = None

@property
def event_namespace(self) -> EventNamespace | None:
"""Get the event namespace.
Expand Down Expand Up @@ -598,32 +594,22 @@ def __call__(self) -> ASGIApp:
Returns:
The backend api.
"""
from reflex.vars.base import GLOBAL_CACHE

# For py3.9 compatibility when redis is used, we MUST add any decorator pages
# before compiling the app in a thread to avoid event loop error (REF-2172).
self._apply_decorated_pages()

compile_future = concurrent.futures.ThreadPoolExecutor(max_workers=1).submit(
self._compile, prerender_routes=is_prod_mode()
)
self._compile(prerender_routes=is_prod_mode())

def callback(f: concurrent.futures.Future):
# Force background compile errors to print eagerly
return f.result()

compile_future.add_done_callback(callback)
# Wait for the compile to finish to ensure all optional endpoints are mounted.
compile_future.result()
# We will not be making more vars, so we can clear the global cache to free up memory.
GLOBAL_CACHE.clear()

if not self._api:
msg = "The app has not been initialized."
raise ValueError(msg)

if self._cached_fastapi_app is not None:
asgi_app = self._cached_fastapi_app
asgi_app.mount("", self._api)
App._add_cors(asgi_app)
else:
asgi_app = self._api
asgi_app = self._api

if self.api_transformer is not None:
api_transformers: Sequence[Starlette | Callable[[ASGIApp], ASGIApp]] = (
Expand Down
Loading