config.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. """The Pynecone config."""
  2. from __future__ import annotations
  3. import os
  4. import sys
  5. import urllib.parse
  6. from typing import List, Optional
  7. from pynecone import constants
  8. from pynecone.base import Base
  9. class DBConfig(Base):
  10. """Database config."""
  11. engine: str
  12. username: Optional[str] = ""
  13. password: Optional[str] = ""
  14. host: Optional[str] = ""
  15. port: Optional[int] = None
  16. database: str
  17. @classmethod
  18. def postgresql(
  19. cls,
  20. database: str,
  21. username: str,
  22. password: Optional[str] = None,
  23. host: Optional[str] = None,
  24. port: Optional[int] = 5432,
  25. ) -> DBConfig:
  26. """Create an instance with postgresql engine.
  27. Args:
  28. database: Database name.
  29. username: Database username.
  30. password: Database password.
  31. host: Database host.
  32. port: Database port.
  33. Returns:
  34. DBConfig instance.
  35. """
  36. return cls(
  37. engine="postgresql",
  38. username=username,
  39. password=password,
  40. host=host,
  41. port=port,
  42. database=database,
  43. )
  44. @classmethod
  45. def postgresql_psycopg2(
  46. cls,
  47. database: str,
  48. username: str,
  49. password: Optional[str] = None,
  50. host: Optional[str] = None,
  51. port: Optional[int] = 5432,
  52. ) -> DBConfig:
  53. """Create an instance with postgresql+psycopg2 engine.
  54. Args:
  55. database: Database name.
  56. username: Database username.
  57. password: Database password.
  58. host: Database host.
  59. port: Database port.
  60. Returns:
  61. DBConfig instance.
  62. """
  63. return cls(
  64. engine="postgresql+psycopg2",
  65. username=username,
  66. password=password,
  67. host=host,
  68. port=port,
  69. database=database,
  70. )
  71. @classmethod
  72. def sqlite(
  73. cls,
  74. database: str,
  75. ) -> DBConfig:
  76. """Create an instance with sqlite engine.
  77. Args:
  78. database: Database name.
  79. Returns:
  80. DBConfig instance.
  81. """
  82. return cls(
  83. engine="sqlite",
  84. database=database,
  85. )
  86. def get_url(self) -> str:
  87. """Get database URL.
  88. Returns:
  89. The database URL.
  90. """
  91. host = (
  92. f"{self.host}:{self.port}" if self.host and self.port else self.host or ""
  93. )
  94. username = urllib.parse.quote_plus(self.username) if self.username else ""
  95. password = urllib.parse.quote_plus(self.password) if self.password else ""
  96. if username:
  97. path = f"{username}:{password}@{host}" if password else f"{username}@{host}"
  98. else:
  99. path = f"{host}"
  100. return f"{self.engine}://{path}/{self.database}"
  101. class Config(Base):
  102. """A Pynecone config."""
  103. # The name of the app.
  104. app_name: str
  105. # The username.
  106. username: Optional[str] = None
  107. # The frontend port.
  108. port: str = constants.FRONTEND_PORT
  109. # The frontend port.
  110. backend_port: str = constants.BACKEND_PORT
  111. # The backend host.
  112. backend_host: str = constants.BACKEND_HOST
  113. # The backend API url.
  114. api_url: str = constants.API_URL
  115. # The deploy url.
  116. deploy_url: Optional[str] = None
  117. # The database url.
  118. db_url: Optional[str] = constants.DB_URL
  119. # The database config.
  120. db_config: Optional[DBConfig] = None
  121. # The redis url.
  122. redis_url: Optional[str] = None
  123. # Telemetry opt-in.
  124. telemetry_enabled: bool = True
  125. # The pcdeploy url.
  126. pcdeploy_url: Optional[str] = None
  127. # The environment mode.
  128. env: constants.Env = constants.Env.DEV
  129. # The path to the bun executable.
  130. bun_path: str = constants.BUN_PATH
  131. # Disable bun.
  132. disable_bun: bool = False
  133. # Additional frontend packages to install.
  134. frontend_packages: List[str] = []
  135. # Backend transport methods.
  136. backend_transports: Optional[
  137. constants.Transports
  138. ] = constants.Transports.WEBSOCKET_POLLING
  139. # List of origins that are allowed to connect to the backend API.
  140. cors_allowed_origins: Optional[list] = [constants.CORS_ALLOWED_ORIGINS]
  141. # Whether credentials (cookies, authentication) are allowed in requests to the backend API.
  142. cors_credentials: Optional[bool] = True
  143. # The maximum size of a message when using the polling backend transport.
  144. polling_max_http_buffer_size: Optional[int] = constants.POLLING_MAX_HTTP_BUFFER_SIZE
  145. def __init__(self, *args, **kwargs):
  146. """Initialize the config values.
  147. If db_url is not provided gets it from db_config.
  148. Args:
  149. *args: The args to pass to the Pydantic init method.
  150. **kwargs: The kwargs to pass to the Pydantic init method.
  151. """
  152. if "db_url" not in kwargs and "db_config" in kwargs:
  153. kwargs["db_url"] = kwargs["db_config"].get_url()
  154. super().__init__(*args, **kwargs)
  155. def get_config() -> Config:
  156. """Get the app config.
  157. Returns:
  158. The app config.
  159. """
  160. from pynecone.config import Config
  161. sys.path.append(os.getcwd())
  162. try:
  163. return __import__(constants.CONFIG_MODULE).config
  164. except ImportError:
  165. return Config(app_name="") # type: ignore