Remove app_module_for_backend
* Replace app_module_for_backend with ASGI factory on `rx.App.__call__` * Consolidate module spec for uvicorn, gunicorn, and granian
This commit is contained in:
parent
c3ac051bbb
commit
78277af4e9
@ -468,6 +468,22 @@ class App(MiddlewareMixin, LifespanMixin):
|
|||||||
"""
|
"""
|
||||||
if not self.api:
|
if not self.api:
|
||||||
raise ValueError("The app has not been initialized.")
|
raise ValueError("The app has not been initialized.")
|
||||||
|
|
||||||
|
# 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
|
||||||
|
)
|
||||||
|
compile_future.add_done_callback(
|
||||||
|
# Force background compile errors to print eagerly
|
||||||
|
lambda f: f.result()
|
||||||
|
)
|
||||||
|
# Wait for the compile to finish in prod mode to ensure all optional endpoints are mounted.
|
||||||
|
if is_prod_mode():
|
||||||
|
compile_future.result()
|
||||||
|
|
||||||
return self.api
|
return self.api
|
||||||
|
|
||||||
def _add_default_endpoints(self):
|
def _add_default_endpoints(self):
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
"""Shims the real reflex app module for running backend server (uvicorn or gunicorn).
|
|
||||||
Only the app attribute is explicitly exposed.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
|
||||||
|
|
||||||
from reflex import constants
|
|
||||||
from reflex.utils.exec import is_prod_mode
|
|
||||||
from reflex.utils.prerequisites import get_and_validate_app
|
|
||||||
|
|
||||||
if constants.CompileVars.APP != "app":
|
|
||||||
raise AssertionError("unexpected variable name for 'app'")
|
|
||||||
|
|
||||||
app, app_module = get_and_validate_app(reload=False)
|
|
||||||
# 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).
|
|
||||||
app._apply_decorated_pages()
|
|
||||||
compile_future = ThreadPoolExecutor(max_workers=1).submit(app._compile)
|
|
||||||
compile_future.add_done_callback(
|
|
||||||
# Force background compile errors to print eagerly
|
|
||||||
lambda f: f.result()
|
|
||||||
)
|
|
||||||
# Wait for the compile to finish in prod mode to ensure all optional endpoints are mounted.
|
|
||||||
if is_prod_mode():
|
|
||||||
compile_future.result()
|
|
||||||
|
|
||||||
# ensure only "app" is exposed.
|
|
||||||
del app_module
|
|
||||||
del compile_future
|
|
||||||
del get_and_validate_app
|
|
||||||
del is_prod_mode
|
|
||||||
del constants
|
|
||||||
del ThreadPoolExecutor
|
|
@ -195,22 +195,9 @@ def get_app_module():
|
|||||||
Returns:
|
Returns:
|
||||||
The app module for the backend.
|
The app module for the backend.
|
||||||
"""
|
"""
|
||||||
return f"reflex.app_module_for_backend:{constants.CompileVars.APP}"
|
config = get_config()
|
||||||
|
|
||||||
|
return f"{config.module}:{constants.CompileVars.APP}"
|
||||||
def get_granian_target():
|
|
||||||
"""Get the Granian target for the backend.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The Granian target for the backend.
|
|
||||||
"""
|
|
||||||
import reflex
|
|
||||||
|
|
||||||
app_module_path = Path(reflex.__file__).parent / "app_module_for_backend.py"
|
|
||||||
|
|
||||||
return (
|
|
||||||
f"{app_module_path!s}:{constants.CompileVars.APP}.{constants.CompileVars.API}"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def run_backend(
|
def run_backend(
|
||||||
@ -278,7 +265,8 @@ def run_uvicorn_backend(host: str, port: int, loglevel: LogLevel):
|
|||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
uvicorn.run(
|
uvicorn.run(
|
||||||
app=f"{get_app_module()}.{constants.CompileVars.API}",
|
app=f"{get_app_module()}",
|
||||||
|
factory=True,
|
||||||
host=host,
|
host=host,
|
||||||
port=port,
|
port=port,
|
||||||
log_level=loglevel.value,
|
log_level=loglevel.value,
|
||||||
@ -304,7 +292,8 @@ def run_granian_backend(host: str, port: int, loglevel: LogLevel):
|
|||||||
from granian.log import LogLevels # pyright: ignore [reportMissingImports]
|
from granian.log import LogLevels # pyright: ignore [reportMissingImports]
|
||||||
|
|
||||||
Granian(
|
Granian(
|
||||||
target=get_granian_target(),
|
target=get_app_module(),
|
||||||
|
factory=True,
|
||||||
address=host,
|
address=host,
|
||||||
port=port,
|
port=port,
|
||||||
interface=Interfaces.ASGI,
|
interface=Interfaces.ASGI,
|
||||||
@ -377,6 +366,7 @@ def run_uvicorn_backend_prod(host: str, port: int, loglevel: LogLevel):
|
|||||||
host,
|
host,
|
||||||
"--port",
|
"--port",
|
||||||
str(port),
|
str(port),
|
||||||
|
"--factory",
|
||||||
app_module,
|
app_module,
|
||||||
]
|
]
|
||||||
if constants.IS_WINDOWS
|
if constants.IS_WINDOWS
|
||||||
@ -433,7 +423,8 @@ def run_granian_backend_prod(host: str, port: int, loglevel: LogLevel):
|
|||||||
str(port),
|
str(port),
|
||||||
"--interface",
|
"--interface",
|
||||||
str(Interfaces.ASGI),
|
str(Interfaces.ASGI),
|
||||||
get_granian_target(),
|
"--factory",
|
||||||
|
get_app_module(),
|
||||||
]
|
]
|
||||||
processes.new_process(
|
processes.new_process(
|
||||||
command,
|
command,
|
||||||
|
Loading…
Reference in New Issue
Block a user