constants.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. """Constants used throughout the package."""
  2. import os
  3. import re
  4. from enum import Enum
  5. from types import SimpleNamespace
  6. import pkg_resources
  7. # App names and versions.
  8. # The name of the Pynecone module.
  9. MODULE_NAME = "pynecone"
  10. # The name of the pip install package.
  11. PACKAGE_NAME = "pynecone"
  12. # The current version of Pynecone.
  13. VERSION = pkg_resources.get_distribution(PACKAGE_NAME).version
  14. # Minimum version of Node.js required to run Pynecone.
  15. MIN_NODE_VERSION = "12.22.0"
  16. # Files and directories used to init a new project.
  17. # The root directory of the pynecone library.
  18. ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  19. # The name of the file used for pc init.
  20. APP_TEMPLATE_FILE = "tutorial.py"
  21. # The name of the assets directory.
  22. APP_ASSETS_DIR = "assets"
  23. # The template directory used during pc init.
  24. TEMPLATE_DIR = os.path.join(ROOT_DIR, MODULE_NAME, ".templates")
  25. # The web subdirectory of the template directory.
  26. WEB_TEMPLATE_DIR = os.path.join(TEMPLATE_DIR, "web")
  27. # The app subdirectory of the template directory.
  28. APP_TEMPLATE_DIR = os.path.join(TEMPLATE_DIR, "app")
  29. # The assets subdirectory of the template directory.
  30. ASSETS_TEMPLATE_DIR = os.path.join(TEMPLATE_DIR, APP_ASSETS_DIR)
  31. # The frontend directories in a project.
  32. # The web folder where the NextJS app is compiled to.
  33. WEB_DIR = ".web"
  34. # The name of the utils file.
  35. UTILS_DIR = "utils"
  36. # The name of the state file.
  37. STATE_PATH = "/".join([UTILS_DIR, "state"])
  38. # The name of the components file.
  39. COMPONENTS_PATH = "/".join([UTILS_DIR, "components"])
  40. # The directory where the app pages are compiled to.
  41. WEB_PAGES_DIR = os.path.join(WEB_DIR, "pages")
  42. # The directory where the static build is located.
  43. WEB_STATIC_DIR = os.path.join(WEB_DIR, "_static")
  44. # The directory where the utils file is located.
  45. WEB_UTILS_DIR = os.path.join(WEB_DIR, UTILS_DIR)
  46. # The directory where the assets are located.
  47. WEB_ASSETS_DIR = os.path.join(WEB_DIR, "public")
  48. # The node modules directory.
  49. NODE_MODULES = "node_modules"
  50. # The package lock file.
  51. PACKAGE_LOCK = "package-lock.json"
  52. # The pcversion template file.
  53. PCVERSION_TEMPLATE_FILE = os.path.join(WEB_TEMPLATE_DIR, "pynecone.json")
  54. # The pcversion app file.
  55. PCVERSION_APP_FILE = os.path.join(WEB_DIR, "pynecone.json")
  56. # Commands to run the app.
  57. # The frontend default port.
  58. FRONTEND_PORT = "3000"
  59. # The backend api url.
  60. API_URL = "http://localhost:8000"
  61. # The default path where bun is installed.
  62. BUN_PATH = "$HOME/.bun/bin/bun"
  63. # Command to install bun.
  64. INSTALL_BUN = "curl -fsSL https://bun.sh/install | bash -s -- bun-v0.5.5"
  65. # Default host in dev mode.
  66. BACKEND_HOST = "0.0.0.0"
  67. # The default timeout when launching the gunicorn server.
  68. TIMEOUT = 120
  69. # The command to run the backend in production mode.
  70. RUN_BACKEND_PROD = f"gunicorn --worker-class uvicorn.workers.UvicornH11Worker --preload --timeout {TIMEOUT} --log-level critical".split()
  71. # Compiler variables.
  72. # The extension for compiled Javascript files.
  73. JS_EXT = ".js"
  74. # The extension for python files.
  75. PY_EXT = ".py"
  76. # The expected variable name where the pc.App is stored.
  77. APP_VAR = "app"
  78. # The expected variable name where the API object is stored for deployment.
  79. API_VAR = "api"
  80. # The name of the router variable.
  81. ROUTER = "router"
  82. # The name of the socket variable.
  83. SOCKET = "socket"
  84. # The name of the variable to hold API results.
  85. RESULT = "result"
  86. # The name of the process variable.
  87. PROCESSING = "processing"
  88. # The name of the state variable.
  89. STATE = "state"
  90. # The name of the events variable.
  91. EVENTS = "events"
  92. # The name of the initial hydrate event.
  93. HYDRATE = "hydrate"
  94. # The name of the index page.
  95. INDEX_ROUTE = "index"
  96. # The name of the document root page.
  97. DOCUMENT_ROOT = "_document"
  98. # The name of the theme page.
  99. THEME = "theme"
  100. # The prefix used to create setters for state vars.
  101. SETTER_PREFIX = "set_"
  102. # The name of the frontend zip during deployment.
  103. FRONTEND_ZIP = "frontend.zip"
  104. # The name of the backend zip during deployment.
  105. BACKEND_ZIP = "backend.zip"
  106. # The name of the sqlite database.
  107. DB_NAME = "pynecone.db"
  108. # The sqlite url.
  109. DB_URL = f"sqlite:///{DB_NAME}"
  110. # The default title to show for Pynecone apps.
  111. DEFAULT_TITLE = "Pynecone App"
  112. # The default description to show for Pynecone apps.
  113. DEFAULT_DESCRIPTION = "A Pynecone app."
  114. # The default image to show for Pynecone apps.
  115. DEFAULT_IMAGE = "favicon.ico"
  116. # The gitignore file.
  117. GITIGNORE_FILE = ".gitignore"
  118. # Files to gitignore.
  119. DEFAULT_GITIGNORE = {WEB_DIR, DB_NAME}
  120. # The name of the pynecone config module.
  121. CONFIG_MODULE = "pcconfig"
  122. # The python config file.
  123. CONFIG_FILE = f"{CONFIG_MODULE}{PY_EXT}"
  124. # The deployment URL.
  125. PRODUCTION_BACKEND_URL = "https://{username}-{app_name}.api.pynecone.app"
  126. # Token expiration time in seconds.
  127. TOKEN_EXPIRATION = 60 * 60
  128. # Env modes
  129. class Env(str, Enum):
  130. """The environment modes."""
  131. DEV = "dev"
  132. PROD = "prod"
  133. # Log levels
  134. class LogLevel(str, Enum):
  135. """The log levels."""
  136. DEBUG = "debug"
  137. INFO = "info"
  138. WARNING = "warning"
  139. ERROR = "error"
  140. CRITICAL = "critical"
  141. class Endpoint(Enum):
  142. """Endpoints for the pynecone backend API."""
  143. PING = "ping"
  144. EVENT = "event"
  145. def __str__(self) -> str:
  146. """Get the string representation of the endpoint.
  147. Returns:
  148. The path for the endpoint.
  149. """
  150. return f"/{self.value}"
  151. def get_url(self) -> str:
  152. """Get the URL for the endpoint.
  153. Returns:
  154. The full URL for the endpoint.
  155. """
  156. # Import here to avoid circular imports.
  157. from pynecone import utils
  158. # Get the API URL from the config.
  159. config = utils.get_config()
  160. url = "".join([config.api_url, str(self)])
  161. # The event endpoint is a websocket.
  162. if self == Endpoint.EVENT:
  163. # Replace the protocol with ws.
  164. url = url.replace("https://", "wss://").replace("http://", "ws://")
  165. # Return the url.
  166. return url
  167. class SocketEvent(Enum):
  168. """Socket events sent by the pynecone backend API."""
  169. PING = "ping"
  170. EVENT = "event"
  171. def __str__(self) -> str:
  172. """Get the string representation of the event name.
  173. Returns:
  174. The event name string.
  175. """
  176. return str(self.value)
  177. class Transports(Enum):
  178. """Socket transports used by the pynecone backend API."""
  179. POLLING_WEBSOCKET = "['polling', 'websocket']"
  180. WEBSOCKET_POLLING = "['websocket', 'polling']"
  181. WEBSOCKET_ONLY = "['websocket']"
  182. POLLING_ONLY = "['polling']"
  183. def __str__(self) -> str:
  184. """Get the string representation of the transports.
  185. Returns:
  186. The transports string.
  187. """
  188. return str(self.value)
  189. def get_transports(self) -> str:
  190. """Get the transports config for the backend.
  191. Returns:
  192. The transports config for the backend.
  193. """
  194. # Import here to avoid circular imports.
  195. from pynecone import utils
  196. # Get the transports from the config.
  197. config = utils.get_config()
  198. return str(config.backend_transports)
  199. class RouteArgType(SimpleNamespace):
  200. """Type of dynamic route arg extracted from URI route."""
  201. # Typecast to str is needed for Enum to work.
  202. SINGLE = str("arg_single")
  203. LIST = str("arg_list")
  204. class RouteVar(SimpleNamespace):
  205. """Names of variables used in the router_data dict stored in State."""
  206. CLIENT_IP = "ip"
  207. CLIENT_TOKEN = "token"
  208. HEADERS = "headers"
  209. PATH = "pathname"
  210. SESSION_ID = "sid"
  211. QUERY = "query"
  212. class RouteRegex(SimpleNamespace):
  213. """Regex used for extracting route args in route."""
  214. ARG = re.compile(r"\[(?!\.)([^\[\]]+)\]")
  215. # group return the catchall pattern (i.e. "[[..slug]]")
  216. CATCHALL = re.compile(r"(\[?\[\.{3}(?![0-9]).*\]?\])")
  217. # group return the arg name (i.e. "slug")
  218. STRICT_CATCHALL = re.compile(r"\[\.{3}([a-zA-Z_][\w]*)\]")
  219. # group return the arg name (i.e. "slug")
  220. OPT_CATCHALL = re.compile(r"\[\[\.{3}([a-zA-Z_][\w]*)\]\]")
  221. # 404 variables
  222. ROOT_404 = ""
  223. SLUG_404 = "[..._]"
  224. TITLE_404 = "404 - Not Found"
  225. FAVICON_404 = "favicon.ico"
  226. DESCRIPTION_404 = "The page was not found"
  227. # Color mode variables
  228. USE_COLOR_MODE = "useColorMode"
  229. COLOR_MODE = "colorMode"
  230. TOGGLE_COLOR_MODE = "toggleColorMode"
  231. # Server socket configuration variables
  232. CORS_ALLOWED_ORIGINS = "*"
  233. POLLING_MAX_HTTP_BUFFER_SIZE = 1000 * 1000