plain 0.68.0__py3-none-any.whl → 0.103.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/CHANGELOG.md +684 -1
- plain/README.md +1 -1
- plain/agents/.claude/rules/plain.md +88 -0
- plain/agents/.claude/skills/plain-install/SKILL.md +26 -0
- plain/agents/.claude/skills/plain-upgrade/SKILL.md +35 -0
- plain/assets/compile.py +25 -12
- plain/assets/finders.py +24 -17
- plain/assets/fingerprints.py +10 -7
- plain/assets/urls.py +1 -1
- plain/assets/views.py +47 -33
- plain/chores/README.md +25 -23
- plain/chores/__init__.py +2 -1
- plain/chores/core.py +27 -0
- plain/chores/registry.py +23 -36
- plain/cli/README.md +185 -16
- plain/cli/__init__.py +2 -1
- plain/cli/agent.py +234 -0
- plain/cli/build.py +7 -8
- plain/cli/changelog.py +11 -5
- plain/cli/chores.py +32 -34
- plain/cli/core.py +110 -26
- plain/cli/docs.py +98 -21
- plain/cli/formatting.py +40 -17
- plain/cli/install.py +10 -54
- plain/cli/{agent/llmdocs.py → llmdocs.py} +45 -26
- plain/cli/output.py +6 -2
- plain/cli/preflight.py +27 -75
- plain/cli/print.py +4 -4
- plain/cli/registry.py +96 -10
- plain/cli/{agent/request.py → request.py} +67 -33
- plain/cli/runtime.py +45 -0
- plain/cli/scaffold.py +2 -7
- plain/cli/server.py +153 -0
- plain/cli/settings.py +53 -49
- plain/cli/shell.py +15 -12
- plain/cli/startup.py +9 -8
- plain/cli/upgrade.py +17 -104
- plain/cli/urls.py +12 -7
- plain/cli/utils.py +3 -3
- plain/csrf/README.md +65 -40
- plain/csrf/middleware.py +53 -43
- plain/debug.py +5 -2
- plain/exceptions.py +22 -114
- plain/forms/README.md +453 -24
- plain/forms/__init__.py +55 -4
- plain/forms/boundfield.py +15 -8
- plain/forms/exceptions.py +1 -1
- plain/forms/fields.py +346 -143
- plain/forms/forms.py +75 -45
- plain/http/README.md +356 -9
- plain/http/__init__.py +41 -26
- plain/http/cookie.py +15 -7
- plain/http/exceptions.py +65 -0
- plain/http/middleware.py +32 -0
- plain/http/multipartparser.py +99 -88
- plain/http/request.py +362 -250
- plain/http/response.py +99 -197
- plain/internal/__init__.py +8 -1
- plain/internal/files/base.py +35 -19
- plain/internal/files/locks.py +19 -11
- plain/internal/files/move.py +8 -3
- plain/internal/files/temp.py +25 -6
- plain/internal/files/uploadedfile.py +47 -28
- plain/internal/files/uploadhandler.py +64 -58
- plain/internal/files/utils.py +24 -10
- plain/internal/handlers/base.py +34 -23
- plain/internal/handlers/exception.py +68 -65
- plain/internal/handlers/wsgi.py +65 -54
- plain/internal/middleware/headers.py +37 -11
- plain/internal/middleware/hosts.py +11 -8
- plain/internal/middleware/https.py +17 -7
- plain/internal/middleware/slash.py +14 -9
- plain/internal/reloader.py +77 -0
- plain/json.py +2 -1
- plain/logs/README.md +161 -62
- plain/logs/__init__.py +1 -1
- plain/logs/{loggers.py → app.py} +71 -67
- plain/logs/configure.py +63 -14
- plain/logs/debug.py +17 -6
- plain/logs/filters.py +15 -0
- plain/logs/formatters.py +7 -4
- plain/packages/README.md +105 -23
- plain/packages/config.py +15 -7
- plain/packages/registry.py +27 -16
- plain/paginator.py +31 -21
- plain/preflight/README.md +209 -24
- plain/preflight/__init__.py +1 -0
- plain/preflight/checks.py +3 -1
- plain/preflight/files.py +3 -1
- plain/preflight/registry.py +26 -11
- plain/preflight/results.py +15 -7
- plain/preflight/security.py +15 -13
- plain/preflight/settings.py +54 -0
- plain/preflight/urls.py +4 -1
- plain/runtime/README.md +115 -47
- plain/runtime/__init__.py +10 -6
- plain/runtime/global_settings.py +34 -25
- plain/runtime/secret.py +20 -0
- plain/runtime/user_settings.py +110 -38
- plain/runtime/utils.py +1 -1
- plain/server/LICENSE +35 -0
- plain/server/README.md +155 -0
- plain/server/__init__.py +9 -0
- plain/server/app.py +52 -0
- plain/server/arbiter.py +555 -0
- plain/server/config.py +118 -0
- plain/server/errors.py +31 -0
- plain/server/glogging.py +292 -0
- plain/server/http/__init__.py +12 -0
- plain/server/http/body.py +283 -0
- plain/server/http/errors.py +155 -0
- plain/server/http/message.py +400 -0
- plain/server/http/parser.py +70 -0
- plain/server/http/unreader.py +88 -0
- plain/server/http/wsgi.py +421 -0
- plain/server/pidfile.py +92 -0
- plain/server/sock.py +240 -0
- plain/server/util.py +317 -0
- plain/server/workers/__init__.py +6 -0
- plain/server/workers/base.py +304 -0
- plain/server/workers/sync.py +212 -0
- plain/server/workers/thread.py +399 -0
- plain/server/workers/workertmp.py +50 -0
- plain/signals/README.md +170 -1
- plain/signals/__init__.py +0 -1
- plain/signals/dispatch/dispatcher.py +49 -27
- plain/signing.py +131 -35
- plain/templates/README.md +211 -20
- plain/templates/jinja/__init__.py +13 -5
- plain/templates/jinja/environments.py +5 -4
- plain/templates/jinja/extensions.py +12 -5
- plain/templates/jinja/filters.py +7 -2
- plain/templates/jinja/globals.py +2 -2
- plain/test/README.md +184 -22
- plain/test/client.py +340 -222
- plain/test/encoding.py +9 -6
- plain/test/exceptions.py +7 -2
- plain/urls/README.md +157 -73
- plain/urls/converters.py +18 -15
- plain/urls/exceptions.py +2 -2
- plain/urls/patterns.py +38 -22
- plain/urls/resolvers.py +35 -25
- plain/urls/utils.py +5 -1
- plain/utils/README.md +250 -3
- plain/utils/cache.py +17 -11
- plain/utils/crypto.py +21 -5
- plain/utils/datastructures.py +89 -56
- plain/utils/dateparse.py +9 -6
- plain/utils/deconstruct.py +15 -7
- plain/utils/decorators.py +5 -1
- plain/utils/dotenv.py +373 -0
- plain/utils/duration.py +8 -4
- plain/utils/encoding.py +14 -7
- plain/utils/functional.py +66 -49
- plain/utils/hashable.py +5 -1
- plain/utils/html.py +36 -22
- plain/utils/http.py +16 -9
- plain/utils/inspect.py +14 -6
- plain/utils/ipv6.py +7 -3
- plain/utils/itercompat.py +6 -1
- plain/utils/module_loading.py +7 -3
- plain/utils/regex_helper.py +37 -23
- plain/utils/safestring.py +14 -6
- plain/utils/text.py +41 -23
- plain/utils/timezone.py +33 -22
- plain/utils/tree.py +35 -19
- plain/validators.py +94 -52
- plain/views/README.md +156 -79
- plain/views/__init__.py +0 -1
- plain/views/base.py +25 -18
- plain/views/errors.py +13 -5
- plain/views/exceptions.py +4 -1
- plain/views/forms.py +6 -6
- plain/views/objects.py +52 -49
- plain/views/redirect.py +18 -15
- plain/views/templates.py +5 -3
- plain/wsgi.py +3 -1
- {plain-0.68.0.dist-info → plain-0.103.0.dist-info}/METADATA +4 -2
- plain-0.103.0.dist-info/RECORD +198 -0
- {plain-0.68.0.dist-info → plain-0.103.0.dist-info}/WHEEL +1 -1
- plain-0.103.0.dist-info/entry_points.txt +2 -0
- plain/AGENTS.md +0 -18
- plain/cli/agent/__init__.py +0 -20
- plain/cli/agent/docs.py +0 -80
- plain/cli/agent/md.py +0 -87
- plain/cli/agent/prompt.py +0 -45
- plain/csrf/views.py +0 -31
- plain/logs/utils.py +0 -46
- plain/templates/AGENTS.md +0 -3
- plain-0.68.0.dist-info/RECORD +0 -169
- plain-0.68.0.dist-info/entry_points.txt +0 -5
- {plain-0.68.0.dist-info → plain-0.103.0.dist-info}/licenses/LICENSE +0 -0
plain/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,688 @@
|
|
|
1
1
|
# plain changelog
|
|
2
2
|
|
|
3
|
+
## [0.103.0](https://github.com/dropseed/plain/releases/plain@0.103.0) (2026-01-30)
|
|
4
|
+
|
|
5
|
+
### What's changed
|
|
6
|
+
|
|
7
|
+
- `plain docs` now shows markdown documentation by default (previously required `--source`), with a new `--symbols` flag to show only the symbolicated API surface ([b71dab9d5d](https://github.com/dropseed/plain/commit/b71dab9d5d))
|
|
8
|
+
- `plain docs --list` now shows all official Plain packages (installed and uninstalled) with descriptions and install status ([9cba705d62](https://github.com/dropseed/plain/commit/9cba705d62))
|
|
9
|
+
- `plain docs` for uninstalled packages now shows the install command and an online docs URL instead of a generic error ([9cba705d62](https://github.com/dropseed/plain/commit/9cba705d62))
|
|
10
|
+
- Removed the `plain agent context` command and the `SessionStart` hook setup — agent rules now provide context directly without needing a startup hook ([88d9424643](https://github.com/dropseed/plain/commit/88d9424643))
|
|
11
|
+
- `plain agent install` now cleans up old SessionStart hooks from `.claude/settings.json` ([88d9424643](https://github.com/dropseed/plain/commit/88d9424643))
|
|
12
|
+
|
|
13
|
+
### Upgrade instructions
|
|
14
|
+
|
|
15
|
+
- The `--source` flag for `plain docs` has been removed. Use `--symbols` instead to see the symbolicated API surface.
|
|
16
|
+
- The `--open` flag for `plain docs` has been removed.
|
|
17
|
+
- Run `plain agent install` to clean up the old SessionStart hook from your `.claude/settings.json`.
|
|
18
|
+
|
|
19
|
+
## [0.102.0](https://github.com/dropseed/plain/releases/plain@0.102.0) (2026-01-28)
|
|
20
|
+
|
|
21
|
+
### What's changed
|
|
22
|
+
|
|
23
|
+
- Refactored agent integration from skills-based to rules-based: packages now provide `agents/.claude/rules/` files and `agents/.claude/skills/` directories instead of `skills/` directories ([512040ac51](https://github.com/dropseed/plain/commit/512040ac51))
|
|
24
|
+
- The `plain agent install` command now copies both rules (`.md` files) and skills to the project's `.claude/` directory, and cleans up orphaned `plain*` items ([512040ac51](https://github.com/dropseed/plain/commit/512040ac51))
|
|
25
|
+
- Removed standalone skills (`plain-docs`, `plain-shell`, `plain-request`) that are now provided as passive rules instead ([512040ac51](https://github.com/dropseed/plain/commit/512040ac51))
|
|
26
|
+
|
|
27
|
+
### Upgrade instructions
|
|
28
|
+
|
|
29
|
+
- Run `plain agent install` to update your `.claude/` directory with the new rules-based structure.
|
|
30
|
+
|
|
31
|
+
## [0.101.2](https://github.com/dropseed/plain/releases/plain@0.101.2) (2026-01-28)
|
|
32
|
+
|
|
33
|
+
### What's changed
|
|
34
|
+
|
|
35
|
+
- When `load_dotenv()` is called with `override=False` (the default), command substitution is now skipped for keys that already exist in `os.environ`. This prevents redundant command execution in child processes that re-load the `.env` file after inheriting resolved values from the parent, avoiding multiple auth prompts with tools like the 1Password CLI ([2f6ff93499](https://github.com/dropseed/plain/commit/2f6ff93499))
|
|
36
|
+
- The `_execute_command` helper now uses `stdout=subprocess.PIPE` instead of `capture_output=True`, allowing stderr/tty to pass through for interactive prompts ([2f6ff93499](https://github.com/dropseed/plain/commit/2f6ff93499))
|
|
37
|
+
- Updated templates README examples to use `id` instead of `pk` ([837d345d23](https://github.com/dropseed/plain/commit/837d345d23))
|
|
38
|
+
- Added Settings section to README ([803fee1ad5](https://github.com/dropseed/plain/commit/803fee1ad5))
|
|
39
|
+
|
|
40
|
+
### Upgrade instructions
|
|
41
|
+
|
|
42
|
+
- No changes required.
|
|
43
|
+
|
|
44
|
+
## [0.101.1](https://github.com/dropseed/plain/releases/plain@0.101.1) (2026-01-17)
|
|
45
|
+
|
|
46
|
+
### What's changed
|
|
47
|
+
|
|
48
|
+
- Fixed a crash when running the development server with `--reload` when an app's `assets` directory doesn't exist ([df33f93ece](https://github.com/dropseed/plain/commit/df33f93ece))
|
|
49
|
+
- The `plain agent install` command now preserves user-created skills (those without the `plain-` prefix) instead of removing them as orphans ([bbc87498ed](https://github.com/dropseed/plain/commit/bbc87498ed))
|
|
50
|
+
|
|
51
|
+
### Upgrade instructions
|
|
52
|
+
|
|
53
|
+
- No changes required.
|
|
54
|
+
|
|
55
|
+
## [0.101.0](https://github.com/dropseed/plain/releases/plain@0.101.0) (2026-01-15)
|
|
56
|
+
|
|
57
|
+
### What's changed
|
|
58
|
+
|
|
59
|
+
- The `plain server` command now accepts `--workers auto` (or `WEB_CONCURRENCY=auto`) to automatically set worker count based on CPU count ([02a1769948](https://github.com/dropseed/plain/commit/02a1769948))
|
|
60
|
+
- Response headers can now be set to `None` to opt out of default headers; `None` values are filtered out at the WSGI layer rather than being deleted by middleware ([cbf27e728d](https://github.com/dropseed/plain/commit/cbf27e728d))
|
|
61
|
+
- Removed unused `Response` methods: `serialize_headers`, `serialize`, file-like interface stubs (`write`, `flush`, `tell`, `readable`, `seekable`, `writable`, `writelines`), `text` property, pickling support, and `getvalue` ([cbf27e728d](https://github.com/dropseed/plain/commit/cbf27e728d))
|
|
62
|
+
|
|
63
|
+
### Upgrade instructions
|
|
64
|
+
|
|
65
|
+
- No changes required
|
|
66
|
+
|
|
67
|
+
## [0.100.1](https://github.com/dropseed/plain/releases/plain@0.100.1) (2026-01-15)
|
|
68
|
+
|
|
69
|
+
### What's changed
|
|
70
|
+
|
|
71
|
+
- The `plain agent install` command now only sets up session hooks for Claude Code, not Codex, since the `settings.json` hook format is Claude Code-specific ([a41e08bcd2](https://github.com/dropseed/plain/commit/a41e08bcd2))
|
|
72
|
+
|
|
73
|
+
### Upgrade instructions
|
|
74
|
+
|
|
75
|
+
- No changes required
|
|
76
|
+
|
|
77
|
+
## [0.100.0](https://github.com/dropseed/plain/releases/plain@0.100.0) (2026-01-15)
|
|
78
|
+
|
|
79
|
+
### What's changed
|
|
80
|
+
|
|
81
|
+
- The `plain skills` command has been renamed to `plain agent` with new subcommands: `plain agent install` (installs skills and sets up hooks), `plain agent skills` (lists available skills), and `plain agent context` (outputs framework context) ([fac8673436](https://github.com/dropseed/plain/commit/fac8673436))
|
|
82
|
+
- Added `SessionStart` hook that automatically runs `plain agent context` at the start of every Claude Code or Codex session, providing framework context without needing a separate skill ([fac8673436](https://github.com/dropseed/plain/commit/fac8673436))
|
|
83
|
+
- The `plain-principles` skill has been removed - its content is now provided by the `plain agent context` command via the SessionStart hook ([fac8673436](https://github.com/dropseed/plain/commit/fac8673436))
|
|
84
|
+
- Added `--no-headers` and `--no-body` flags to `plain request` for limiting output ([fac8673436](https://github.com/dropseed/plain/commit/fac8673436))
|
|
85
|
+
|
|
86
|
+
### Upgrade instructions
|
|
87
|
+
|
|
88
|
+
- Replace `plain skills --install` with `plain agent install`
|
|
89
|
+
- Replace `plain skills` (without flags) with `plain agent skills`
|
|
90
|
+
- Run `plain agent install` to set up the new SessionStart hook in your project's `.claude/` or `.codex/` directory
|
|
91
|
+
|
|
92
|
+
## [0.99.0](https://github.com/dropseed/plain/releases/plain@0.99.0) (2026-01-15)
|
|
93
|
+
|
|
94
|
+
### What's changed
|
|
95
|
+
|
|
96
|
+
- Added `plain.utils.dotenv` module with `load_dotenv()` and `parse_dotenv()` functions for bash-compatible `.env` file parsing, supporting variable expansion, command substitution, multiline values, and escape sequences ([a9b2dc3e16](https://github.com/dropseed/plain/commit/a9b2dc3e16))
|
|
97
|
+
|
|
98
|
+
### Upgrade instructions
|
|
99
|
+
|
|
100
|
+
- No changes required
|
|
101
|
+
|
|
102
|
+
## [0.98.1](https://github.com/dropseed/plain/releases/plain@0.98.1) (2026-01-13)
|
|
103
|
+
|
|
104
|
+
### What's changed
|
|
105
|
+
|
|
106
|
+
- Fixed `INSTALLED_PACKAGES` not being optional in user settings, restoring the default empty list behavior ([820773c473](https://github.com/dropseed/plain/commit/820773c473))
|
|
107
|
+
|
|
108
|
+
### Upgrade instructions
|
|
109
|
+
|
|
110
|
+
- No changes required
|
|
111
|
+
|
|
112
|
+
## [0.98.0](https://github.com/dropseed/plain/releases/plain@0.98.0) (2026-01-13)
|
|
113
|
+
|
|
114
|
+
### What's changed
|
|
115
|
+
|
|
116
|
+
- The `plain skills --install` command now removes orphaned skills from destination directories when skills are renamed or removed from packages ([d51294ace1](https://github.com/dropseed/plain/commit/d51294ace1))
|
|
117
|
+
- Added README documentation for `plain.skills` with available skills and installation instructions ([7c90fc8595](https://github.com/dropseed/plain/commit/7c90fc8595))
|
|
118
|
+
|
|
119
|
+
### Upgrade instructions
|
|
120
|
+
|
|
121
|
+
- No changes required
|
|
122
|
+
|
|
123
|
+
## [0.97.0](https://github.com/dropseed/plain/releases/plain@0.97.0) (2026-01-13)
|
|
124
|
+
|
|
125
|
+
### What's changed
|
|
126
|
+
|
|
127
|
+
- HTTP exceptions (`NotFoundError404`, `ForbiddenError403`, `BadRequestError400`, and `SuspiciousOperationError400` variants) moved from `plain.exceptions` to `plain.http.exceptions` and are now exported from `plain.http` ([b61f909e29](https://github.com/dropseed/plain/commit/b61f909e29))
|
|
128
|
+
|
|
129
|
+
### Upgrade instructions
|
|
130
|
+
|
|
131
|
+
- Update imports of HTTP exceptions from `plain.exceptions` to `plain.http`:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
# Before
|
|
135
|
+
from plain.exceptions import NotFoundError404, ForbiddenError403, BadRequestError400
|
|
136
|
+
|
|
137
|
+
# After
|
|
138
|
+
from plain.http import NotFoundError404, ForbiddenError403, BadRequestError400
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## [0.96.0](https://github.com/dropseed/plain/releases/plain@0.96.0) (2026-01-13)
|
|
142
|
+
|
|
143
|
+
### What's changed
|
|
144
|
+
|
|
145
|
+
- Response classes renamed for consistency: `ResponseRedirect` → `RedirectResponse`, `ResponseNotModified` → `NotModifiedResponse`, `ResponseNotAllowed` → `NotAllowedResponse` ([fad5bf28b0](https://github.com/dropseed/plain/commit/fad5bf28b0))
|
|
146
|
+
- Redundant response classes removed: `ResponseNotFound`, `ResponseForbidden`, `ResponseBadRequest`, `ResponseGone`, `ResponseServerError` - use `Response(status_code=X)` instead ([fad5bf28b0](https://github.com/dropseed/plain/commit/fad5bf28b0))
|
|
147
|
+
- HTTP exceptions renamed to include status code suffix: `Http404` → `NotFoundError404`, `PermissionDenied` → `ForbiddenError403`, `BadRequest` → `BadRequestError400`, `SuspiciousOperation` → `SuspiciousOperationError400` ([5a1f020f52](https://github.com/dropseed/plain/commit/5a1f020f52))
|
|
148
|
+
- Added `Secret[T]` type annotation for masking sensitive settings like `SECRET_KEY` in CLI output ([8713dc08b0](https://github.com/dropseed/plain/commit/8713dc08b0))
|
|
149
|
+
- Added `ENV_SETTINGS_PREFIXES` setting to configure which environment variable prefixes are checked for settings (defaults to `["PLAIN_"]`) ([8713dc08b0](https://github.com/dropseed/plain/commit/8713dc08b0))
|
|
150
|
+
- New `plain settings list` and `plain settings get` CLI commands for viewing settings with their sources ([8713dc08b0](https://github.com/dropseed/plain/commit/8713dc08b0))
|
|
151
|
+
- Added preflight check for unused environment variables matching configured prefixes ([8713dc08b0](https://github.com/dropseed/plain/commit/8713dc08b0))
|
|
152
|
+
- Renamed `request.meta` to `request.environ` for clarity ([786b95bef8](https://github.com/dropseed/plain/commit/786b95bef8))
|
|
153
|
+
- Added `request.query_string` and `request.content_length` properties ([786b95bef8](https://github.com/dropseed/plain/commit/786b95bef8), [76dfd477d2](https://github.com/dropseed/plain/commit/76dfd477d2))
|
|
154
|
+
- Renamed X-Forwarded settings: `USE_X_FORWARDED_HOST` → `HTTP_X_FORWARDED_HOST`, `USE_X_FORWARDED_PORT` → `HTTP_X_FORWARDED_PORT`, `USE_X_FORWARDED_FOR` → `HTTP_X_FORWARDED_FOR` ([22f241a55c](https://github.com/dropseed/plain/commit/22f241a55c))
|
|
155
|
+
- Changed `HTTPS_PROXY_HEADER` from a tuple to a string format (e.g., `"X-Forwarded-Proto: https"`) ([7ac2a431b6](https://github.com/dropseed/plain/commit/7ac2a431b6))
|
|
156
|
+
|
|
157
|
+
### Upgrade instructions
|
|
158
|
+
|
|
159
|
+
- Replace Response class imports and usages:
|
|
160
|
+
- `ResponseRedirect` → `RedirectResponse`
|
|
161
|
+
- `ResponseNotModified` → `NotModifiedResponse`
|
|
162
|
+
- `ResponseNotAllowed` → `NotAllowedResponse`
|
|
163
|
+
- `ResponseNotFound` → `Response(status_code=404)`
|
|
164
|
+
- `ResponseForbidden` → `Response(status_code=403)`
|
|
165
|
+
- `ResponseBadRequest` → `Response(status_code=400)`
|
|
166
|
+
- `ResponseGone` → `Response(status_code=410)`
|
|
167
|
+
- `ResponseServerError` → `Response(status_code=500)`
|
|
168
|
+
- Replace exception imports and usages:
|
|
169
|
+
- `Http404` → `NotFoundError404`
|
|
170
|
+
- `PermissionDenied` → `ForbiddenError403`
|
|
171
|
+
- `BadRequest` → `BadRequestError400`
|
|
172
|
+
- `SuspiciousOperation` → `SuspiciousOperationError400`
|
|
173
|
+
- `SuspiciousMultipartForm` → `SuspiciousMultipartFormError400`
|
|
174
|
+
- `SuspiciousFileOperation` → `SuspiciousFileOperationError400`
|
|
175
|
+
- `TooManyFieldsSent` → `TooManyFieldsSentError400`
|
|
176
|
+
- `TooManyFilesSent` → `TooManyFilesSentError400`
|
|
177
|
+
- `RequestDataTooBig` → `RequestDataTooBigError400`
|
|
178
|
+
- Replace `request.meta` with `request.environ`
|
|
179
|
+
- Rename X-Forwarded settings in your configuration:
|
|
180
|
+
- `USE_X_FORWARDED_HOST` → `HTTP_X_FORWARDED_HOST`
|
|
181
|
+
- `USE_X_FORWARDED_PORT` → `HTTP_X_FORWARDED_PORT`
|
|
182
|
+
- `USE_X_FORWARDED_FOR` → `HTTP_X_FORWARDED_FOR`
|
|
183
|
+
- Update `HTTPS_PROXY_HEADER` from tuple format to string format:
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
# Before
|
|
187
|
+
HTTPS_PROXY_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
|
188
|
+
|
|
189
|
+
# After
|
|
190
|
+
HTTPS_PROXY_HEADER = "X-Forwarded-Proto: https"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
- Replace `plain setting <name>` command with `plain settings get <name>`
|
|
194
|
+
|
|
195
|
+
## [0.95.0](https://github.com/dropseed/plain/releases/plain@0.95.0) (2025-12-22)
|
|
196
|
+
|
|
197
|
+
### What's changed
|
|
198
|
+
|
|
199
|
+
- Improved thread worker server shutdown behavior with `cancel_futures=True` for faster and cleaner process termination ([72d0620](https://github.com/dropseed/plain/commit/72d0620094))
|
|
200
|
+
|
|
201
|
+
### Upgrade instructions
|
|
202
|
+
|
|
203
|
+
- No changes required
|
|
204
|
+
|
|
205
|
+
## [0.94.0](https://github.com/dropseed/plain/releases/plain@0.94.0) (2025-12-12)
|
|
206
|
+
|
|
207
|
+
### What's changed
|
|
208
|
+
|
|
209
|
+
- `FormFieldMissingError` exceptions are now automatically converted to HTTP 400 Bad Request responses with a warning log instead of causing a 500 error ([b38f6e5](https://github.com/dropseed/plain/commit/b38f6e50db))
|
|
210
|
+
|
|
211
|
+
### Upgrade instructions
|
|
212
|
+
|
|
213
|
+
- No changes required
|
|
214
|
+
|
|
215
|
+
## [0.93.1](https://github.com/dropseed/plain/releases/plain@0.93.1) (2025-12-09)
|
|
216
|
+
|
|
217
|
+
### What's changed
|
|
218
|
+
|
|
219
|
+
- Added type annotation for `request.unique_id` attribute to improve IDE support and type checking ([23af501](https://github.com/dropseed/plain/commit/23af501d09))
|
|
220
|
+
|
|
221
|
+
### Upgrade instructions
|
|
222
|
+
|
|
223
|
+
- No changes required
|
|
224
|
+
|
|
225
|
+
## [0.93.0](https://github.com/dropseed/plain/releases/plain@0.93.0) (2025-12-04)
|
|
226
|
+
|
|
227
|
+
### What's changed
|
|
228
|
+
|
|
229
|
+
- Improved type annotations across forms, HTTP handling, logging, and other core modules for better IDE support and type checking ([ac1eeb0](https://github.com/dropseed/plain/commit/ac1eeb0ea0))
|
|
230
|
+
- Internal refactor of `TimestampSigner` to use composition instead of inheritance from `Signer`, maintaining the same public API ([ac1eeb0](https://github.com/dropseed/plain/commit/ac1eeb0ea0))
|
|
231
|
+
|
|
232
|
+
### Upgrade instructions
|
|
233
|
+
|
|
234
|
+
- No changes required
|
|
235
|
+
|
|
236
|
+
## [0.92.0](https://github.com/dropseed/plain/releases/plain@0.92.0) (2025-12-01)
|
|
237
|
+
|
|
238
|
+
### What's changed
|
|
239
|
+
|
|
240
|
+
- Added `request.client_ip` property to get the client's IP address, with support for `X-Forwarded-For` header when behind a trusted proxy ([cb0bc5d](https://github.com/dropseed/plain/commit/cb0bc5d08f))
|
|
241
|
+
- Added `USE_X_FORWARDED_FOR` setting to enable reading client IP from `X-Forwarded-For` header ([cb0bc5d](https://github.com/dropseed/plain/commit/cb0bc5d08f))
|
|
242
|
+
- Improved `print_event` CLI output styling with dimmed text for less visual noise ([b09edfd](https://github.com/dropseed/plain/commit/b09edfd2a1))
|
|
243
|
+
|
|
244
|
+
### Upgrade instructions
|
|
245
|
+
|
|
246
|
+
- No changes required
|
|
247
|
+
|
|
248
|
+
## [0.91.0](https://github.com/dropseed/plain/releases/plain@0.91.0) (2025-11-24)
|
|
249
|
+
|
|
250
|
+
### What's changed
|
|
251
|
+
|
|
252
|
+
- Request body parsing refactored: the `request.data` attribute has been replaced with `request.json_data` and `request.form_data` for explicit content-type handling ([90332a9](https://github.com/dropseed/plain/commit/90332a9c21))
|
|
253
|
+
- `QueryDict` now has proper type annotations for `get()`, `pop()`, `getlist()`, and `__getitem__()` methods that reflect string return types ([90332a9](https://github.com/dropseed/plain/commit/90332a9c21))
|
|
254
|
+
- Forms now automatically select between `json_data` and `form_data` based on request content-type ([90332a9](https://github.com/dropseed/plain/commit/90332a9c21))
|
|
255
|
+
- View mixins `ObjectTemplateViewMixin` removed in favor of class inheritance for better typing - `UpdateView` and `DeleteView` now inherit from `DetailView` ([569afd6](https://github.com/dropseed/plain/commit/569afd606d))
|
|
256
|
+
- `AppLogger` context logging now uses a `context` dict parameter instead of `**kwargs` for better type checking ([581b406](https://github.com/dropseed/plain/commit/581b4060d3))
|
|
257
|
+
- Removed erroneous `AuthViewMixin` export from `plain.views` ([334bbb6](https://github.com/dropseed/plain/commit/334bbb6e7a))
|
|
258
|
+
|
|
259
|
+
### Upgrade instructions
|
|
260
|
+
|
|
261
|
+
- Replace `request.data` with the appropriate method:
|
|
262
|
+
- For JSON requests: use `request.json_data` (returns a dict, raises `BadRequest` for invalid JSON)
|
|
263
|
+
- For form data: use `request.form_data` (returns a `QueryDict`)
|
|
264
|
+
- Update `app_logger` calls that pass context as kwargs to use the `context` parameter:
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
# Before
|
|
268
|
+
app_logger.info("Message", user_id=123, action="login")
|
|
269
|
+
|
|
270
|
+
# After
|
|
271
|
+
app_logger.info("Message", context={"user_id": 123, "action": "login"})
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## [0.90.0](https://github.com/dropseed/plain/releases/plain@0.90.0) (2025-11-20)
|
|
275
|
+
|
|
276
|
+
### What's changed
|
|
277
|
+
|
|
278
|
+
- Improved type annotations in `timezone.py`: `is_aware()` and `is_naive()` now accept both `datetime` and `time` objects for more flexible type checking ([a43145e](https://github.com/dropseed/plain/commit/a43145e697))
|
|
279
|
+
- Enhanced type annotations in view classes: `convert_value_to_response()` and handler result variables now use more explicit type hints for better IDE support ([dc4454e](https://github.com/dropseed/plain/commit/dc4454e196))
|
|
280
|
+
- Fixed type errors in forms and server workers: URL field now handles bytes properly, and worker wait_fds has explicit type annotation ([fc98d66](https://github.com/dropseed/plain/commit/fc98d666d4))
|
|
281
|
+
|
|
282
|
+
### Upgrade instructions
|
|
283
|
+
|
|
284
|
+
- No changes required
|
|
285
|
+
|
|
286
|
+
## [0.89.0](https://github.com/dropseed/plain/releases/plain@0.89.0) (2025-11-14)
|
|
287
|
+
|
|
288
|
+
### What's changed
|
|
289
|
+
|
|
290
|
+
- Improved type annotations in view classes: `url_args`, `url_kwargs`, and various template/form context dictionaries now have more specific type hints for better IDE support and type checking ([83bcb95](https://github.com/dropseed/plain/commit/83bcb95b09))
|
|
291
|
+
|
|
292
|
+
### Upgrade instructions
|
|
293
|
+
|
|
294
|
+
- No changes required
|
|
295
|
+
|
|
296
|
+
## [0.88.0](https://github.com/dropseed/plain/releases/plain@0.88.0) (2025-11-13)
|
|
297
|
+
|
|
298
|
+
### What's changed
|
|
299
|
+
|
|
300
|
+
- The `plain.forms` module now uses explicit imports instead of wildcard imports, improving IDE autocomplete and type checking support ([eff36f3](https://github.com/dropseed/plain/commit/eff36f31e8e15f84e11164a44c833aeab096ffbd))
|
|
301
|
+
|
|
302
|
+
### Upgrade instructions
|
|
303
|
+
|
|
304
|
+
- No changes required
|
|
305
|
+
|
|
306
|
+
## [0.87.0](https://github.com/dropseed/plain/releases/plain@0.87.0) (2025-11-12)
|
|
307
|
+
|
|
308
|
+
### What's changed
|
|
309
|
+
|
|
310
|
+
- Internal classes now use abstract base classes with `@abstractmethod` decorators instead of raising `NotImplementedError`, improving type checking and IDE support ([91b329a](https://github.com/dropseed/plain/commit/91b329a8adb477031c4358e638b12f35f19bb85d), [81b5f88](https://github.com/dropseed/plain/commit/81b5f88a4bd39785f6b19c3c00c0ed23a36fb72f), [d2e2423](https://github.com/dropseed/plain/commit/d2e24235f497a92f45d5a21fc83d802897c2dec0), [61e7b5a](https://github.com/dropseed/plain/commit/61e7b5a0c8675aaaf65f0a626ff7959a786dca7f))
|
|
311
|
+
- Updated to latest version of `ty` type checker and fixed type errors and warnings throughout the codebase ([f4dbcef](https://github.com/dropseed/plain/commit/f4dbcefa929058be517cb1d4ab35bd73a89f26b8))
|
|
312
|
+
|
|
313
|
+
### Upgrade instructions
|
|
314
|
+
|
|
315
|
+
- No changes required
|
|
316
|
+
|
|
317
|
+
## [0.86.2](https://github.com/dropseed/plain/releases/plain@0.86.2) (2025-11-11)
|
|
318
|
+
|
|
319
|
+
### What's changed
|
|
320
|
+
|
|
321
|
+
- CLI color output is now enabled in CI environments by checking the `CI` environment variable, matching the behavior of modern tools like uv ([a1500f15ed](https://github.com/dropseed/plain/commit/a1500f15ed))
|
|
322
|
+
|
|
323
|
+
### Upgrade instructions
|
|
324
|
+
|
|
325
|
+
- No changes required
|
|
326
|
+
|
|
327
|
+
## [0.86.1](https://github.com/dropseed/plain/releases/plain@0.86.1) (2025-11-10)
|
|
328
|
+
|
|
329
|
+
### What's changed
|
|
330
|
+
|
|
331
|
+
- The `plain preflight` command now outputs to stderr only when using `--format json`, keeping stdout clean for JSON parsing while avoiding success messages appearing in error logs for text format ([72ebee7729](https://github.com/dropseed/plain/commit/72ebee7729))
|
|
332
|
+
- CLI color handling now follows the CLICOLOR standard with proper priority: `NO_COLOR` > `CLICOLOR_FORCE`/`FORCE_COLOR` > `CLICOLOR` > `isatty` ([c7fea406c5](https://github.com/dropseed/plain/commit/c7fea406c5))
|
|
333
|
+
|
|
334
|
+
### Upgrade instructions
|
|
335
|
+
|
|
336
|
+
- No changes required
|
|
337
|
+
|
|
338
|
+
## [0.86.0](https://github.com/dropseed/plain/releases/plain@0.86.0) (2025-11-10)
|
|
339
|
+
|
|
340
|
+
### What's changed
|
|
341
|
+
|
|
342
|
+
- Log output is now split by severity level: INFO and below go to stdout, WARNING and above go to stderr for proper cloud platform log classification ([52403b15ba](https://github.com/dropseed/plain/commit/52403b15ba))
|
|
343
|
+
- Added `LOG_STREAM` setting to customize log output behavior with options: `"split"` (default), `"stdout"`, or `"stderr"` ([52403b15ba](https://github.com/dropseed/plain/commit/52403b15ba))
|
|
344
|
+
- Log configuration documentation expanded with detailed guidance on output streams and environment variable settings ([52403b15ba](https://github.com/dropseed/plain/commit/52403b15ba))
|
|
345
|
+
|
|
346
|
+
### Upgrade instructions
|
|
347
|
+
|
|
348
|
+
- No changes required (default behavior splits logs to stdout/stderr automatically, but this can be customized via `PLAIN_LOG_STREAM` environment variable if needed)
|
|
349
|
+
|
|
350
|
+
## [0.85.0](https://github.com/dropseed/plain/releases/plain@0.85.0) (2025-11-03)
|
|
351
|
+
|
|
352
|
+
### What's changed
|
|
353
|
+
|
|
354
|
+
- CLI help output now organizes commands into "Common Commands", "Core Commands", and "Package Commands" sections for better discoverability ([73d3a48](https://github.com/dropseed/plain/commit/73d3a48fca))
|
|
355
|
+
- CLI help output has been customized with improved formatting and shortcut indicators showing which commands are shortcuts (e.g., `migrate → models migrate`) ([db882e6](https://github.com/dropseed/plain/commit/db882e6d47))
|
|
356
|
+
- CSRF exception messages now include more detailed context about what was rejected and why (e.g., port mismatches, host mismatches) ([9a8e09c](https://github.com/dropseed/plain/commit/9a8e09c1dc))
|
|
357
|
+
- The `plain agent md` command now saves a combined `AGENTS.md` file to `.plain/` by default when using `plain dev`, making it easier to provide context to coding agents ([786b7a0](https://github.com/dropseed/plain/commit/786b7a0ca1))
|
|
358
|
+
- CLI help text styling has been refined with dimmed descriptions and usage prefixes for improved readability ([d7f7053](https://github.com/dropseed/plain/commit/d7f705398d))
|
|
359
|
+
|
|
360
|
+
### Upgrade instructions
|
|
361
|
+
|
|
362
|
+
- No changes required
|
|
363
|
+
|
|
364
|
+
## [0.84.1](https://github.com/dropseed/plain/releases/plain@0.84.1) (2025-10-31)
|
|
365
|
+
|
|
366
|
+
### What's changed
|
|
367
|
+
|
|
368
|
+
- Added `license = "BSD-3-Clause"` to package metadata in `pyproject.toml` ([8477355](https://github.com/dropseed/plain/commit/8477355e65))
|
|
369
|
+
|
|
370
|
+
### Upgrade instructions
|
|
371
|
+
|
|
372
|
+
- No changes required
|
|
373
|
+
|
|
374
|
+
## [0.84.0](https://github.com/dropseed/plain/releases/plain@0.84.0) (2025-10-29)
|
|
375
|
+
|
|
376
|
+
### What's changed
|
|
377
|
+
|
|
378
|
+
- The `DEFAULT_RESPONSE_HEADERS` setting now supports format string placeholders (e.g., `{request.csp_nonce}`) for dynamic header values instead of requiring a callable function ([5199383128](https://github.com/dropseed/plain/commit/5199383128))
|
|
379
|
+
- Views can now set headers to `None` to explicitly remove default response headers ([5199383128](https://github.com/dropseed/plain/commit/5199383128))
|
|
380
|
+
- Added comprehensive documentation for customizing default response headers including override, remove, and extend patterns ([5199383128](https://github.com/dropseed/plain/commit/5199383128))
|
|
381
|
+
|
|
382
|
+
### Upgrade instructions
|
|
383
|
+
|
|
384
|
+
- If you have `DEFAULT_RESPONSE_HEADERS` configured as a callable function, convert it to a dictionary with format string placeholders:
|
|
385
|
+
|
|
386
|
+
```python
|
|
387
|
+
# Before:
|
|
388
|
+
def DEFAULT_RESPONSE_HEADERS(request):
|
|
389
|
+
nonce = request.csp_nonce
|
|
390
|
+
return {
|
|
391
|
+
"Content-Security-Policy": f"script-src 'self' 'nonce-{nonce}'",
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
# After:
|
|
395
|
+
DEFAULT_RESPONSE_HEADERS = {
|
|
396
|
+
"Content-Security-Policy": "script-src 'self' 'nonce-{request.csp_nonce}'",
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
- If you were overriding default headers to empty strings (`""`) to remove them, change those to `None` instead
|
|
401
|
+
|
|
402
|
+
## [0.83.0](https://github.com/dropseed/plain/releases/plain@0.83.0) (2025-10-29)
|
|
403
|
+
|
|
404
|
+
### What's changed
|
|
405
|
+
|
|
406
|
+
- Added comprehensive Content Security Policy (CSP) documentation explaining how to use nonces with inline scripts and styles ([784f3dd972](https://github.com/dropseed/plain/commit/784f3dd972))
|
|
407
|
+
- The `json_script` utility function now accepts an optional `nonce` parameter for CSP-compliant inline JSON scripts ([784f3dd972](https://github.com/dropseed/plain/commit/784f3dd972))
|
|
408
|
+
|
|
409
|
+
### Upgrade instructions
|
|
410
|
+
|
|
411
|
+
- Any `|json_script` usages need to make sure the second argument is a nonce, not a custom encoder (which is now third)
|
|
412
|
+
|
|
413
|
+
## [0.82.0](https://github.com/dropseed/plain/releases/plain@0.82.0) (2025-10-29)
|
|
414
|
+
|
|
415
|
+
### What's changed
|
|
416
|
+
|
|
417
|
+
- The `DEFAULT_RESPONSE_HEADERS` setting can now be a callable that accepts a request argument, enabling dynamic header generation per request ([cb92905834](https://github.com/dropseed/plain/commit/cb92905834))
|
|
418
|
+
- Added `request.csp_nonce` cached property for generating Content Security Policy nonces ([75071dcc70](https://github.com/dropseed/plain/commit/75071dcc70))
|
|
419
|
+
- Simplified the preflight command by moving `plain preflight check` back to `plain preflight` ([40c2c4560e](https://github.com/dropseed/plain/commit/40c2c4560e))
|
|
420
|
+
|
|
421
|
+
### Upgrade instructions
|
|
422
|
+
|
|
423
|
+
- If you use `plain preflight check`, update to `plain preflight` (the `check` subcommand has been removed for simplicity)
|
|
424
|
+
- If you use `plain preflight check --deploy`, update to `plain preflight --deploy`
|
|
425
|
+
|
|
426
|
+
## [0.81.0](https://github.com/dropseed/plain/releases/plain@0.81.0) (2025-10-22)
|
|
427
|
+
|
|
428
|
+
### What's changed
|
|
429
|
+
|
|
430
|
+
- Removed support for category-specific error template fallbacks like `4xx.html` and `5xx.html` ([9513f7c4fa](https://github.com/dropseed/plain/commit/9513f7c4fa))
|
|
431
|
+
|
|
432
|
+
### Upgrade instructions
|
|
433
|
+
|
|
434
|
+
- If you have `4xx.html` or `5xx.html` error templates, rename them to specific status code templates (e.g., `404.html`, `500.html`) or remove them if you prefer the plain HTTP response fallback
|
|
435
|
+
|
|
436
|
+
## [0.80.0](https://github.com/dropseed/plain/releases/plain@0.80.0) (2025-10-22)
|
|
437
|
+
|
|
438
|
+
### What's changed
|
|
439
|
+
|
|
440
|
+
- CSRF failures now raise `SuspiciousOperation` (HTTP 400) instead of `PermissionDenied` (HTTP 403) ([ad146bde3e](https://github.com/dropseed/plain/commit/ad146bde3e))
|
|
441
|
+
- Error templates can now use category-specific fallbacks like `4xx.html` or `5xx.html` instead of the generic `error.html` ([716cfa3cfc](https://github.com/dropseed/plain/commit/716cfa3cfc))
|
|
442
|
+
- Updated error template documentation with best practices for self-contained `500.html` templates ([55cea3b522](https://github.com/dropseed/plain/commit/55cea3b522))
|
|
443
|
+
|
|
444
|
+
### Upgrade instructions
|
|
445
|
+
|
|
446
|
+
- If you have a `templates/error.html` template, instead create specific error templates for each status code you want to customize (e.g., `400.html`, `403.html`, `404.html`, `500.html`). You can also create category-specific templates like `4xx.html` or `5xx.html` for broader coverage.
|
|
447
|
+
|
|
448
|
+
## [0.79.0](https://github.com/dropseed/plain/releases/plain@0.79.0) (2025-10-22)
|
|
449
|
+
|
|
450
|
+
### What's changed
|
|
451
|
+
|
|
452
|
+
- Response objects now have an `exception` attribute that stores the exception that caused 5xx errors ([0a243ba89c](https://github.com/dropseed/plain/commit/0a243ba89c))
|
|
453
|
+
- Middleware classes now use an abstract base class `HttpMiddleware` with a `process_request()` method ([b960eed6c6](https://github.com/dropseed/plain/commit/b960eed6c6))
|
|
454
|
+
- CSRF middleware now raises `PermissionDenied` instead of rendering a custom `CsrfFailureView` ([d4b93e59b3](https://github.com/dropseed/plain/commit/d4b93e59b3))
|
|
455
|
+
- The `HTTP_ERROR_VIEWS` setting has been removed ([7a4e3a31f4](https://github.com/dropseed/plain/commit/7a4e3a31f4))
|
|
456
|
+
- Standalone `plain-changelog` and `plain-upgrade` executables have been removed in favor of the built-in commands ([07c3a4c540](https://github.com/dropseed/plain/commit/07c3a4c540))
|
|
457
|
+
- Standalone `plain-build` executable has been removed ([99301ea797](https://github.com/dropseed/plain/commit/99301ea797))
|
|
458
|
+
- Removed automatic logging of all HTTP 400+ status codes for cleaner logs ([c2769d7281](https://github.com/dropseed/plain/commit/c2769d7281))
|
|
459
|
+
|
|
460
|
+
### Upgrade instructions
|
|
461
|
+
|
|
462
|
+
- If you have custom middleware, inherit from `HttpMiddleware` and rename your `__call__()` method to `process_request()`:
|
|
463
|
+
|
|
464
|
+
```python
|
|
465
|
+
# Before:
|
|
466
|
+
class MyMiddleware:
|
|
467
|
+
def __init__(self, get_response):
|
|
468
|
+
self.get_response = get_response
|
|
469
|
+
|
|
470
|
+
def __call__(self, request):
|
|
471
|
+
response = self.get_response(request)
|
|
472
|
+
return response
|
|
473
|
+
|
|
474
|
+
# After:
|
|
475
|
+
from plain.http import HttpMiddleware
|
|
476
|
+
|
|
477
|
+
class MyMiddleware(HttpMiddleware):
|
|
478
|
+
def process_request(self, request):
|
|
479
|
+
response = self.get_response(request)
|
|
480
|
+
return response
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
- Remove any custom `HTTP_ERROR_VIEWS` setting from your configuration - error views are now controlled entirely by exception handlers
|
|
484
|
+
- If you were calling `plain-changelog` or `plain-upgrade` as standalone commands, use `plain changelog` or `plain upgrade` instead
|
|
485
|
+
- If you were calling `plain-build` as a standalone command, use `plain build` instead
|
|
486
|
+
|
|
487
|
+
## [0.78.2](https://github.com/dropseed/plain/releases/plain@0.78.2) (2025-10-20)
|
|
488
|
+
|
|
489
|
+
### What's changed
|
|
490
|
+
|
|
491
|
+
- Updated package metadata to use `[dependency-groups]` instead of `[tool.uv]` for development dependencies, following PEP 735 standard ([1b43a3a272](https://github.com/dropseed/plain/commit/1b43a3a272))
|
|
492
|
+
|
|
493
|
+
### Upgrade instructions
|
|
494
|
+
|
|
495
|
+
- No changes required
|
|
496
|
+
|
|
497
|
+
## [0.78.1](https://github.com/dropseed/plain/releases/plain@0.78.1) (2025-10-17)
|
|
498
|
+
|
|
499
|
+
### What's changed
|
|
500
|
+
|
|
501
|
+
- Fixed job worker logging by using `getLogger` instead of directly instantiating `Logger` for the plain logger ([dd675666b9](https://github.com/dropseed/plain/commit/dd675666b9))
|
|
502
|
+
|
|
503
|
+
### Upgrade instructions
|
|
504
|
+
|
|
505
|
+
- No changes required
|
|
506
|
+
|
|
507
|
+
## [0.78.0](https://github.com/dropseed/plain/releases/plain@0.78.0) (2025-10-17)
|
|
508
|
+
|
|
509
|
+
### What's changed
|
|
510
|
+
|
|
511
|
+
- Chores have been refactored to use abstract base classes instead of decorated functions ([c4466d3c60](https://github.com/dropseed/plain/commit/c4466d3c60))
|
|
512
|
+
- Added `SHELL_IMPORT` setting to customize what gets automatically imported in `plain shell` ([9055f59c08](https://github.com/dropseed/plain/commit/9055f59c08))
|
|
513
|
+
- Views that return `None` now raise `Http404` instead of returning `ResponseNotFound` ([5bb60016eb](https://github.com/dropseed/plain/commit/5bb60016eb))
|
|
514
|
+
- The `plain chores list` command output formatting now matches the `plain jobs list` format ([4b6881a49e](https://github.com/dropseed/plain/commit/4b6881a49e))
|
|
515
|
+
|
|
516
|
+
### Upgrade instructions
|
|
517
|
+
|
|
518
|
+
- Update any chores from decorated functions to class-based chores:
|
|
519
|
+
|
|
520
|
+
```python
|
|
521
|
+
# Before:
|
|
522
|
+
@register_chore("group")
|
|
523
|
+
def chore_name():
|
|
524
|
+
"""Description"""
|
|
525
|
+
return "Done!"
|
|
526
|
+
|
|
527
|
+
# After:
|
|
528
|
+
from plain.chores import Chore, register_chore
|
|
529
|
+
|
|
530
|
+
@register_chore
|
|
531
|
+
class ChoreName(Chore):
|
|
532
|
+
"""Description"""
|
|
533
|
+
|
|
534
|
+
def run(self):
|
|
535
|
+
return "Done!"
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
- Import `Chore` base class from `plain.chores` when creating new chores
|
|
539
|
+
|
|
540
|
+
## [0.77.0](https://github.com/dropseed/plain/releases/plain@0.77.0) (2025-10-13)
|
|
541
|
+
|
|
542
|
+
### What's changed
|
|
543
|
+
|
|
544
|
+
- The `plain server --reload` now uses `watchfiles` for improved cross-platform file watching ([92e95c5032](https://github.com/dropseed/plain/commit/92e95c5032))
|
|
545
|
+
- Server reloader now watches `.env*` files for changes and triggers automatic reload ([92e95c5032](https://github.com/dropseed/plain/commit/92e95c5032))
|
|
546
|
+
- HTML template additions and deletions now trigger automatic server reload when using `--reload` ([f2f31c288b](https://github.com/dropseed/plain/commit/f2f31c288b))
|
|
547
|
+
- Internal server worker type renamed from "gthread" to "thread" for clarity ([6470748e91](https://github.com/dropseed/plain/commit/6470748e91))
|
|
548
|
+
|
|
549
|
+
### Upgrade instructions
|
|
550
|
+
|
|
551
|
+
- No changes required
|
|
552
|
+
|
|
553
|
+
## [0.76.0](https://github.com/dropseed/plain/releases/plain@0.76.0) (2025-10-12)
|
|
554
|
+
|
|
555
|
+
### What's changed
|
|
556
|
+
|
|
557
|
+
- Added new `plain server` command with built-in WSGI server (vendored gunicorn) ([f9dc2867c7](https://github.com/dropseed/plain/commit/f9dc2867c7))
|
|
558
|
+
- The `plain server` command supports `WEB_CONCURRENCY` environment variable for worker processes ([0c3e8c6f32](https://github.com/dropseed/plain/commit/0c3e8c6f32))
|
|
559
|
+
- Simplified server startup logging to use a single consolidated log line ([b1405b71f0](https://github.com/dropseed/plain/commit/b1405b71f0))
|
|
560
|
+
- Removed `gunicorn` as an external dependency - server functionality is now built into plain core ([cb6c2f484d](https://github.com/dropseed/plain/commit/cb6c2f484d))
|
|
561
|
+
- Internal server environment variables renamed from `GUNICORN_*` to `PLAIN_SERVER_*` ([745c073123](https://github.com/dropseed/plain/commit/745c073123))
|
|
562
|
+
- Removed unused server features including hooks, syslog, proxy protocol, user/group dropping, and config file loading ([be0f82d92b](https://github.com/dropseed/plain/commit/be0f82d92b), [10c206875b](https://github.com/dropseed/plain/commit/10c206875b), [ecf327014c](https://github.com/dropseed/plain/commit/ecf327014c), [fb5a10f50b](https://github.com/dropseed/plain/commit/fb5a10f50b))
|
|
563
|
+
|
|
564
|
+
### Upgrade instructions
|
|
565
|
+
|
|
566
|
+
- Replace any direct usage of `gunicorn` with the new `plain server` command (ex. `gunicorn plain.wsgi:app --workers 4` becomes `plain server --workers 4`)
|
|
567
|
+
- Update any deployment scripts or Procfiles that use `gunicorn` to use `plain server` instead
|
|
568
|
+
- Remove `gunicorn` from your project dependencies if you added it separately (it's now built into plain)
|
|
569
|
+
- For Heroku deployments, the `$PORT` is not automatically detected - update your Procfile to `web: plain server --bind 0.0.0.0:$PORT`
|
|
570
|
+
- If you were using gunicorn configuration files, migrate the settings to `plain server` command-line options (run `plain server --help` to see available options)
|
|
571
|
+
|
|
572
|
+
## [0.75.0](https://github.com/dropseed/plain/releases/plain@0.75.0) (2025-10-10)
|
|
573
|
+
|
|
574
|
+
### What's changed
|
|
575
|
+
|
|
576
|
+
- Documentation references updated from `plain-worker` to `plain-jobs` following the package rename ([24219856e0](https://github.com/dropseed/plain/commit/24219856e0))
|
|
577
|
+
|
|
578
|
+
### Upgrade instructions
|
|
579
|
+
|
|
580
|
+
- No changes required
|
|
581
|
+
|
|
582
|
+
## [0.74.0](https://github.com/dropseed/plain/releases/plain@0.74.0) (2025-10-08)
|
|
583
|
+
|
|
584
|
+
### What's changed
|
|
585
|
+
|
|
586
|
+
- The `plain agent request` command now displays request ID in the response output ([4a20cfa3fc](https://github.com/dropseed/plain/commit/4a20cfa3fc))
|
|
587
|
+
- Request headers are now included in OpenTelemetry tracing baggage for improved observability ([08a3376d06](https://github.com/dropseed/plain/commit/08a3376d06))
|
|
588
|
+
|
|
589
|
+
### Upgrade instructions
|
|
590
|
+
|
|
591
|
+
- No changes required
|
|
592
|
+
|
|
593
|
+
## [0.73.0](https://github.com/dropseed/plain/releases/plain@0.73.0) (2025-10-07)
|
|
594
|
+
|
|
595
|
+
### What's changed
|
|
596
|
+
|
|
597
|
+
- Internal preflight result handling updated to use `model_options` instead of `_meta` for model label retrieval ([73ba469](https://github.com/dropseed/plain/commit/73ba469ba0))
|
|
598
|
+
|
|
599
|
+
### Upgrade instructions
|
|
600
|
+
|
|
601
|
+
- No changes required
|
|
602
|
+
|
|
603
|
+
## [0.72.2](https://github.com/dropseed/plain/releases/plain@0.72.2) (2025-10-06)
|
|
604
|
+
|
|
605
|
+
### What's changed
|
|
606
|
+
|
|
607
|
+
- Improved type annotations for test client responses with new `ClientResponse` wrapper class ([369353f9d6](https://github.com/dropseed/plain/commit/369353f9d6))
|
|
608
|
+
- Enhanced internal type checking for WSGI handler and request/response types ([50463b00c3](https://github.com/dropseed/plain/commit/50463b00c3))
|
|
609
|
+
|
|
610
|
+
### Upgrade instructions
|
|
611
|
+
|
|
612
|
+
- No changes required
|
|
613
|
+
|
|
614
|
+
## [0.72.1](https://github.com/dropseed/plain/releases/plain@0.72.1) (2025-10-02)
|
|
615
|
+
|
|
616
|
+
### What's changed
|
|
617
|
+
|
|
618
|
+
- 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))
|
|
619
|
+
|
|
620
|
+
### Upgrade instructions
|
|
621
|
+
|
|
622
|
+
- No changes required
|
|
623
|
+
|
|
624
|
+
## [0.72.0](https://github.com/dropseed/plain/releases/plain@0.72.0) (2025-10-02)
|
|
625
|
+
|
|
626
|
+
### What's changed
|
|
627
|
+
|
|
628
|
+
- Request attributes `user` and `session` are no longer set directly on the request object ([154ee10](https://github.com/dropseed/plain/commit/154ee10375))
|
|
629
|
+
- 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))
|
|
630
|
+
- Removed `plain.auth.middleware.AuthenticationMiddleware` from default middleware configuration ([154ee10](https://github.com/dropseed/plain/commit/154ee10375))
|
|
631
|
+
|
|
632
|
+
### Upgrade instructions
|
|
633
|
+
|
|
634
|
+
- No changes required
|
|
635
|
+
|
|
636
|
+
## [0.71.0](https://github.com/dropseed/plain/releases/plain@0.71.0) (2025-09-30)
|
|
637
|
+
|
|
638
|
+
### What's changed
|
|
639
|
+
|
|
640
|
+
- Renamed `HttpRequest` to `Request` throughout the codebase for consistency and simplicity ([cd46ff20](https://github.com/dropseed/plain/commit/cd46ff2003))
|
|
641
|
+
- Renamed `HttpHeaders` to `RequestHeaders` for naming consistency ([cd46ff20](https://github.com/dropseed/plain/commit/cd46ff2003))
|
|
642
|
+
- Renamed settings: `APP_NAME` → `NAME`, `APP_VERSION` → `VERSION`, `APP_LOG_LEVEL` → `LOG_LEVEL`, `APP_LOG_FORMAT` → `LOG_FORMAT`, `PLAIN_LOG_LEVEL` → `FRAMEWORK_LOG_LEVEL` ([4c5f2166](https://github.com/dropseed/plain/commit/4c5f2166c1))
|
|
643
|
+
- Added `request.get_preferred_type()` method to select the most preferred media type from Accept header ([b105ba4d](https://github.com/dropseed/plain/commit/b105ba4dd0))
|
|
644
|
+
- Moved helper functions in `http/request.py` to be static methods of `QueryDict` ([0e1b0133](https://github.com/dropseed/plain/commit/0e1b0133c5))
|
|
645
|
+
|
|
646
|
+
### Upgrade instructions
|
|
647
|
+
|
|
648
|
+
- Replace all imports and usage of `HttpRequest` with `Request`
|
|
649
|
+
- Replace all imports and usage of `HttpHeaders` with `RequestHeaders`
|
|
650
|
+
- Update any custom settings that reference `APP_NAME` to `NAME`, `APP_VERSION` to `VERSION`, `APP_LOG_LEVEL` to `LOG_LEVEL`, `APP_LOG_FORMAT` to `LOG_FORMAT`, and `PLAIN_LOG_LEVEL` to `FRAMEWORK_LOG_LEVEL`
|
|
651
|
+
- Configuring these settings via the `PLAIN_` prefixed environment variable will need to be updated accordingly
|
|
652
|
+
|
|
653
|
+
## [0.70.0](https://github.com/dropseed/plain/releases/plain@0.70.0) (2025-09-30)
|
|
654
|
+
|
|
655
|
+
### What's changed
|
|
656
|
+
|
|
657
|
+
- Added comprehensive type annotations throughout the codebase for improved IDE support and type checking ([365414c](https://github.com/dropseed/plain/commit/365414cc6f))
|
|
658
|
+
- The `Asset` class in `plain.assets.finders` is now a module-level public class instead of being defined inside `iter_assets()` ([6321765](https://github.com/dropseed/plain/commit/6321765d30))
|
|
659
|
+
|
|
660
|
+
### Upgrade instructions
|
|
661
|
+
|
|
662
|
+
- No changes required
|
|
663
|
+
|
|
664
|
+
## [0.69.0](https://github.com/dropseed/plain/releases/plain@0.69.0) (2025-09-29)
|
|
665
|
+
|
|
666
|
+
### What's changed
|
|
667
|
+
|
|
668
|
+
- Model-related exceptions (`FieldDoesNotExist`, `FieldError`, `ObjectDoesNotExist`, `MultipleObjectsReturned`, `EmptyResultSet`, `FullResultSet`) moved from `plain.exceptions` to `plain.models.exceptions` ([1c02564](https://github.com/dropseed/plain/commit/1c02564561))
|
|
669
|
+
- Added `plain dev` alias prompt that suggests adding `p` as a shell alias for convenience ([d913b44](https://github.com/dropseed/plain/commit/d913b44fab))
|
|
670
|
+
|
|
671
|
+
### Upgrade instructions
|
|
672
|
+
|
|
673
|
+
- Replace imports of `FieldDoesNotExist`, `FieldError`, `ObjectDoesNotExist`, `MultipleObjectsReturned`, `EmptyResultSet`, or `FullResultSet` from `plain.exceptions` to `plain.models.exceptions`
|
|
674
|
+
- If you're using `ObjectDoesNotExist` in views, update your import from `plain.exceptions.ObjectDoesNotExist` to `plain.models.exceptions.ObjectDoesNotExist`
|
|
675
|
+
|
|
676
|
+
## [0.68.1](https://github.com/dropseed/plain/releases/plain@0.68.1) (2025-09-25)
|
|
677
|
+
|
|
678
|
+
### What's changed
|
|
679
|
+
|
|
680
|
+
- Preflight checks are now sorted by name for consistent ordering ([cb8e160](https://github.com/dropseed/plain/commit/cb8e160934))
|
|
681
|
+
|
|
682
|
+
### Upgrade instructions
|
|
683
|
+
|
|
684
|
+
- No changes required
|
|
685
|
+
|
|
3
686
|
## [0.68.0](https://github.com/dropseed/plain/releases/plain@0.68.0) (2025-09-25)
|
|
4
687
|
|
|
5
688
|
### What's changed
|
|
@@ -11,7 +694,7 @@
|
|
|
11
694
|
|
|
12
695
|
### Upgrade instructions
|
|
13
696
|
|
|
14
|
-
-
|
|
697
|
+
- Update any uses of the `plain preflight` command to `plain preflight check`, and remove the `--database` and `--fail-level` options which no longer exist
|
|
15
698
|
- Custom preflight checks should be class based, extending `PreflightCheck` and implementing the `run()` method
|
|
16
699
|
- Preflight checks need to be registered with a custom name (ex. `@register_check("app.my_custom_check")`) and optionally with `deploy=True` if it should run in only in deploy mode
|
|
17
700
|
- Preflight results should use `PreflightResult` (optionally with `warning=True`) instead of `preflight.Warning` or `preflight.Error`
|