From 1dfe76c4a3996edf3d4b7f00b6e0cc978e9942c4 Mon Sep 17 00:00:00 2001 From: Sergei Ozeranskii Date: Tue, 27 Jun 2023 05:50:23 +0800 Subject: [PATCH] Unify the launch of child processes (#1250) --- reflex/utils/build.py | 11 +++-------- reflex/utils/exec.py | 9 +++------ reflex/utils/processes.py | 25 +++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/reflex/utils/build.py b/reflex/utils/build.py index 2f55f04a9..35947f450 100644 --- a/reflex/utils/build.py +++ b/reflex/utils/build.py @@ -14,6 +14,7 @@ from rich.progress import Progress from reflex import constants from reflex.config import get_config from reflex.utils import path_ops, prerequisites +from reflex.utils.processes import new_process def update_json_file(file_path: str, update_dict: dict[str, Union[int, str]]): @@ -115,13 +116,9 @@ def export_app( task = progress.add_task("Building app... ", total=500) # Start the subprocess with the progress bar. - with progress, subprocess.Popen( + with progress, new_process( [prerequisites.get_package_manager(), "run", "export"], cwd=constants.WEB_DIR, - env=os.environ, - stderr=subprocess.STDOUT, - stdout=subprocess.PIPE, # Redirect stdout to a pipe - universal_newlines=True, # Set universal_newlines to True for text mode ) as export_process: assert export_process.stdout is not None, "No stdout for export process." for line in export_process.stdout: @@ -216,7 +213,7 @@ def setup_frontend( # Disable the Next telemetry. if disable_telemetry: - subprocess.Popen( + new_process( [ prerequisites.get_package_manager(), "run", @@ -225,9 +222,7 @@ def setup_frontend( "disable", ], cwd=constants.WEB_DIR, - env=os.environ, stdout=subprocess.DEVNULL, - stderr=subprocess.STDOUT, ) diff --git a/reflex/utils/exec.py b/reflex/utils/exec.py index df31f4a77..651d50f33 100644 --- a/reflex/utils/exec.py +++ b/reflex/utils/exec.py @@ -13,6 +13,7 @@ from rich import print from reflex import constants from reflex.config import get_config from reflex.utils import console, prerequisites, processes +from reflex.utils.processes import new_process from reflex.utils.watch import AssetFolderWatch @@ -36,13 +37,9 @@ def run_process_and_launch_url( run_command: The command to run. loglevel: The log level to use. """ - process = subprocess.Popen( + process = new_process( run_command, cwd=constants.WEB_DIR, - env=os.environ, - stderr=subprocess.STDOUT, - stdout=None if platform.system() == "Windows" else subprocess.PIPE, - universal_newlines=None if platform.system() == "Windows" else True, ) current_time = datetime.now() @@ -134,7 +131,7 @@ def run_backend( loglevel, "--reload", ] - process = subprocess.Popen(cmd) + process = new_process(cmd) try: process.wait() diff --git a/reflex/utils/processes.py b/reflex/utils/processes.py index fe7bac3db..7b494b3be 100644 --- a/reflex/utils/processes.py +++ b/reflex/utils/processes.py @@ -5,6 +5,7 @@ from __future__ import annotations import contextlib import os import signal +import subprocess import sys from typing import Optional from urllib.parse import urlparse @@ -120,3 +121,27 @@ def change_or_terminate_port(port, _type) -> str: else: console.print("Exiting...") sys.exit() + + +def new_process(args, **kwargs): + """Wrapper over subprocess.Popen to unify the launch of child processes. + + Args: + args: A string, or a sequence of program arguments. + **kwargs: Kwargs to override default wrap values to pass to subprocess.Popen as arguments. + + Returns: + Execute a child program in a new process. + """ + kwargs = { + "env": os.environ, + "stderr": subprocess.STDOUT, + "stdout": subprocess.PIPE, # Redirect stdout to a pipe + "universal_newlines": True, # Set universal_newlines to True for text mode + "encoding": "UTF-8", + **kwargs, + } + return subprocess.Popen( + args, + **kwargs, + )