exec.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. """Everything regarding execution of the built app."""
  2. from __future__ import annotations
  3. import os
  4. import platform
  5. import subprocess
  6. from pathlib import Path
  7. from typing import TYPE_CHECKING
  8. import uvicorn
  9. from pynecone import constants
  10. from pynecone.config import get_config
  11. from pynecone.utils import console, prerequisites, processes
  12. from pynecone.utils.build import export_app, setup_backend, setup_frontend
  13. from pynecone.watch import AssetFolderWatch
  14. if TYPE_CHECKING:
  15. from pynecone.app import App
  16. def start_watching_assets_folder(root):
  17. """Start watching assets folder.
  18. Args:
  19. root: root path of the project.
  20. """
  21. asset_watch = AssetFolderWatch(root)
  22. asset_watch.start()
  23. def run_frontend(app: App, root: Path, port: str):
  24. """Run the frontend.
  25. Args:
  26. app: The app.
  27. root: root path of the project.
  28. port: port of the app.
  29. """
  30. # Initialize the web directory if it doesn't exist.
  31. web_dir = prerequisites.create_web_directory(root)
  32. # Install frontend packages
  33. prerequisites.install_frontend_packages(web_dir)
  34. # Set up the frontend.
  35. setup_frontend(root)
  36. # start watching asset folder
  37. start_watching_assets_folder(root)
  38. # Compile the frontend.
  39. app.compile(force_compile=True)
  40. # Run the frontend in development mode.
  41. console.rule("[bold green]App Running")
  42. os.environ["PORT"] = get_config().port if port is None else port
  43. subprocess.Popen(
  44. [prerequisites.get_package_manager(), "run", "next", "telemetry", "disable"],
  45. cwd=constants.WEB_DIR,
  46. env=os.environ,
  47. stdout=subprocess.DEVNULL,
  48. stderr=subprocess.STDOUT,
  49. )
  50. subprocess.Popen(
  51. [prerequisites.get_package_manager(), "run", "dev"],
  52. cwd=constants.WEB_DIR,
  53. env=os.environ,
  54. )
  55. def run_frontend_prod(app: App, root: Path, port: str):
  56. """Run the frontend.
  57. Args:
  58. app: The app.
  59. root: root path of the project.
  60. port: port of the app.
  61. """
  62. # Set up the frontend.
  63. setup_frontend(root)
  64. # Export the app.
  65. export_app(app)
  66. os.environ["PORT"] = get_config().port if port is None else port
  67. # Run the frontend in production mode.
  68. subprocess.Popen(
  69. [prerequisites.get_package_manager(), "run", "prod"],
  70. cwd=constants.WEB_DIR,
  71. env=os.environ,
  72. )
  73. def run_backend(
  74. app_name: str, port: int, loglevel: constants.LogLevel = constants.LogLevel.ERROR
  75. ):
  76. """Run the backend.
  77. Args:
  78. app_name: The app name.
  79. port: The app port
  80. loglevel: The log level.
  81. """
  82. setup_backend()
  83. uvicorn.run(
  84. f"{app_name}:{constants.APP_VAR}.{constants.API_VAR}",
  85. host=constants.BACKEND_HOST,
  86. port=port,
  87. log_level=loglevel,
  88. reload=True,
  89. )
  90. def run_backend_prod(
  91. app_name: str, port: int, loglevel: constants.LogLevel = constants.LogLevel.ERROR
  92. ):
  93. """Run the backend.
  94. Args:
  95. app_name: The app name.
  96. port: The app port
  97. loglevel: The log level.
  98. """
  99. setup_backend()
  100. num_workers = processes.get_num_workers()
  101. command = (
  102. [
  103. *constants.RUN_BACKEND_PROD_WINDOWS,
  104. "--host",
  105. "0.0.0.0",
  106. "--port",
  107. str(port),
  108. f"{app_name}:{constants.APP_VAR}",
  109. ]
  110. if platform.system() == "Windows"
  111. else [
  112. *constants.RUN_BACKEND_PROD,
  113. "--bind",
  114. f"0.0.0.0:{port}",
  115. "--threads",
  116. str(num_workers),
  117. f"{app_name}:{constants.APP_VAR}()",
  118. ]
  119. )
  120. command += [
  121. "--log-level",
  122. loglevel.value,
  123. "--workers",
  124. str(num_workers),
  125. ]
  126. subprocess.run(command)