plain 0.71.0__tar.gz → 0.72.1__tar.gz

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.
Files changed (182) hide show
  1. {plain-0.71.0 → plain-0.72.1}/.gitignore +1 -0
  2. {plain-0.71.0 → plain-0.72.1}/PKG-INFO +1 -1
  3. {plain-0.71.0 → plain-0.72.1}/plain/CHANGELOG.md +22 -0
  4. {plain-0.71.0 → plain-0.72.1}/plain/runtime/README.md +0 -1
  5. {plain-0.71.0 → plain-0.72.1}/plain/test/client.py +7 -3
  6. {plain-0.71.0 → plain-0.72.1}/plain/views/README.md +5 -5
  7. {plain-0.71.0 → plain-0.72.1}/pyproject.toml +1 -1
  8. {plain-0.71.0 → plain-0.72.1}/LICENSE +0 -0
  9. {plain-0.71.0 → plain-0.72.1}/README.md +0 -0
  10. {plain-0.71.0 → plain-0.72.1}/plain/AGENTS.md +0 -0
  11. {plain-0.71.0 → plain-0.72.1}/plain/README.md +0 -0
  12. {plain-0.71.0 → plain-0.72.1}/plain/__main__.py +0 -0
  13. {plain-0.71.0 → plain-0.72.1}/plain/assets/README.md +0 -0
  14. {plain-0.71.0 → plain-0.72.1}/plain/assets/__init__.py +0 -0
  15. {plain-0.71.0 → plain-0.72.1}/plain/assets/compile.py +0 -0
  16. {plain-0.71.0 → plain-0.72.1}/plain/assets/finders.py +0 -0
  17. {plain-0.71.0 → plain-0.72.1}/plain/assets/fingerprints.py +0 -0
  18. {plain-0.71.0 → plain-0.72.1}/plain/assets/urls.py +0 -0
  19. {plain-0.71.0 → plain-0.72.1}/plain/assets/views.py +0 -0
  20. {plain-0.71.0 → plain-0.72.1}/plain/chores/README.md +0 -0
  21. {plain-0.71.0 → plain-0.72.1}/plain/chores/__init__.py +0 -0
  22. {plain-0.71.0 → plain-0.72.1}/plain/chores/registry.py +0 -0
  23. {plain-0.71.0 → plain-0.72.1}/plain/cli/README.md +0 -0
  24. {plain-0.71.0 → plain-0.72.1}/plain/cli/__init__.py +0 -0
  25. {plain-0.71.0 → plain-0.72.1}/plain/cli/agent/__init__.py +0 -0
  26. {plain-0.71.0 → plain-0.72.1}/plain/cli/agent/docs.py +0 -0
  27. {plain-0.71.0 → plain-0.72.1}/plain/cli/agent/llmdocs.py +0 -0
  28. {plain-0.71.0 → plain-0.72.1}/plain/cli/agent/md.py +0 -0
  29. {plain-0.71.0 → plain-0.72.1}/plain/cli/agent/prompt.py +0 -0
  30. {plain-0.71.0 → plain-0.72.1}/plain/cli/agent/request.py +0 -0
  31. {plain-0.71.0 → plain-0.72.1}/plain/cli/build.py +0 -0
  32. {plain-0.71.0 → plain-0.72.1}/plain/cli/changelog.py +0 -0
  33. {plain-0.71.0 → plain-0.72.1}/plain/cli/chores.py +0 -0
  34. {plain-0.71.0 → plain-0.72.1}/plain/cli/core.py +0 -0
  35. {plain-0.71.0 → plain-0.72.1}/plain/cli/docs.py +0 -0
  36. {plain-0.71.0 → plain-0.72.1}/plain/cli/formatting.py +0 -0
  37. {plain-0.71.0 → plain-0.72.1}/plain/cli/install.py +0 -0
  38. {plain-0.71.0 → plain-0.72.1}/plain/cli/output.py +0 -0
  39. {plain-0.71.0 → plain-0.72.1}/plain/cli/preflight.py +0 -0
  40. {plain-0.71.0 → plain-0.72.1}/plain/cli/print.py +0 -0
  41. {plain-0.71.0 → plain-0.72.1}/plain/cli/registry.py +0 -0
  42. {plain-0.71.0 → plain-0.72.1}/plain/cli/scaffold.py +0 -0
  43. {plain-0.71.0 → plain-0.72.1}/plain/cli/settings.py +0 -0
  44. {plain-0.71.0 → plain-0.72.1}/plain/cli/shell.py +0 -0
  45. {plain-0.71.0 → plain-0.72.1}/plain/cli/startup.py +0 -0
  46. {plain-0.71.0 → plain-0.72.1}/plain/cli/upgrade.py +0 -0
  47. {plain-0.71.0 → plain-0.72.1}/plain/cli/urls.py +0 -0
  48. {plain-0.71.0 → plain-0.72.1}/plain/cli/utils.py +0 -0
  49. {plain-0.71.0 → plain-0.72.1}/plain/csrf/README.md +0 -0
  50. {plain-0.71.0 → plain-0.72.1}/plain/csrf/middleware.py +0 -0
  51. {plain-0.71.0 → plain-0.72.1}/plain/csrf/views.py +0 -0
  52. {plain-0.71.0 → plain-0.72.1}/plain/debug.py +0 -0
  53. {plain-0.71.0 → plain-0.72.1}/plain/exceptions.py +0 -0
  54. {plain-0.71.0 → plain-0.72.1}/plain/forms/README.md +0 -0
  55. {plain-0.71.0 → plain-0.72.1}/plain/forms/__init__.py +0 -0
  56. {plain-0.71.0 → plain-0.72.1}/plain/forms/boundfield.py +0 -0
  57. {plain-0.71.0 → plain-0.72.1}/plain/forms/exceptions.py +0 -0
  58. {plain-0.71.0 → plain-0.72.1}/plain/forms/fields.py +0 -0
  59. {plain-0.71.0 → plain-0.72.1}/plain/forms/forms.py +0 -0
  60. {plain-0.71.0 → plain-0.72.1}/plain/http/README.md +0 -0
  61. {plain-0.71.0 → plain-0.72.1}/plain/http/__init__.py +0 -0
  62. {plain-0.71.0 → plain-0.72.1}/plain/http/cookie.py +0 -0
  63. {plain-0.71.0 → plain-0.72.1}/plain/http/multipartparser.py +0 -0
  64. {plain-0.71.0 → plain-0.72.1}/plain/http/request.py +0 -0
  65. {plain-0.71.0 → plain-0.72.1}/plain/http/response.py +0 -0
  66. {plain-0.71.0 → plain-0.72.1}/plain/internal/__init__.py +0 -0
  67. {plain-0.71.0 → plain-0.72.1}/plain/internal/files/__init__.py +0 -0
  68. {plain-0.71.0 → plain-0.72.1}/plain/internal/files/base.py +0 -0
  69. {plain-0.71.0 → plain-0.72.1}/plain/internal/files/locks.py +0 -0
  70. {plain-0.71.0 → plain-0.72.1}/plain/internal/files/move.py +0 -0
  71. {plain-0.71.0 → plain-0.72.1}/plain/internal/files/temp.py +0 -0
  72. {plain-0.71.0 → plain-0.72.1}/plain/internal/files/uploadedfile.py +0 -0
  73. {plain-0.71.0 → plain-0.72.1}/plain/internal/files/uploadhandler.py +0 -0
  74. {plain-0.71.0 → plain-0.72.1}/plain/internal/files/utils.py +0 -0
  75. {plain-0.71.0 → plain-0.72.1}/plain/internal/handlers/__init__.py +0 -0
  76. {plain-0.71.0 → plain-0.72.1}/plain/internal/handlers/base.py +0 -0
  77. {plain-0.71.0 → plain-0.72.1}/plain/internal/handlers/exception.py +0 -0
  78. {plain-0.71.0 → plain-0.72.1}/plain/internal/handlers/wsgi.py +0 -0
  79. {plain-0.71.0 → plain-0.72.1}/plain/internal/middleware/__init__.py +0 -0
  80. {plain-0.71.0 → plain-0.72.1}/plain/internal/middleware/headers.py +0 -0
  81. {plain-0.71.0 → plain-0.72.1}/plain/internal/middleware/hosts.py +0 -0
  82. {plain-0.71.0 → plain-0.72.1}/plain/internal/middleware/https.py +0 -0
  83. {plain-0.71.0 → plain-0.72.1}/plain/internal/middleware/slash.py +0 -0
  84. {plain-0.71.0 → plain-0.72.1}/plain/json.py +0 -0
  85. {plain-0.71.0 → plain-0.72.1}/plain/logs/README.md +0 -0
  86. {plain-0.71.0 → plain-0.72.1}/plain/logs/__init__.py +0 -0
  87. {plain-0.71.0 → plain-0.72.1}/plain/logs/configure.py +0 -0
  88. {plain-0.71.0 → plain-0.72.1}/plain/logs/debug.py +0 -0
  89. {plain-0.71.0 → plain-0.72.1}/plain/logs/formatters.py +0 -0
  90. {plain-0.71.0 → plain-0.72.1}/plain/logs/loggers.py +0 -0
  91. {plain-0.71.0 → plain-0.72.1}/plain/logs/utils.py +0 -0
  92. {plain-0.71.0 → plain-0.72.1}/plain/packages/README.md +0 -0
  93. {plain-0.71.0 → plain-0.72.1}/plain/packages/__init__.py +0 -0
  94. {plain-0.71.0 → plain-0.72.1}/plain/packages/config.py +0 -0
  95. {plain-0.71.0 → plain-0.72.1}/plain/packages/registry.py +0 -0
  96. {plain-0.71.0 → plain-0.72.1}/plain/paginator.py +0 -0
  97. {plain-0.71.0 → plain-0.72.1}/plain/preflight/README.md +0 -0
  98. {plain-0.71.0 → plain-0.72.1}/plain/preflight/__init__.py +0 -0
  99. {plain-0.71.0 → plain-0.72.1}/plain/preflight/checks.py +0 -0
  100. {plain-0.71.0 → plain-0.72.1}/plain/preflight/files.py +0 -0
  101. {plain-0.71.0 → plain-0.72.1}/plain/preflight/registry.py +0 -0
  102. {plain-0.71.0 → plain-0.72.1}/plain/preflight/results.py +0 -0
  103. {plain-0.71.0 → plain-0.72.1}/plain/preflight/security.py +0 -0
  104. {plain-0.71.0 → plain-0.72.1}/plain/preflight/urls.py +0 -0
  105. {plain-0.71.0 → plain-0.72.1}/plain/runtime/__init__.py +0 -0
  106. {plain-0.71.0 → plain-0.72.1}/plain/runtime/global_settings.py +0 -0
  107. {plain-0.71.0 → plain-0.72.1}/plain/runtime/user_settings.py +0 -0
  108. {plain-0.71.0 → plain-0.72.1}/plain/runtime/utils.py +0 -0
  109. {plain-0.71.0 → plain-0.72.1}/plain/signals/README.md +0 -0
  110. {plain-0.71.0 → plain-0.72.1}/plain/signals/__init__.py +0 -0
  111. {plain-0.71.0 → plain-0.72.1}/plain/signals/dispatch/__init__.py +0 -0
  112. {plain-0.71.0 → plain-0.72.1}/plain/signals/dispatch/dispatcher.py +0 -0
  113. {plain-0.71.0 → plain-0.72.1}/plain/signals/dispatch/license.txt +0 -0
  114. {plain-0.71.0 → plain-0.72.1}/plain/signing.py +0 -0
  115. {plain-0.71.0 → plain-0.72.1}/plain/templates/AGENTS.md +0 -0
  116. {plain-0.71.0 → plain-0.72.1}/plain/templates/README.md +0 -0
  117. {plain-0.71.0 → plain-0.72.1}/plain/templates/__init__.py +0 -0
  118. {plain-0.71.0 → plain-0.72.1}/plain/templates/core.py +0 -0
  119. {plain-0.71.0 → plain-0.72.1}/plain/templates/jinja/__init__.py +0 -0
  120. {plain-0.71.0 → plain-0.72.1}/plain/templates/jinja/environments.py +0 -0
  121. {plain-0.71.0 → plain-0.72.1}/plain/templates/jinja/extensions.py +0 -0
  122. {plain-0.71.0 → plain-0.72.1}/plain/templates/jinja/filters.py +0 -0
  123. {plain-0.71.0 → plain-0.72.1}/plain/templates/jinja/globals.py +0 -0
  124. {plain-0.71.0 → plain-0.72.1}/plain/test/README.md +0 -0
  125. {plain-0.71.0 → plain-0.72.1}/plain/test/__init__.py +0 -0
  126. {plain-0.71.0 → plain-0.72.1}/plain/test/encoding.py +0 -0
  127. {plain-0.71.0 → plain-0.72.1}/plain/test/exceptions.py +0 -0
  128. {plain-0.71.0 → plain-0.72.1}/plain/urls/README.md +0 -0
  129. {plain-0.71.0 → plain-0.72.1}/plain/urls/__init__.py +0 -0
  130. {plain-0.71.0 → plain-0.72.1}/plain/urls/converters.py +0 -0
  131. {plain-0.71.0 → plain-0.72.1}/plain/urls/exceptions.py +0 -0
  132. {plain-0.71.0 → plain-0.72.1}/plain/urls/patterns.py +0 -0
  133. {plain-0.71.0 → plain-0.72.1}/plain/urls/resolvers.py +0 -0
  134. {plain-0.71.0 → plain-0.72.1}/plain/urls/routers.py +0 -0
  135. {plain-0.71.0 → plain-0.72.1}/plain/urls/utils.py +0 -0
  136. {plain-0.71.0 → plain-0.72.1}/plain/utils/README.md +0 -0
  137. {plain-0.71.0 → plain-0.72.1}/plain/utils/__init__.py +0 -0
  138. {plain-0.71.0 → plain-0.72.1}/plain/utils/cache.py +0 -0
  139. {plain-0.71.0 → plain-0.72.1}/plain/utils/crypto.py +0 -0
  140. {plain-0.71.0 → plain-0.72.1}/plain/utils/datastructures.py +0 -0
  141. {plain-0.71.0 → plain-0.72.1}/plain/utils/dateparse.py +0 -0
  142. {plain-0.71.0 → plain-0.72.1}/plain/utils/deconstruct.py +0 -0
  143. {plain-0.71.0 → plain-0.72.1}/plain/utils/decorators.py +0 -0
  144. {plain-0.71.0 → plain-0.72.1}/plain/utils/duration.py +0 -0
  145. {plain-0.71.0 → plain-0.72.1}/plain/utils/encoding.py +0 -0
  146. {plain-0.71.0 → plain-0.72.1}/plain/utils/functional.py +0 -0
  147. {plain-0.71.0 → plain-0.72.1}/plain/utils/hashable.py +0 -0
  148. {plain-0.71.0 → plain-0.72.1}/plain/utils/html.py +0 -0
  149. {plain-0.71.0 → plain-0.72.1}/plain/utils/http.py +0 -0
  150. {plain-0.71.0 → plain-0.72.1}/plain/utils/inspect.py +0 -0
  151. {plain-0.71.0 → plain-0.72.1}/plain/utils/ipv6.py +0 -0
  152. {plain-0.71.0 → plain-0.72.1}/plain/utils/itercompat.py +0 -0
  153. {plain-0.71.0 → plain-0.72.1}/plain/utils/module_loading.py +0 -0
  154. {plain-0.71.0 → plain-0.72.1}/plain/utils/regex_helper.py +0 -0
  155. {plain-0.71.0 → plain-0.72.1}/plain/utils/safestring.py +0 -0
  156. {plain-0.71.0 → plain-0.72.1}/plain/utils/text.py +0 -0
  157. {plain-0.71.0 → plain-0.72.1}/plain/utils/timesince.py +0 -0
  158. {plain-0.71.0 → plain-0.72.1}/plain/utils/timezone.py +0 -0
  159. {plain-0.71.0 → plain-0.72.1}/plain/utils/tree.py +0 -0
  160. {plain-0.71.0 → plain-0.72.1}/plain/validators.py +0 -0
  161. {plain-0.71.0 → plain-0.72.1}/plain/views/__init__.py +0 -0
  162. {plain-0.71.0 → plain-0.72.1}/plain/views/base.py +0 -0
  163. {plain-0.71.0 → plain-0.72.1}/plain/views/errors.py +0 -0
  164. {plain-0.71.0 → plain-0.72.1}/plain/views/exceptions.py +0 -0
  165. {plain-0.71.0 → plain-0.72.1}/plain/views/forms.py +0 -0
  166. {plain-0.71.0 → plain-0.72.1}/plain/views/objects.py +0 -0
  167. {plain-0.71.0 → plain-0.72.1}/plain/views/redirect.py +0 -0
  168. {plain-0.71.0 → plain-0.72.1}/plain/views/templates.py +0 -0
  169. {plain-0.71.0 → plain-0.72.1}/plain/wsgi.py +0 -0
  170. {plain-0.71.0 → plain-0.72.1}/tests/.gitignore +0 -0
  171. {plain-0.71.0 → plain-0.72.1}/tests/app/.gitignore +0 -0
  172. {plain-0.71.0 → plain-0.72.1}/tests/app/settings.py +0 -0
  173. {plain-0.71.0 → plain-0.72.1}/tests/app/test/__init__.py +0 -0
  174. {plain-0.71.0 → plain-0.72.1}/tests/app/test/default_settings.py +0 -0
  175. {plain-0.71.0 → plain-0.72.1}/tests/app/urls.py +0 -0
  176. {plain-0.71.0 → plain-0.72.1}/tests/conftest.py +0 -0
  177. {plain-0.71.0 → plain-0.72.1}/tests/test_cli.py +0 -0
  178. {plain-0.71.0 → plain-0.72.1}/tests/test_csrf.py +0 -0
  179. {plain-0.71.0 → plain-0.72.1}/tests/test_http_hosts.py +0 -0
  180. {plain-0.71.0 → plain-0.72.1}/tests/test_logs.py +0 -0
  181. {plain-0.71.0 → plain-0.72.1}/tests/test_runtime.py +0 -0
  182. {plain-0.71.0 → plain-0.72.1}/tests/test_wsgi.py +0 -0
@@ -16,3 +16,4 @@ plain*/tests/.plain
16
16
 
17
17
  .vscode
18
18
  /.claude
19
+ /.benchmarks
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain
3
- Version: 0.71.0
3
+ Version: 0.72.1
4
4
  Summary: A web framework for building products with Python.
5
5
  Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
6
6
  License-File: LICENSE
@@ -1,5 +1,27 @@
1
1
  # plain changelog
2
2
 
3
+ ## [0.72.1](https://github.com/dropseed/plain/releases/plain@0.72.1) (2025-10-02)
4
+
5
+ ### What's changed
6
+
7
+ - Fixed documentation examples to use the correct view attribute names (`self.user` instead of `self.request.user`) ([f6278d9](https://github.com/dropseed/plain/commit/f6278d9bb4))
8
+
9
+ ### Upgrade instructions
10
+
11
+ - No changes required
12
+
13
+ ## [0.72.0](https://github.com/dropseed/plain/releases/plain@0.72.0) (2025-10-02)
14
+
15
+ ### What's changed
16
+
17
+ - Request attributes `user` and `session` are no longer set directly on the request object ([154ee10](https://github.com/dropseed/plain/commit/154ee10375))
18
+ - Test client now uses `plain.auth.requests.get_request_user()` to retrieve user for response object when available ([154ee10](https://github.com/dropseed/plain/commit/154ee10375))
19
+ - Removed `plain.auth.middleware.AuthenticationMiddleware` from default middleware configuration ([154ee10](https://github.com/dropseed/plain/commit/154ee10375))
20
+
21
+ ### Upgrade instructions
22
+
23
+ - No changes required
24
+
3
25
  ## [0.71.0](https://github.com/dropseed/plain/releases/plain@0.71.0) (2025-09-30)
4
26
 
5
27
  ### What's changed
@@ -37,7 +37,6 @@ AUTH_LOGIN_URL = "login"
37
37
 
38
38
  MIDDLEWARE = [
39
39
  "plain.sessions.middleware.SessionMiddleware",
40
- "plain.auth.middleware.AuthenticationMiddleware",
41
40
  "plain.admin.AdminMiddleware",
42
41
  ]
43
42
  ```
@@ -494,9 +494,13 @@ class Client:
494
494
  response.request = request
495
495
  response.json = partial(self._parse_json, response)
496
496
 
497
- # If the request had a user attached, make it available on the response.
498
- if hasattr(response.wsgi_request, "user"):
499
- response.user = response.wsgi_request.user
497
+ # If the request had a user, make it available on the response.
498
+ try:
499
+ from plain.auth.requests import get_request_user
500
+
501
+ response.user = get_request_user(response.wsgi_request)
502
+ except ImportError:
503
+ pass
500
504
 
501
505
  # Attach the ResolverMatch instance to the response.
502
506
  resolver = get_resolver()
@@ -181,7 +181,7 @@ class ExampleDetailView(DetailView):
181
181
  def get_object(self):
182
182
  return MyObjectClass.query.get(
183
183
  id=self.url_kwargs["id"],
184
- user=self.request.user, # Limit access
184
+ user=self.user, # Limit access
185
185
  )
186
186
 
187
187
 
@@ -199,7 +199,7 @@ class ExampleUpdateView(UpdateView):
199
199
  def get_object(self):
200
200
  return MyObjectClass.query.get(
201
201
  id=self.url_kwargs["id"],
202
- user=self.request.user, # Limit access
202
+ user=self.user, # Limit access
203
203
  )
204
204
 
205
205
 
@@ -213,7 +213,7 @@ class ExampleDeleteView(DeleteView):
213
213
  def get_object(self):
214
214
  return MyObjectClass.query.get(
215
215
  id=self.url_kwargs["id"],
216
- user=self.request.user, # Limit access
216
+ user=self.user, # Limit access
217
217
  )
218
218
 
219
219
 
@@ -222,7 +222,7 @@ class ExampleListView(ListView):
222
222
 
223
223
  def get_objects(self):
224
224
  return MyObjectClass.query.filter(
225
- user=self.request.user, # Limit access
225
+ user=self.user, # Limit access
226
226
  )
227
227
  ```
228
228
 
@@ -241,7 +241,7 @@ from plain.http import Response
241
241
 
242
242
  class ExampleView(DetailView):
243
243
  def get_object(self):
244
- if self.request.user.exceeds_rate_limit:
244
+ if self.user and self.user.exceeds_rate_limit:
245
245
  raise ResponseException(
246
246
  Response("Rate limit exceeded", status_code=429)
247
247
  )
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "plain"
3
- version = "0.71.0"
3
+ version = "0.72.1"
4
4
  description = "A web framework for building products with Python."
5
5
  authors = [{name = "Dave Gaeddert", email = "dave.gaeddert@dropseed.dev"}]
6
6
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes