pc.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. """Pynecone CLI to create, run, and deploy apps."""
  2. import os
  3. import httpx
  4. import typer
  5. from pynecone import constants, utils
  6. # Create the app.
  7. cli = typer.Typer()
  8. @cli.command()
  9. def version():
  10. """Get the Pynecone version."""
  11. utils.console.print(constants.VERSION)
  12. @cli.command()
  13. def init():
  14. """Initialize a new Pynecone app.
  15. Raises:
  16. Exit: If the app directory is invalid.
  17. """
  18. app_name = utils.get_default_app_name()
  19. # Make sure they don't name the app "pynecone".
  20. if app_name == constants.MODULE_NAME:
  21. utils.console.print(
  22. f"[red]The app directory cannot be named [bold]{constants.MODULE_NAME}."
  23. )
  24. raise typer.Exit()
  25. with utils.console.status(f"[bold]Initializing {app_name}"):
  26. # Set up the web directory.
  27. utils.install_bun()
  28. utils.initialize_web_directory()
  29. # Set up the app directory, only if the config doesn't exist.
  30. if not os.path.exists(constants.CONFIG_FILE):
  31. utils.create_config(app_name)
  32. utils.initialize_app_directory(app_name)
  33. # Finish initializing the app.
  34. utils.console.log(f"[bold green]Finished Initializing: {app_name}")
  35. @cli.command()
  36. def run(
  37. env: constants.Env = constants.Env.DEV,
  38. frontend: bool = True,
  39. backend: bool = True,
  40. ):
  41. """Run the app.
  42. Args:
  43. env: The environment to run the app in.
  44. frontend: Whether to run the frontend.
  45. backend: Whether to run the backend.
  46. Raises:
  47. Exit: If the app is not initialized.
  48. """
  49. # Check that the app is initialized.
  50. if not utils.is_initialized():
  51. utils.console.print(
  52. "[red]The app is not initialized. Run [bold]pc init[/bold] first."
  53. )
  54. raise typer.Exit()
  55. # Get the app module.
  56. utils.console.rule("[bold]Starting Pynecone App")
  57. app = utils.get_app()
  58. # Get the frontend and backend commands, based on the environment.
  59. frontend_cmd = backend_cmd = None
  60. if env == constants.Env.DEV:
  61. frontend_cmd, backend_cmd = utils.run_frontend, utils.run_backend
  62. if env == constants.Env.PROD:
  63. frontend_cmd, backend_cmd = utils.run_frontend_prod, utils.run_backend_prod
  64. assert frontend_cmd and backend_cmd, "Invalid env"
  65. # Run the frontend and backend.
  66. if frontend:
  67. frontend_cmd(app.app)
  68. if backend:
  69. backend_cmd(app.__name__)
  70. @cli.command()
  71. def deploy(dry_run: bool = False):
  72. """Deploy the app to the hosting service.
  73. Args:
  74. dry_run: Whether to run a dry run.
  75. """
  76. # Get the app config.
  77. config = utils.get_config()
  78. config.api_url = utils.get_production_backend_url()
  79. # Check if the deploy url is set.
  80. if config.deploy_url is None:
  81. typer.echo("This feature is coming soon!")
  82. return
  83. # Compile the app in production mode.
  84. typer.echo("Compiling production app")
  85. app = utils.get_app().app
  86. utils.export_app(app, zip=True)
  87. # Exit early if this is a dry run.
  88. if dry_run:
  89. return
  90. # Deploy the app.
  91. data = {"userId": config.username, "projectId": config.app_name}
  92. original_response = httpx.get(config.deploy_url, params=data)
  93. response = original_response.json()
  94. print("response", response)
  95. frontend = response["frontend_resources_url"]
  96. backend = response["backend_resources_url"]
  97. # Upload the frontend and backend.
  98. with open(constants.FRONTEND_ZIP, "rb") as f:
  99. response = httpx.put(frontend, data=f) # type: ignore
  100. with open(constants.BACKEND_ZIP, "rb") as f:
  101. response = httpx.put(backend, data=f) # type: ignore
  102. main = cli
  103. if __name__ == "__main__":
  104. main()