patx/micropie
Prepare 0.32 tagged release
Commit 0493dcd · patx · 2026-07-14T23:17:41-04:00
Comments
No comments yet.
Diff
diff --git a/docs/apidocs/tutorial/quickstart.rst b/docs/apidocs/tutorial/quickstart.rst
index 0325272..3a711b4 100644
--- a/docs/apidocs/tutorial/quickstart.rst
+++ b/docs/apidocs/tutorial/quickstart.rst
@@ -4,7 +4,7 @@ Quick start
This tutorial shows you how to install MicroPie and run a very simple
application. By the end you will be able to serve an HTTP
endpoint that returns plain text. This section assumes that you
-already have Python 3.8 or later installed.
+already have Python 3.11 or later installed.
Installation
------------
diff --git a/docs/apidocs/whats_new.rst b/docs/apidocs/whats_new.rst
index 4d0d3dd..08a0c0b 100644
--- a/docs/apidocs/whats_new.rst
+++ b/docs/apidocs/whats_new.rst
@@ -11,7 +11,7 @@ releases, consult the `GitHub releases page <https://github.com/patx/micropie/re
Version highlights
------------------
-* **Next release** – Adds request-body and multipart-field limits,
+* **0.32** – Adds request-body and multipart-field limits,
per-chunk timeouts for buffered and multipart bodies, deadlock-free
multi-file streaming, explicit multipart failure signaling, session
fixation protection, configurable session cookie/ID policies, isolated
@@ -64,21 +64,67 @@ Version highlights
* **0.13** – Introduces built-in WebSocket support, opening the door to
real-time applications without additional middleware.
+Breaking changes in 0.32
+------------------------
+
+Version 0.32 intentionally changes several public behaviours. Review each
+item before upgrading an existing application.
+
+* **Session values no longer bind to handler arguments.** This applies to
+ both HTTP and WebSocket handlers. A parameter such as ``user_id`` must
+ come from path, query, form, JSON or file input (as applicable), or have a
+ default. Read trusted state explicitly instead:
+
+ .. code-block:: python
+
+ async def transfer(self, amount):
+ user_id = self.request.session["user_id"]
+ return await make_transfer(user_id, amount)
+
+* **Request.form() no longer reads JSON bodies.** JSON objects are no longer
+ copied into ``Request.body_params``; code using ``request.form(...)`` for
+ JSON must move to ``request.json(...)``. Top-level JSON object keys still
+ bind to handler arguments, but values retain their native JSON types instead
+ of being converted with ``str()``. The namespace change also applies to
+ middleware and mounted sub-applications that inspect ``body_params``.
+
+* **Session IDs use UUIDv4 validation by default.** Existing non-UUID session
+ cookies are rejected, and non-UUID values passed to
+ ``WebSocket.accept(session_id=...)`` raise ``ValueError``. Custom session
+ back-ends must configure matching ``session_id_factory`` and
+ ``session_id_validator`` callables. Session IDs also rotate when an empty
+ session becomes populated, so clients must honor the returned
+ ``Set-Cookie`` header.
+
+* **Request-body limits are enabled by default.** Bodies larger than 16 MiB
+ receive ``413 Payload Too Large``. Each accumulated multipart text field
+ is additionally limited to 1 MiB. Pass larger values—or ``None`` to
+ disable a limit—through ``max_body_size`` and ``max_form_field_size`` when
+ larger payloads are intentional.
+
+* **Aborted multipart file streams raise an exception.** A file queue yields
+ ``None`` only after a complete upload. Parser failures, idle timeouts and
+ size-limit failures now raise :class:`~micropie.MultipartFileError` from
+ ``get()``. Upload consumers must treat that exception as an incomplete
+ file and avoid persisting partial data.
+
+* **Python 3.11 or newer is required.** Package metadata now declares the
+ framework's actual interpreter requirement, including its use of
+ ``asyncio.timeout``. Installers will reject older Python versions instead
+ of installing a package that cannot run correctly.
+
+* **Some error and middleware values are normalized.** JSON response bodies
+ passed to ``HttpMiddleware.after_request`` are now text regardless of
+ whether ``orjson`` is installed. Unhandled WebSocket handler exceptions
+ close with code ``1011`` and the generic reason ``Internal server error``;
+ exception details are available only through server logging.
+
Upgrade tips
------------
-* **Review request parsing compatibility.** Query strings and URL-encoded form
- bodies retain their earlier permissive behavior: empty and bare fields are
- omitted and malformed encoding is tolerated. JSON objects now retain native
- types and are no longer mirrored into ``body_params``; use ``Request.json()``
- rather than ``Request.form()`` for JSON payloads.
-* **Review custom session IDs.** Session cookies and explicit WebSocket IDs
- now require canonical UUIDv4 by default. Back-ends using signed or custom
- identifiers must configure matching ``session_id_factory`` and
- ``session_id_validator`` callables.
-* **Handle aborted file streams.** Multipart file queues now raise
- ``MultipartFileError`` when parsing fails instead of yielding a clean
- ``None`` sentinel for truncated content.
+* **URL-encoded parsing remains permissive.** Query strings and URL-encoded
+ form bodies retain their earlier behavior: empty and bare fields are omitted
+ and malformed encoding is tolerated.
* **Check optional extras.** When upgrading, confirm that any optional
dependencies you rely on (``jinja2``, ``multipart``, ``orjson``) are
still installed, especially if you pin minimal environments.
diff --git a/docs/release_notes.md b/docs/release_notes.md
index 4dc9de8..1b0bc6c 100644
--- a/docs/release_notes.md
+++ b/docs/release_notes.md
@@ -1,7 +1,14 @@
[](https://patx.github.io/micropie)
## Releases Notes
-- **Unreleased** - Harden request parsing, multipart streaming, sessions, parameter binding, logging, and response streaming. This release retains consistent permissive URL-encoded query and form parsing, and introduces native JSON binding without `body_params` mirroring, UUIDv4 session validation by default, configurable custom session-ID policies, request-body limits, and `MultipartFileError` for aborted uploads; review the upgrade notes before deploying.
+- **[0.32](https://github.com/patx/micropie/releases/tag/v0.32)** - Harden request parsing, multipart streaming, sessions, parameter binding, logging, and response streaming. URL-encoded query and form parsing remain permissive and compatible with earlier releases.
+ - **Breaking — session binding:** HTTP and WebSocket handler arguments are no longer populated from session data. Read trusted state explicitly from `self.request.session`.
+ - **Breaking — `Request.form()` and JSON:** `Request.form()` no longer returns values from JSON bodies because JSON objects are no longer mirrored into `body_params`. Use `request.json(...)` instead. Top-level JSON keys still bind to handler arguments, now with native JSON types.
+ - **Breaking — session IDs:** Session cookies and explicit `WebSocket.accept(session_id=...)` values use canonical UUIDv4 validation by default. Custom backends must configure matching `session_id_factory` and `session_id_validator` callables; otherwise existing non-UUID sessions are rejected.
+ - **Breaking — request limits:** Requests now default to a 16 MiB total body limit and multipart text fields to 1 MiB. Configure larger values or `None` when an application intentionally accepts more.
+ - **Breaking — multipart failures:** An aborted upload now raises `MultipartFileError` from the file queue instead of yielding a clean `None` sentinel. Treat `None` as successful EOF and handle the exception as an incomplete upload.
+ - **Breaking — Python requirement:** Package metadata now requires Python 3.11 or newer, matching the framework's use of Python 3.11 asyncio APIs. Older interpreters are no longer accepted by installers.
+ - **Integration changes:** JSON response bodies passed to HTTP middleware are consistently text even when `orjson` is installed, and unhandled WebSocket handler failures now use a generic `1011` close reason while logging details server-side.
- **[0.31](https://github.com/patx/micropie/releases/tag/v0.31)** - Security fix: route lookup now ignores non-callable public attributes and property-like descriptors, preventing internal App attributes from being treated as handlers while preserving descriptor-backed route methods.
- **[0.30](https://github.com/patx/micropie/releases/tag/v0.30)** - Remove the public `Request.get_json` attribute. Use `Request.json()` or `Request.json(name, default)`.
- **[0.29](https://github.com/patx/micropie/releases/tag/v0.29)** - Performance upgrades, no more per request signature inspections for routing. 24%-54% increase in req/sec.
diff --git a/pyproject.toml b/pyproject.toml
index 259fde1..1298152 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,6 +5,7 @@ build-backend = "flit_core.buildapi"
[project]
name = "micropie"
version = "0.32"
+requires-python = ">=3.11"
description = "An ultra micro ASGI web framework"
keywords = ["micropie", "asgi", "microframework", "http"]
readme = "docs/README.md"
@@ -17,6 +18,7 @@ classifiers = [
"Topic :: Internet :: WWW/HTTP :: WSGI",
"Topic :: Software Development :: Libraries :: Application Frameworks",
"Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3 :: Only",
"License :: OSI Approved :: BSD License",
"Intended Audience :: Developers",
"Operating System :: OS Independent",