Bläddra i källkod

Support prod run on windows (#99)

Nikhil Rao 2 år sedan
förälder
incheckning
2c3ef6e23f
5 ändrade filer med 60 tillägg och 50 borttagningar
  1. 1 1
      README.md
  2. 2 2
      pynecone/components/layout/html.py
  3. 2 0
      pynecone/constants.py
  4. 7 4
      pynecone/pc.py
  5. 48 43
      pynecone/utils.py

+ 1 - 1
README.md

@@ -220,7 +220,7 @@ We are actively looking for contributors, no matter your skill level or experien
 ## More Information 
 ## More Information 
 
 
 More information about Pynecone can be found on our website:
 More information about Pynecone can be found on our website:
-- [Pynecone.io](https://pynecone.io)
+- [pynecone.io](https://pynecone.io)
 
 
 ## License
 ## License
 
 

+ 2 - 2
pynecone/components/layout/html.py

@@ -1,8 +1,9 @@
 """A html component."""
 """A html component."""
 
 
+from typing import Dict
+
 from pynecone.components.layout.box import Box
 from pynecone.components.layout.box import Box
 from pynecone.var import Var
 from pynecone.var import Var
-from typing import Dict
 
 
 
 
 class Html(Box):
 class Html(Box):
@@ -33,7 +34,6 @@ class Html(Box):
         if len(children) != 1:
         if len(children) != 1:
             raise ValueError("Must provide children to the html component.")
             raise ValueError("Must provide children to the html component.")
         else:
         else:
-
             props["dangerouslySetInnerHTML"] = {"__html": children[0]}
             props["dangerouslySetInnerHTML"] = {"__html": children[0]}
 
 
         # Create the component.
         # Create the component.

+ 2 - 0
pynecone/constants.py

@@ -38,6 +38,8 @@ UTILS_DIR = "utils"
 STATE_PATH = os.path.join(UTILS_DIR, "state")
 STATE_PATH = os.path.join(UTILS_DIR, "state")
 # The directory where the app pages are compiled to.
 # The directory where the app pages are compiled to.
 WEB_PAGES_DIR = os.path.join(WEB_DIR, "pages")
 WEB_PAGES_DIR = os.path.join(WEB_DIR, "pages")
+# The directory where the static build is located.
+WEB_STATIC_DIR = os.path.join(WEB_DIR, "_static")
 # The directory where the utils file is located.
 # The directory where the utils file is located.
 WEB_UTILS_DIR = os.path.join(WEB_DIR, UTILS_DIR)
 WEB_UTILS_DIR = os.path.join(WEB_DIR, UTILS_DIR)
 # The directory where the assets are located.
 # The directory where the assets are located.

+ 7 - 4
pynecone/pc.py

@@ -70,9 +70,11 @@ def run(
         )
         )
         raise typer.Exit()
         raise typer.Exit()
 
 
+    # Get the app module.
     utils.console.rule("[bold]Starting Pynecone App")
     utils.console.rule("[bold]Starting Pynecone App")
     app = utils.get_app()
     app = utils.get_app()
 
 
+    # Get the frontend and backend commands, based on the environment.
     frontend_cmd = backend_cmd = None
     frontend_cmd = backend_cmd = None
     if env == constants.Env.DEV:
     if env == constants.Env.DEV:
         frontend_cmd, backend_cmd = utils.run_frontend, utils.run_backend
         frontend_cmd, backend_cmd = utils.run_frontend, utils.run_backend
@@ -80,10 +82,11 @@ def run(
         frontend_cmd, backend_cmd = utils.run_frontend_prod, utils.run_backend_prod
         frontend_cmd, backend_cmd = utils.run_frontend_prod, utils.run_backend_prod
     assert frontend_cmd and backend_cmd, "Invalid env"
     assert frontend_cmd and backend_cmd, "Invalid env"
 
 
+    # Run the frontend and backend.
     if frontend:
     if frontend:
-        frontend_cmd(app)
+        frontend_cmd(app.app)
     if backend:
     if backend:
-        backend_cmd(app)
+        backend_cmd(app.__name__)
 
 
 
 
 @cli.command()
 @cli.command()
@@ -104,8 +107,8 @@ def deploy(dry_run: bool = False):
 
 
     # Compile the app in production mode.
     # Compile the app in production mode.
     typer.echo("Compiling production app")
     typer.echo("Compiling production app")
-    app = utils.get_app()
-    utils.export_app(app)
+    app = utils.get_app().app
+    utils.export_app(app, zip=True)
 
 
     # Exit early if this is a dry run.
     # Exit early if this is a dry run.
     if dry_run:
     if dry_run:

+ 48 - 43
pynecone/utils.py

@@ -15,6 +15,7 @@ import subprocess
 import sys
 import sys
 from collections import defaultdict
 from collections import defaultdict
 from subprocess import PIPE
 from subprocess import PIPE
+from types import ModuleType
 from typing import _GenericAlias  # type: ignore
 from typing import _GenericAlias  # type: ignore
 from typing import (
 from typing import (
     TYPE_CHECKING,
     TYPE_CHECKING,
@@ -37,6 +38,7 @@ from pynecone import constants
 from pynecone.base import Base
 from pynecone.base import Base
 
 
 if TYPE_CHECKING:
 if TYPE_CHECKING:
+    from pynecone.app import App
     from pynecone.components.component import ImportDict
     from pynecone.components.component import ImportDict
     from pynecone.config import Config
     from pynecone.config import Config
     from pynecone.event import Event, EventHandler, EventSpec
     from pynecone.event import Event, EventHandler, EventSpec
@@ -308,8 +310,8 @@ def get_bun_path() -> str:
     return os.path.expandvars(get_config().bun_path)
     return os.path.expandvars(get_config().bun_path)
 
 
 
 
-def get_app() -> Any:
-    """Get the app based on the default config.
+def get_app() -> ModuleType:
+    """Get the app module based on the default config.
 
 
     Returns:
     Returns:
         The app based on the default config.
         The app based on the default config.
@@ -372,11 +374,11 @@ def install_bun():
 def install_frontend_packages():
 def install_frontend_packages():
     """Install the frontend packages."""
     """Install the frontend packages."""
     # Install the base packages.
     # Install the base packages.
-    subprocess.call([get_bun_path(), "install"], cwd=constants.WEB_DIR, stdout=PIPE)
+    subprocess.run([get_bun_path(), "install"], cwd=constants.WEB_DIR, stdout=PIPE)
 
 
     # Install the app packages.
     # Install the app packages.
     packages = get_config().frontend_packages
     packages = get_config().frontend_packages
-    subprocess.call(
+    subprocess.run(
         [get_bun_path(), "add", *packages], cwd=constants.WEB_DIR, stdout=PIPE
         [get_bun_path(), "add", *packages], cwd=constants.WEB_DIR, stdout=PIPE
     )
     )
 
 
@@ -390,23 +392,30 @@ def is_initialized() -> bool:
     return os.path.exists(constants.CONFIG_FILE) and os.path.exists(constants.WEB_DIR)
     return os.path.exists(constants.CONFIG_FILE) and os.path.exists(constants.WEB_DIR)
 
 
 
 
-def export_app(app):
+def export_app(app: App, zip: bool = False):
     """Zip up the app for deployment.
     """Zip up the app for deployment.
 
 
     Args:
     Args:
         app: The app.
         app: The app.
+        zip: Whether to zip the app.
     """
     """
-    app.app.compile(force_compile=True)
-    cmd = r"rm -rf .web/_static; cd .web && bun run export && cd _static  && zip -r ../../frontend.zip ./* && cd ../.. && zip -r backend.zip ./* -x .web/\* ./assets\* ./frontend.zip\* ./backend.zip\*"
-    os.system(cmd)
+    # Force compile the app.
+    app.compile(force_compile=True)
 
 
+    # Remove the static folder.
+    rm(constants.WEB_STATIC_DIR)
 
 
-def setup_frontend(app):
-    """Set up the frontend.
+    # Export the Next app.
+    subprocess.run([get_bun_path(), "run", "export"], cwd=constants.WEB_DIR)
 
 
-    Args:
-        app: The app.
-    """
+    # Zip up the app.
+    if zip:
+        cmd = r"cd .web/_static && zip -r ../../frontend.zip ./* && cd ../.. && zip -r backend.zip ./* -x .web/\* ./assets\* ./frontend.zip\* ./backend.zip\*"
+        os.system(cmd)
+
+
+def setup_frontend():
+    """Set up the frontend."""
     # Initialize the web directory if it doesn't exist.
     # Initialize the web directory if it doesn't exist.
     cp(constants.WEB_TEMPLATE_DIR, constants.WEB_DIR, overwrite=False)
     cp(constants.WEB_TEMPLATE_DIR, constants.WEB_DIR, overwrite=False)
 
 
@@ -417,42 +426,38 @@ def setup_frontend(app):
     # Link the assets folder.
     # Link the assets folder.
     ln(src=os.path.join("..", constants.APP_ASSETS_DIR), dest=constants.WEB_ASSETS_DIR)
     ln(src=os.path.join("..", constants.APP_ASSETS_DIR), dest=constants.WEB_ASSETS_DIR)
 
 
-    # Compile the frontend.
-    app.app.compile(force_compile=True)
-
 
 
-def run_frontend(app) -> subprocess.Popen:
+def run_frontend(app: App):
     """Run the frontend.
     """Run the frontend.
 
 
     Args:
     Args:
         app: The app.
         app: The app.
-
-    Returns:
-        The frontend process.
     """
     """
-    setup_frontend(app)
-    command = [get_bun_path(), "run", "dev"]
+    # Set up the frontend.
+    setup_frontend()
+
+    # Compile the frontend.
+    app.compile(force_compile=True)
+
+    # Run the frontend in development mode.
     console.rule("[bold green]App Running")
     console.rule("[bold green]App Running")
-    return subprocess.Popen(
-        command, cwd=constants.WEB_DIR
-    )  # stdout=PIPE to hide output
+    subprocess.Popen([get_bun_path(), "run", "dev"], cwd=constants.WEB_DIR)
 
 
 
 
-def run_frontend_prod(app) -> subprocess.Popen:
+def run_frontend_prod(app: App):
     """Run the frontend.
     """Run the frontend.
 
 
     Args:
     Args:
         app: The app.
         app: The app.
-
-    Returns:
-        The frontend process.
     """
     """
-    setup_frontend(app)
-    # Export and zip up the frontend and backend then  start the frontend in production mode.
-    cmd = r"rm -rf .web/_static || true; cd .web && bun run export"
-    os.system(cmd)
-    command = [get_bun_path(), "run", "prod"]
-    return subprocess.Popen(command, cwd=constants.WEB_DIR)
+    # Set up the frontend.
+    setup_frontend()
+
+    # Export the app.
+    export_app(app)
+
+    # Run the frontend in production mode.
+    subprocess.Popen([get_bun_path(), "run", "prod"], cwd=constants.WEB_DIR)
 
 
 
 
 def get_num_workers() -> int:
 def get_num_workers() -> int:
@@ -469,23 +474,23 @@ def get_num_workers() -> int:
     return (os.cpu_count() or 1) * 2 + 1
     return (os.cpu_count() or 1) * 2 + 1
 
 
 
 
-def run_backend(app):
+def run_backend(app_name: str):
     """Run the backend.
     """Run the backend.
 
 
     Args:
     Args:
-        app: The app.
+        app_name: The app name.
     """
     """
     command = constants.RUN_BACKEND + [
     command = constants.RUN_BACKEND + [
-        f"{app.__name__}:{constants.APP_VAR}.{constants.API_VAR}"
+        f"{app_name}:{constants.APP_VAR}.{constants.API_VAR}"
     ]
     ]
-    subprocess.call(command)
+    subprocess.run(command)
 
 
 
 
-def run_backend_prod(app) -> None:
+def run_backend_prod(app_name: str):
     """Run the backend.
     """Run the backend.
 
 
     Args:
     Args:
-        app: The app.
+        app_name: The app name.
     """
     """
     num_workers = get_num_workers()
     num_workers = get_num_workers()
     command = constants.RUN_BACKEND_PROD + [
     command = constants.RUN_BACKEND_PROD + [
@@ -493,9 +498,9 @@ def run_backend_prod(app) -> None:
         str(num_workers),
         str(num_workers),
         "--threads",
         "--threads",
         str(num_workers),
         str(num_workers),
-        f"{app.__name__}:{constants.APP_VAR}()",
+        f"{app_name}:{constants.APP_VAR}()",
     ]
     ]
-    subprocess.call(command)
+    subprocess.run(command)
 
 
 
 
 def get_production_backend_url() -> str:
 def get_production_backend_url() -> str: