pc.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. utils.console.rule("[bold]Starting Pynecone App")
  56. app = utils.get_app()
  57. frontend_cmd = backend_cmd = None
  58. if env == constants.Env.DEV:
  59. frontend_cmd, backend_cmd = utils.run_frontend, utils.run_backend
  60. if env == constants.Env.PROD:
  61. frontend_cmd, backend_cmd = utils.run_frontend_prod, utils.run_backend_prod
  62. assert frontend_cmd and backend_cmd, "Invalid env"
  63. if frontend:
  64. frontend_cmd(app)
  65. if backend:
  66. backend_cmd(app)
  67. @cli.command()
  68. def deploy(dry_run: bool = False):
  69. """Deploy the app to the hosting service.
  70. Args:
  71. dry_run: Whether to run a dry run.
  72. """
  73. # Get the app config.
  74. config = utils.get_config()
  75. config.api_url = utils.get_production_backend_url()
  76. # Check if the deploy url is set.
  77. if config.deploy_url is None:
  78. typer.echo("This feature is coming soon!")
  79. return
  80. # Compile the app in production mode.
  81. typer.echo("Compiling production app")
  82. app = utils.get_app()
  83. utils.export_app(app)
  84. # Exit early if this is a dry run.
  85. if dry_run:
  86. return
  87. # Deploy the app.
  88. data = {"userId": config.username, "projectId": config.app_name}
  89. original_response = httpx.get(config.deploy_url, params=data)
  90. response = original_response.json()
  91. print("response", response)
  92. frontend = response["frontend_resources_url"]
  93. backend = response["backend_resources_url"]
  94. # Upload the frontend and backend.
  95. with open(constants.FRONTEND_ZIP, "rb") as f:
  96. response = httpx.put(frontend, data=f) # type: ignore
  97. with open(constants.BACKEND_ZIP, "rb") as f:
  98. response = httpx.put(backend, data=f) # type: ignore
  99. main = cli
  100. if __name__ == "__main__":
  101. main()