plain 0.4.1__py3-none-any.whl → 0.11.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
plain/runtime/__init__.py CHANGED
@@ -1,11 +1,9 @@
1
1
  import importlib.metadata
2
2
  import sys
3
- from os import environ
3
+ from importlib.metadata import entry_points
4
4
  from pathlib import Path
5
5
 
6
- from dotenv import load_dotenv
7
-
8
- from .user_settings import LazySettings
6
+ from .user_settings import Settings
9
7
 
10
8
  try:
11
9
  __version__ = importlib.metadata.version("plain")
@@ -16,9 +14,8 @@ except importlib.metadata.PackageNotFoundError:
16
14
  # Made available without setup or settings
17
15
  APP_PATH = Path.cwd() / "app"
18
16
 
19
-
20
17
  # from plain.runtime import settings
21
- settings = LazySettings()
18
+ settings = Settings()
22
19
 
23
20
 
24
21
  class AppPathNotFound(RuntimeError):
@@ -30,6 +27,11 @@ def setup():
30
27
  Configure the settings (this happens as a side effect of accessing the
31
28
  first setting), configure logging and populate the app registry.
32
29
  """
30
+
31
+ # Packages can hook into the setup process through an entrypoint.
32
+ for entry_point in entry_points().select(group="plain.setup"):
33
+ entry_point.load()()
34
+
33
35
  from plain.logs import configure_logging
34
36
  from plain.packages import packages
35
37
 
@@ -38,15 +40,11 @@ def setup():
38
40
  "No app directory found. Are you sure you're in a Plain project?"
39
41
  )
40
42
 
41
- # Automatically put the app dir on the Python path for convenience
42
- if APP_PATH not in sys.path:
43
- sys.path.insert(0, APP_PATH.as_posix())
44
-
45
- # Load .env files automatically before settings
46
- if app_env := environ.get("PLAIN_ENV", ""):
47
- load_dotenv(f".env.{app_env}")
48
- else:
49
- load_dotenv(".env")
43
+ # Automatically put the project dir on the Python path
44
+ # which doesn't otherwise happen when you run `plain` commands.
45
+ # This makes "app.<module>" imports and relative imports work.
46
+ if APP_PATH.parent not in sys.path:
47
+ sys.path.insert(0, APP_PATH.parent.as_posix())
50
48
 
51
49
  configure_logging(settings.LOGGING)
52
50
 
@@ -20,23 +20,50 @@ ALLOWED_HOSTS: list[str] = []
20
20
 
21
21
  # Local time zone for this installation. All choices can be found here:
22
22
  # https://en.wikipedia.org/wiki/List_of_tz_zones_by_name (although not all
23
- # systems may support all possibilities). When USE_TZ is True, this is
24
- # interpreted as the default user time zone.
25
- TIME_ZONE = "America/Chicago"
26
-
27
- # If you set this to True, Plain will use timezone-aware datetimes.
28
- USE_TZ = True
23
+ # systems may support all possibilities). This is interpreted as the default
24
+ # user time zone.
25
+ TIME_ZONE: str = "UTC"
29
26
 
30
27
  # Default charset to use for all Response objects, if a MIME type isn't
31
28
  # manually specified. It's used to construct the Content-Type header.
32
29
  DEFAULT_CHARSET = "utf-8"
33
30
 
34
31
  # List of strings representing installed packages.
35
- INSTALLED_PACKAGES: list = []
32
+ INSTALLED_PACKAGES: list[str] = []
36
33
 
37
34
  # Whether to append trailing slashes to URLs.
38
35
  APPEND_SLASH = True
39
36
 
37
+ # Default headers for all responses.
38
+ DEFAULT_RESPONSE_HEADERS = {
39
+ # "Content-Security-Policy": "default-src 'self'",
40
+ # https://hstspreload.org/
41
+ # "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
42
+ "Cross-Origin-Opener-Policy": "same-origin",
43
+ "Referrer-Policy": "same-origin",
44
+ "X-Content-Type-Options": "nosniff",
45
+ "X-Frame-Options": "DENY",
46
+ }
47
+
48
+ # Whether to redirect all non-HTTPS requests to HTTPS.
49
+ HTTPS_REDIRECT_ENABLED = True
50
+ HTTPS_REDIRECT_EXEMPT = []
51
+ HTTPS_REDIRECT_HOST = None
52
+
53
+ # If your Plain app is behind a proxy that sets a header to specify secure
54
+ # connections, AND that proxy ensures that user-submitted headers with the
55
+ # same name are ignored (so that people can't spoof it), set this value to
56
+ # a tuple of (header_name, header_value). For any requests that come in with
57
+ # that header/value, request.is_https() will return True.
58
+ # WARNING! Only set this if you fully understand what you're doing. Otherwise,
59
+ # you may be opening yourself up to a security risk.
60
+ HTTPS_PROXY_HEADER = None
61
+
62
+ # Whether to use the X-Forwarded-Host and X-Forwarded-Port headers
63
+ # when determining the host and port for the request.
64
+ USE_X_FORWARDED_HOST = False
65
+ USE_X_FORWARDED_PORT = False
66
+
40
67
  # A secret key for this particular Plain installation. Used in secret-key
41
68
  # hashing algorithms. Set this in your settings, or Plain will complain
42
69
  # loudly.
@@ -46,7 +73,7 @@ SECRET_KEY: str
46
73
  # secret key rotation.
47
74
  SECRET_KEY_FALLBACKS: list[str] = []
48
75
 
49
- ROOT_URLCONF = "urls"
76
+ ROOT_URLCONF = "app.urls"
50
77
 
51
78
  # List of upload handler classes to be applied in order.
52
79
  FILE_UPLOAD_HANDLERS = [
@@ -75,34 +102,9 @@ DATA_UPLOAD_MAX_NUMBER_FILES = 100
75
102
  # (i.e. "/tmp" on *nix systems).
76
103
  FILE_UPLOAD_TEMP_DIR = None
77
104
 
78
- # The numeric mode to set newly-uploaded files to. The value should be a mode
79
- # you'd pass directly to os.chmod; see
80
- # https://docs.python.org/library/os.html#files-and-directories.
81
- FILE_UPLOAD_PERMISSIONS = 0o644
82
-
83
- # The numeric mode to assign to newly-created directories, when uploading files.
84
- # The value should be a mode as you'd pass to os.chmod;
85
- # see https://docs.python.org/library/os.html#files-and-directories.
86
- FILE_UPLOAD_DIRECTORY_PERMISSIONS = None
87
-
88
- # Default X-Frame-Options header value
89
- X_FRAME_OPTIONS = "DENY"
90
-
91
- USE_X_FORWARDED_HOST = False
92
- USE_X_FORWARDED_PORT = False
93
-
94
105
  # User-defined overrides for error views by status code
95
106
  HTTP_ERROR_VIEWS: dict[int] = {}
96
107
 
97
- # If your Plain app is behind a proxy that sets a header to specify secure
98
- # connections, AND that proxy ensures that user-submitted headers with the
99
- # same name are ignored (so that people can't spoof it), set this value to
100
- # a tuple of (header_name, header_value). For any requests that come in with
101
- # that header/value, request.is_secure() will return True.
102
- # WARNING! Only set this if you fully understand what you're doing. Otherwise,
103
- # you may be opening yourself up to a security risk.
104
- SECURE_PROXY_SSL_HEADER = None
105
-
106
108
  ##############
107
109
  # MIDDLEWARE #
108
110
  ##############
@@ -110,18 +112,13 @@ SECURE_PROXY_SSL_HEADER = None
110
112
  # List of middleware to use. Order is important; in the request phase, these
111
113
  # middleware will be applied in the order given, and in the response
112
114
  # phase the middleware will be applied in reverse order.
113
- MIDDLEWARE = [
114
- "plain.middleware.security.SecurityMiddleware",
115
- "plain.middleware.common.CommonMiddleware",
116
- "plain.csrf.middleware.CsrfViewMiddleware",
117
- "plain.middleware.clickjacking.XFrameOptionsMiddleware",
118
- ]
115
+ MIDDLEWARE: list[str] = []
119
116
 
120
117
  ###########
121
118
  # SIGNING #
122
119
  ###########
123
120
 
124
- SIGNING_BACKEND = "plain.signing.TimestampSigner"
121
+ COOKIE_SIGNING_BACKEND = "plain.signing.TimestampSigner"
125
122
 
126
123
  ########
127
124
  # CSRF #
@@ -132,12 +129,11 @@ CSRF_COOKIE_NAME = "csrftoken"
132
129
  CSRF_COOKIE_AGE = 60 * 60 * 24 * 7 * 52
133
130
  CSRF_COOKIE_DOMAIN = None
134
131
  CSRF_COOKIE_PATH = "/"
135
- CSRF_COOKIE_SECURE = False
132
+ CSRF_COOKIE_SECURE = True
136
133
  CSRF_COOKIE_HTTPONLY = False
137
134
  CSRF_COOKIE_SAMESITE = "Lax"
138
135
  CSRF_HEADER_NAME = "HTTP_X_CSRFTOKEN"
139
136
  CSRF_TRUSTED_ORIGINS: list[str] = []
140
- CSRF_USE_SESSIONS = False
141
137
 
142
138
  ###########
143
139
  # LOGGING #
@@ -167,19 +163,6 @@ ASSETS_BASE_URL: str = ""
167
163
  # message, but Plain will not stop you from e.g. running server.
168
164
  SILENCED_PREFLIGHT_CHECKS = []
169
165
 
170
- #######################
171
- # SECURITY MIDDLEWARE #
172
- #######################
173
- SECURE_CONTENT_TYPE_NOSNIFF = True
174
- SECURE_CROSS_ORIGIN_OPENER_POLICY = "same-origin"
175
- SECURE_HSTS_INCLUDE_SUBDOMAINS = False
176
- SECURE_HSTS_PRELOAD = False
177
- SECURE_HSTS_SECONDS = 0
178
- SECURE_REDIRECT_EXEMPT = []
179
- SECURE_REFERRER_POLICY = "same-origin"
180
- SECURE_SSL_HOST = None
181
- SECURE_SSL_REDIRECT = False
182
-
183
166
  #############
184
167
  # Templates #
185
168
  #############