From ea28f336da8e8645d9f983cf9c6a58cd31d4dea7 Mon Sep 17 00:00:00 2001 From: Francesco Ambrosini <45211144+HellAmbro@users.noreply.github.com> Date: Wed, 1 Feb 2023 06:21:44 +0100 Subject: [PATCH] Allow the user to change ports (#417) * Allow the user to change the app port at runtime * Allow the user to change the app port (backend and frontend) at runtime --- pynecone/pc.py | 10 +++++----- pynecone/utils.py | 35 +++++++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/pynecone/pc.py b/pynecone/pc.py index 58d6268a2..fa42ff652 100644 --- a/pynecone/pc.py +++ b/pynecone/pc.py @@ -65,12 +65,12 @@ def run( frontend_port = utils.get_config().port if port is None else port backend_port = utils.get_api_port() - # If something is running on the ports, ask the user if they want to kill it. + # If something is running on the ports, ask the user if they want to kill or change it. if utils.is_process_on_port(frontend_port): - utils.terminate_port(frontend_port, "frontend") + frontend_port = utils.change_or_terminate_port(frontend_port, "frontend") if utils.is_process_on_port(backend_port): - utils.terminate_port(backend_port, "backend") + backend_port = utils.change_or_terminate_port(backend_port, "backend") # Check that the app is initialized. if frontend and not utils.is_initialized(): @@ -101,9 +101,9 @@ def run( # Run the frontend and backend. try: if frontend: - frontend_cmd(app.app, Path.cwd(), port) + frontend_cmd(app.app, Path.cwd(), frontend_port) if backend: - backend_cmd(app.__name__, loglevel=loglevel) + backend_cmd(app.__name__, port=int(backend_port), loglevel=loglevel) finally: utils.kill_process_on_port(frontend_port) utils.kill_process_on_port(backend_port) diff --git a/pynecone/utils.py b/pynecone/utils.py index 7682845f6..7c4d61f3d 100644 --- a/pynecone/utils.py +++ b/pynecone/utils.py @@ -639,53 +639,72 @@ def kill_process_on_port(port): get_process_on_port(port).kill() # type: ignore -def terminate_port(port, _type): - """Terminate the port. +def change_or_terminate_port(port, _type) -> str: + """Terminate or change the port. Args: port: The port. _type: The type of the port. + + Returns: + The new port or the current one. """ console.print( f"Something is already running on port [bold underline]{port}[/bold underline]. This is the port the {_type} runs on." ) - frontend_action = Prompt.ask("Kill it?", choices=["y", "n"]) - if frontend_action == "y": + frontend_action = Prompt.ask("Kill or change it?", choices=["k", "c", "n"]) + if frontend_action == "k": kill_process_on_port(port) + return port + elif frontend_action == "c": + new_port = Prompt.ask("Specify the new port") + + # Check if also the new port is used + if is_process_on_port(new_port): + return change_or_terminate_port(new_port, _type) + else: + console.print( + f"The {_type} will run on port [bold underline]{new_port}[/bold underline]." + ) + return new_port else: console.print("Exiting...") sys.exit() -def run_backend(app_name: str, loglevel: constants.LogLevel = constants.LogLevel.ERROR): +def run_backend( + app_name: str, port: int, loglevel: constants.LogLevel = constants.LogLevel.ERROR +): """Run the backend. Args: app_name: The app name. + port: The app port loglevel: The log level. """ uvicorn.run( f"{app_name}:{constants.APP_VAR}.{constants.API_VAR}", host=constants.BACKEND_HOST, - port=get_api_port(), + port=port, log_level=loglevel, reload=True, ) def run_backend_prod( - app_name: str, loglevel: constants.LogLevel = constants.LogLevel.ERROR + app_name: str, port: int, loglevel: constants.LogLevel = constants.LogLevel.ERROR ): """Run the backend. Args: app_name: The app name. + port: The app port loglevel: The log level. """ num_workers = get_num_workers() command = constants.RUN_BACKEND_PROD + [ "--bind", - f"0.0.0.0:{get_api_port()}", + f"0.0.0.0:{port}", "--workers", str(num_workers), "--threads",