reflex
reflex copied to clipboard
Create a debuggable pc / entry point
Hello, I loved the pynecode. But one major bad experience that would be a no go to me is that we have to develop in pynecone blindly.
The reason is that the pc run init a uvicorn as another process.
But this can be fixed and would be nice if pynecode had in the project an entrypoint that runs the frontend in another process but the backend in the same thread.
There is an example of this attached. If this file is on the project folder, you can debug it.
"""Pynecone CLI to run apps."""
import platform
import threading
from pathlib import Path
import typer
import uvicorn
from pynecone import constants
from pynecone.config import get_config
from pynecone.utils import build, console, exec, prerequisites, processes
# Create the app.
cli = typer.Typer()
def run_backend_debug(
app_name: str,
host: str,
port: int,
loglevel: constants.LogLevel = constants.LogLevel.ERROR,
):
"""Run the backend.
Args:
host: The app host
app_name: The app name.
port: The app port
loglevel: The log level.
"""
exec.setup_backend()
print(f"RUNNING app_name: {app_name}")
uvicorn.run(f"{app_name}:{constants.APP_VAR}.{constants.API_VAR}", host=host, port=int(port), reload=False, log_level=loglevel)
@cli.command()
def run(
frontend: bool = typer.Option(
False, "--frontend-only", help="Execute only frontend."
),
backend: bool = typer.Option(False, "--backend-only", help="Execute only backend."),
loglevel: constants.LogLevel = typer.Option(
constants.LogLevel.ERROR, help="The log level to use."
),
frontend_port: str = typer.Option(None, help="Specify a different frontend port."),
backend_port: str = typer.Option(None, help="Specify a different backend port."),
backend_host: str = typer.Option(None, help="Specify the backend host."),
):
"""Run the app in the current directory."""
if platform.system() == "Windows":
console.print(
"[yellow][WARNING] We strongly advise you to use Windows Subsystem for Linux (WSL) for optimal performance when using Pynecone. Due to compatibility issues with one of our dependencies, Bun, you may experience slower performance on Windows. By using WSL, you can expect to see a significant speed increase."
)
# Set ports as os env variables to take precedence over config and
# .env variables(if override_os_envs flag in config is set to False).
build.set_os_env(
frontend_port=frontend_port,
backend_port=backend_port,
backend_host=backend_host,
)
frontend_port = (
get_config().frontend_port if frontend_port is None else frontend_port
)
backend_port = get_config().backend_port if backend_port is None else backend_port
backend_host = get_config().backend_host if backend_host is None else backend_host
# If no --frontend-only and no --backend-only, then turn on frontend and backend both
if not frontend and not backend:
frontend = True
backend = True
# If something is running on the ports, ask the user if they want to kill or change it.
if frontend and processes.is_process_on_port(frontend_port):
frontend_port = processes.change_or_terminate_port(frontend_port, "frontend")
if backend and processes.is_process_on_port(backend_port):
backend_port = processes.change_or_terminate_port(backend_port, "backend")
# Check that the app is initialized.
if frontend and not prerequisites.is_initialized():
console.print(
"[red]The app is not initialized. Run [bold]pc init[/bold] first."
)
raise typer.Exit()
# Check that the template is up to date.
if frontend and not prerequisites.is_latest_template():
console.print(
"[red]The base app template has updated. Run [bold]pc init[/bold] again."
)
raise typer.Exit()
# Get the app module.
console.rule("[bold]Starting Pynecone App")
app = prerequisites.get_app()
# Check the admin dashboard settings.
prerequisites.check_admin_settings()
# Get the frontend and backend commands, based on the environment.
frontend_cmd, backend_cmd = exec.run_frontend, run_backend_debug
assert frontend_cmd and backend_cmd, "Invalid env"
# Run the frontend and backend.
if frontend:
threading.Thread(
target=frontend_cmd, args=(app.app, Path.cwd(), frontend_port)
).start()
run_backend_debug(app.__name__, backend_host, backend_port, loglevel)
main = cli
if __name__ == "__main__":
main()
This is also an issue w/ the frontend too. If something goes wrong during the bun installs for example, it tends to silently fail and does not propagate any type of error messages up to the user.
reflex run or python -m reflex run should be "debuggable" entry points since the backend runs in-process instead of as a subprocess