exec.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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.utils.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. # validate bun version
  31. prerequisites.validate_and_install_bun(initialize=False)
  32. # Set up the frontend.
  33. setup_frontend(root)
  34. # start watching asset folder
  35. start_watching_assets_folder(root)
  36. # Compile the frontend.
  37. app.compile(force_compile=True)
  38. # Run the frontend in development mode.
  39. console.rule("[bold green]App Running")
  40. os.environ["PORT"] = get_config().port if port is None else port
  41. # Run the frontend in development mode.
  42. subprocess.Popen(
  43. [prerequisites.get_package_manager(), "run", "dev"],
  44. cwd=constants.WEB_DIR,
  45. env=os.environ,
  46. )
  47. def run_frontend_prod(app: App, root: Path, port: str):
  48. """Run the frontend.
  49. Args:
  50. app: The app.
  51. root: root path of the project.
  52. port: port of the app.
  53. """
  54. # Set up the frontend.
  55. setup_frontend(root)
  56. # Export the app.
  57. export_app(app)
  58. # Set the port.
  59. os.environ["PORT"] = get_config().port if port is None else port
  60. # Run the frontend in production mode.
  61. subprocess.Popen(
  62. [prerequisites.get_package_manager(), "run", "prod"],
  63. cwd=constants.WEB_DIR,
  64. env=os.environ,
  65. )
  66. def run_backend(
  67. app_name: str, port: int, loglevel: constants.LogLevel = constants.LogLevel.ERROR
  68. ):
  69. """Run the backend.
  70. Args:
  71. app_name: The app name.
  72. port: The app port
  73. loglevel: The log level.
  74. """
  75. setup_backend()
  76. uvicorn.run(
  77. f"{app_name}:{constants.APP_VAR}.{constants.API_VAR}",
  78. host=constants.BACKEND_HOST,
  79. port=port,
  80. log_level=loglevel,
  81. reload=True,
  82. )
  83. def run_backend_prod(
  84. app_name: str, port: int, loglevel: constants.LogLevel = constants.LogLevel.ERROR
  85. ):
  86. """Run the backend.
  87. Args:
  88. app_name: The app name.
  89. port: The app port
  90. loglevel: The log level.
  91. """
  92. setup_backend()
  93. num_workers = processes.get_num_workers()
  94. command = (
  95. [
  96. *constants.RUN_BACKEND_PROD_WINDOWS,
  97. "--host",
  98. "0.0.0.0",
  99. "--port",
  100. str(port),
  101. f"{app_name}:{constants.APP_VAR}",
  102. ]
  103. if platform.system() == "Windows"
  104. else [
  105. *constants.RUN_BACKEND_PROD,
  106. "--bind",
  107. f"0.0.0.0:{port}",
  108. "--threads",
  109. str(num_workers),
  110. f"{app_name}:{constants.APP_VAR}()",
  111. ]
  112. )
  113. command += [
  114. "--log-level",
  115. loglevel.value,
  116. "--workers",
  117. str(num_workers),
  118. ]
  119. subprocess.run(command)