exec.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. """Everything regarding execution of the built app."""
  2. from __future__ import annotations
  3. import os
  4. from pathlib import Path
  5. from reflex import constants
  6. from reflex.config import get_config
  7. from reflex.utils import console, prerequisites, processes
  8. from reflex.utils.watch import AssetFolderWatch
  9. def start_watching_assets_folder(root):
  10. """Start watching assets folder.
  11. Args:
  12. root: root path of the project.
  13. """
  14. asset_watch = AssetFolderWatch(root)
  15. asset_watch.start()
  16. def run_process_and_launch_url(
  17. run_command: list[str],
  18. ):
  19. """Run the process and launch the URL.
  20. Args:
  21. run_command: The command to run.
  22. """
  23. process = processes.new_process(
  24. run_command, cwd=constants.WEB_DIR, shell=constants.IS_WINDOWS
  25. )
  26. if process.stdout:
  27. for line in process.stdout:
  28. if "ready started server on" in line:
  29. url = line.split("url: ")[-1].strip()
  30. console.print(f"App running at: [bold green]{url}")
  31. else:
  32. console.debug(line)
  33. def run_frontend(
  34. root: Path,
  35. port: str,
  36. ):
  37. """Run the frontend.
  38. Args:
  39. root: The root path of the project.
  40. port: The port to run the frontend on.
  41. """
  42. # Start watching asset folder.
  43. start_watching_assets_folder(root)
  44. # Run the frontend in development mode.
  45. console.rule("[bold green]App Running")
  46. os.environ["PORT"] = get_config().frontend_port if port is None else port
  47. run_process_and_launch_url([prerequisites.get_package_manager(), "run", "dev"])
  48. def run_frontend_prod(
  49. root: Path,
  50. port: str,
  51. ):
  52. """Run the frontend.
  53. Args:
  54. root: The root path of the project (to keep same API as run_frontend).
  55. port: The port to run the frontend on.
  56. """
  57. # Set the port.
  58. os.environ["PORT"] = get_config().frontend_port if port is None else port
  59. # Run the frontend in production mode.
  60. console.rule("[bold green]App Running")
  61. run_process_and_launch_url([prerequisites.get_package_manager(), "run", "prod"])
  62. def run_backend(
  63. app_name: str,
  64. host: str,
  65. port: int,
  66. loglevel: constants.LogLevel = constants.LogLevel.ERROR,
  67. ):
  68. """Run the backend.
  69. Args:
  70. host: The app host
  71. app_name: The app name.
  72. port: The app port
  73. loglevel: The log level.
  74. """
  75. processes.new_process(
  76. [
  77. "uvicorn",
  78. f"{app_name}:{constants.APP_VAR}.{constants.API_VAR}",
  79. "--host",
  80. host,
  81. "--port",
  82. str(port),
  83. "--log-level",
  84. loglevel.value,
  85. "--reload",
  86. "--reload-dir",
  87. app_name.split(".")[0],
  88. ],
  89. run=True,
  90. show_logs=True,
  91. )
  92. def run_backend_prod(
  93. app_name: str,
  94. host: str,
  95. port: int,
  96. loglevel: constants.LogLevel = constants.LogLevel.ERROR,
  97. ):
  98. """Run the backend.
  99. Args:
  100. host: The app host
  101. app_name: The app name.
  102. port: The app port
  103. loglevel: The log level.
  104. """
  105. num_workers = processes.get_num_workers()
  106. command = (
  107. [
  108. *constants.RUN_BACKEND_PROD_WINDOWS,
  109. "--host",
  110. host,
  111. "--port",
  112. str(port),
  113. f"{app_name}:{constants.APP_VAR}",
  114. ]
  115. if constants.IS_WINDOWS
  116. else [
  117. *constants.RUN_BACKEND_PROD,
  118. "--bind",
  119. f"{host}:{port}",
  120. "--threads",
  121. str(num_workers),
  122. f"{app_name}:{constants.APP_VAR}()",
  123. ]
  124. )
  125. command += [
  126. "--log-level",
  127. loglevel.value,
  128. "--workers",
  129. str(num_workers),
  130. ]
  131. processes.new_process(command, run=True, show_logs=True)