patx/micropie
update readthedocs.io docs for latest release 0.26. update readme with table of contents.
Commit 14bbaa4 · patx · 2026-02-12T01:17:40-05:00
Comments
No comments yet.
Diff
diff --git a/README.md b/README.md
index 7af932b..3eb3e40 100644
--- a/README.md
+++ b/README.md
@@ -30,33 +30,46 @@
### Latest Release Notes
View the latest release notes [here](https://github.com/patx/micropie/blob/main/docs/release_notes.md). It is useful to check release notes each time a new version of MicroPie is published. Any breaking changes (rare, but do happen) also appear here.
+### **Table of Contents**
+- [Installing MicroPie](#installing-micropie)
+- [Getting Started](#getting-started)
+- [Core Features](#core-features)
+- [Learn by Examples](#learn-by-examples)
+- [Comparisons](#comparisons)
+- [Benchmark Results](#benchmark-results)
+- [Suggestions or Feedback?](#suggestions-or-feedback)
+
+### **Documentation Roadmap**
+- **Tutorials**: [quick start](https://micropie.readthedocs.io/en/latest/tutorial/quickstart.html), [routing](https://micropie.readthedocs.io/en/latest/tutorial/routing.html), and [websockets](https://micropie.readthedocs.io/en/latest/tutorial/websockets.html).
+- **How-to Guides**: Practical recipes for [sessions](https://micropie.readthedocs.io/en/latest/howto/sessions.html), [middleware](https://micropie.readthedocs.io/en/latest/howto/middleware.html), [streaming](https://micropie.readthedocs.io/en/latest/howto/streaming.html), and more.
+- **Reference**: Full API docs for [App](https://micropie.readthedocs.io/en/latest/reference/app.html), [Request](https://micropie.readthedocs.io/en/latest/reference/request.html), [WebSocket](https://micropie.readthedocs.io/en/latest/reference/websocket.html), and related classes.
+- **What’s New**: Version-by-version highlights at [What's new in MicroPie](https://micropie.readthedocs.io/en/latest/whats_new.html).
+
## **Installing MicroPie**
-### **Installation**
-Install MicroPie with **standard** optional dependencies via pip:
-```bash
-pip install micropie[standard]
-```
-This will install MicroPie along with `jinja2` for template rendering and `multipart` for parsing multipart form data.
+### **Installation Profiles**
+Install whichever profile fits your use case:
-If you would like to install **all** optional dependencies (everything from `standard` plus `orjson` and `uvicorn`) you can run:
-```bash
-pip install micropie[all]
-```
+| Profile | Command | Includes |
+|---------|---------|----------|
+| Minimal | `pip install micropie` | Core framework only |
+| Standard | `pip install micropie[standard]` | Core + `jinja2` + `multipart` |
+| All | `pip install micropie[all]` | Standard + `orjson` + `uvicorn` |
-### **Minimal Setup**
-You can also install MicroPie without ANY dependencies via pip:
+If you are just getting started, use **standard**:
```bash
-pip install micropie
+pip install micropie[standard]
```
-For an ultra-minimalistic approach, download the standalone script (development version):
+
+For an ultra-minimal setup, you can also use the standalone script (development version):
[micropie.py](https://raw.githubusercontent.com/patx/micropie/refs/heads/main/micropie.py)
-Place it in your project directory, and you are good to go. Note that `jinja2` must be installed separately to use the `_render_template` method and/or `multipart` for handling file data (the `_parse_multipart` method), but this *is* optional and you can use MicroPie without them. To install the optional dependencies use:
+Place it in your project directory and you are ready to go. Install optional packages only if needed:
```bash
pip install jinja2 multipart
```
+Use `jinja2` for `_render_template` and `multipart` for multipart file/form parsing.
By default MicroPie will use the `json` library from Python's standard library. If you need faster performance you can use `orjson`. MicroPie *will* use `orjson` *if installed* by default. If it is not installed, MicroPie will fallback to `json`. This means with or without `orjson` installed MicroPie will still handle JSON requests/responses the same. To install `orjson` and take advantage of its performance, use:
```bash
diff --git a/docs/README.md b/docs/README.md
index fa0a620..977908a 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,30 +1,41 @@
[](https://patx.github.io/micropie)
-[MicroPie](https://patx.github.io/micropie) is an ultra-micro ASGI Python web framework that gets out of your way,
-letting you build fast and dynamic web apps with ease. Inspired by CherryPy and
-licensed under the BSD three-clause license.
+[MicroPie](https://patx.github.io/micropie) is an ultra-micro ASGI Python web framework for building fast, async web apps with minimal boilerplate. It includes convention-based routing, sessions, middleware, WebSocket support, lifespan hooks, and optional template rendering.
-### MicroPie is Fun
+## Quick Start
```python
-from MicroPie import App
+from micropie import App
class MyApp(App):
-
async def index(self):
- return "Hello World!"
+ return "Hello, MicroPie!"
app = MyApp() # Run with `uvicorn app:app`
```
-### And Easy to Install
+Run:
+
+```bash
+uvicorn app:app
+```
+
+## Installation
+
```bash
-$ pip install micropie[all]
+$ pip install micropie[standard]
```
-### Useful Links
+Other profiles:
+
+```bash
+$ pip install micropie # minimal
+$ pip install micropie[all] # standard + orjson + uvicorn
+```
+
+## Useful Links
- **Homepage**: [patx.github.io/micropie](https://patx.github.io/micropie)
- **Official Documentation**: [micropie.readthedocs.io](https://micropie.readthedocs.io/)
- **PyPI Page**: [pypi.org/project/MicroPie](https://pypi.org/project/MicroPie/)
- **GitHub Project**: [github.com/patx/micropie](https://github.com/patx/micropie)
-
+- **Examples**: [github.com/patx/micropie/tree/main/examples](https://github.com/patx/micropie/tree/main/examples)
diff --git a/docs/apidocs/conf.py b/docs/apidocs/conf.py
index a8d0f78..fbb4517 100644
--- a/docs/apidocs/conf.py
+++ b/docs/apidocs/conf.py
@@ -2,7 +2,7 @@
project = "MicroPie"
author = "Harrison Erd"
-release = "0.20"
+release = "0.26"
extensions = [
"sphinx.ext.autodoc",
diff --git a/docs/apidocs/explanation/architecture.rst b/docs/apidocs/explanation/architecture.rst
index 349b725..d75982a 100644
--- a/docs/apidocs/explanation/architecture.rst
+++ b/docs/apidocs/explanation/architecture.rst
@@ -79,7 +79,7 @@ Lifespan hooks
ASGI defines a lifespan protocol for startup and shutdown events. MicroPie
exposes ``startup_handlers`` and ``shutdown_handlers`` lists on the
:class:`~micropie.App` instance. Handlers are executed sequentially and
-may be synchronous or asynchronous. Use them to open database connections,
+should be asynchronous callables. Use them to open database connections,
prime caches or register background tasks. Lifespan functions run before
any request or WebSocket traffic is accepted, ensuring your dependencies
are ready.
@@ -88,7 +88,7 @@ Templating and JSON helpers
---------------------------
If :mod:`jinja2` is installed, MicroPie enables the
-:func:`~micropie.App.render_template` helper to render templates from a
+:meth:`~micropie.App._render_template` helper to render templates from a
``templates`` directory, returning HTML responses with the correct
``Content-Type``. For JSON, the framework prefers :mod:`orjson` when
available and gracefully falls back to :mod:`json`. This keeps the core
diff --git a/docs/apidocs/explanation/design_philosophy.rst b/docs/apidocs/explanation/design_philosophy.rst
index 03d1db3..18eaf72 100644
--- a/docs/apidocs/explanation/design_philosophy.rst
+++ b/docs/apidocs/explanation/design_philosophy.rst
@@ -77,4 +77,4 @@ Where to go next
in mind to see how they shape the developer experience.
* Browse ``tests.py`` to understand the expected behaviour of each hook.
* If you plan to extend MicroPie, read the
- :doc:`reference/index` to learn the public APIs you can rely on.
+ :doc:`../reference/index` to learn the public APIs you can rely on.
diff --git a/docs/apidocs/howto/middleware.rst b/docs/apidocs/howto/middleware.rst
index a815318..cb5dba0 100644
--- a/docs/apidocs/howto/middleware.rst
+++ b/docs/apidocs/howto/middleware.rst
@@ -85,9 +85,9 @@ Example:
app.ws_middlewares.append(RejectAnonymous())
Explicit routing and other patterns
-----------------------------------
+-----------------------------------
You can implement custom routing schemes by writing middleware that
parses the incoming path and sets ``request._route_handler`` or
``request._ws_route_handler`` accordingly. See the examples in the
-``examples/middleware`` directory for a complete implementation.
\ No newline at end of file
+``examples/middleware`` directory for a complete implementation.
diff --git a/docs/apidocs/howto/templates.rst b/docs/apidocs/howto/templates.rst
index 57b5176..0a17017 100644
--- a/docs/apidocs/howto/templates.rst
+++ b/docs/apidocs/howto/templates.rst
@@ -1,11 +1,13 @@
Rendering templates
-==================
+===================
MicroPie can render HTML templates using the Jinja2 template engine.
Templates allow you to separate presentation from code by placing
HTML in separate files. Template rendering is optional; you can use
MicroPie without Jinja2 installed, but the
-:meth:`~micropie.App._render_template` method will not be available.
+:meth:`~micropie.App._render_template` helper will return a
+``500 Internal Server Error: Jinja2 not installed.`` message unless
+Jinja2 is installed.
Installing Jinja2
-----------------
@@ -68,4 +70,4 @@ Template variables
You can pass arbitrary keyword arguments to `_render_template`. These
become variables in the Jinja2 template. For more information on
creating complex templates, including inheritance and control flow,
-refer to the `Jinja2 documentation <https://jinja.palletsprojects.com>`_.
\ No newline at end of file
+refer to the `Jinja2 documentation <https://jinja.palletsprojects.com>`_.
diff --git a/docs/apidocs/howto/testing.rst b/docs/apidocs/howto/testing.rst
index 4c95191..69df521 100644
--- a/docs/apidocs/howto/testing.rst
+++ b/docs/apidocs/howto/testing.rst
@@ -21,13 +21,11 @@ Unit testing handlers directly
Because handlers are regular functions, you can instantiate your
:class:`~micropie.App` subclass and call methods directly. Use the
-:func:`micropie.current_request` context variable to set up any request
+:data:`micropie.current_request` context variable to set up any request
state that your handler expects.
.. code-block:: python
- from contextvars import Token
-
from micropie import App, Request, current_request
class MyApp(App):
@@ -38,7 +36,7 @@ state that your handler expects.
app = MyApp()
scope = {"type": "http", "method": "GET", "path": "/"}
request = Request(scope)
- token: Token = current_request.set(request)
+ token = current_request.set(request)
try:
response = await app.greet()
finally:
@@ -69,7 +67,7 @@ asserts, but the structure works in ``unittest`` with
async def test_index_returns_json():
app = MyApp()
async with httpx.AsyncClient(transport=httpx.ASGITransport(app=app)) as client:
- response = await client.get("http://test/" )
+ response = await client.get("http://test/")
assert response.status_code == 200
assert response.json() == {"status": "ok"}
@@ -83,12 +81,17 @@ app instance before issuing requests.
.. code-block:: python
+ import httpx
+
from micropie import App, HttpMiddleware
class AddHeader(HttpMiddleware):
- async def after_request(self, request, response):
- response.setdefault("headers", []).append((b"x-test", b"1"))
- return response
+ async def before_request(self, request):
+ return None
+
+ async def after_request(self, request, status_code, response_body, extra_headers):
+ extra_headers.append(("X-Test", "1"))
+ return {"headers": extra_headers}
class MyApp(App):
async def index(self):
@@ -96,7 +99,7 @@ app instance before issuing requests.
async def test_middleware_header():
app = MyApp()
- app.middleware.append(AddHeader())
+ app.middlewares.append(AddHeader())
transport = httpx.ASGITransport(app=app)
async with httpx.AsyncClient(transport=transport) as client:
response = await client.get("http://test/")
@@ -108,7 +111,8 @@ Handling lifespan events
If your application registers startup or shutdown handlers, wrap your
ASGI client in a lifespan manager. ``httpx`` exposes
:class:`httpx.ASGITransport` with a ``lifespan="auto"`` mode that will
-run lifespan events before the first request and after the client exits.
+run lifespan events before the first request and after the client exits
+(on versions that support this option).
.. code-block:: python
diff --git a/docs/apidocs/reference/app.rst b/docs/apidocs/reference/app.rst
index 7fbad67..0fb883c 100644
--- a/docs/apidocs/reference/app.rst
+++ b/docs/apidocs/reference/app.rst
@@ -33,6 +33,11 @@ Attributes
A list of :class:`~micropie.WebSocketMiddleware` instances used for
WebSocket connections.
+.. attribute:: session_backend
+
+ The active :class:`~micropie.SessionBackend` instance used to load
+ and save session dictionaries for both HTTP and WebSocket flows.
+
.. attribute:: startup_handlers
A list of asynchronous callables that run during the ASGI
@@ -54,11 +59,11 @@ Methods
handlers based on ``scope['type']``. You normally do not call this
directly; the ASGI server calls it for you.
-.. method:: request
+.. attribute:: request
- Return the current :class:`~micropie.Request` object. This is
- stored in a context variable so that it is available throughout
- asynchronous callbacks.
+ The current :class:`~micropie.Request` (or
+ :class:`~micropie.WebSocketRequest`) stored in a context variable for
+ the active request lifecycle.
.. method:: _redirect(location, extra_headers=None)
@@ -75,4 +80,4 @@ Methods
Additionally, MicroPie defines several private helper methods such as
``_parse_cookies`` and ``_send_response``. These are considered
internal and not part of the public API. They may change without
-notice.
\ No newline at end of file
+notice.
diff --git a/docs/apidocs/reference/session.rst b/docs/apidocs/reference/session.rst
index 1804ae2..c3c3aa4 100644
--- a/docs/apidocs/reference/session.rst
+++ b/docs/apidocs/reference/session.rst
@@ -55,9 +55,9 @@ SESSION_TIMEOUT
.. data:: SESSION_TIMEOUT
The default session expiration time in seconds (eight hours). You
- can override this constant in your own code before importing
- MicroPie or by passing a different timeout when saving sessions in
- a custom back‑end.
+ can override this constant in your own code by assigning a new value
+ to ``micropie.SESSION_TIMEOUT`` or by using a custom back-end that
+ persists with a different timeout policy.
See also the :doc:`../howto/sessions` guide for examples of using and
-implementing session back‑ends.
\ No newline at end of file
+implementing session back‑ends.
diff --git a/docs/apidocs/reference/websocket.rst b/docs/apidocs/reference/websocket.rst
index 78b84a2..afee227 100644
--- a/docs/apidocs/reference/websocket.rst
+++ b/docs/apidocs/reference/websocket.rst
@@ -29,14 +29,15 @@ Methods
.. method:: receive_text()
Await a text message from the client. Returns a string. Raises
- :class:`~micropie.ConnectionClosed` if the client has disconnected or
- ``ValueError`` if a binary message is received.
+ :class:`~micropie.ConnectionClosed` if the client has disconnected.
+ If the client sends bytes, MicroPie decodes them as UTF-8 (ignoring
+ invalid sequences) and returns the decoded string.
.. method:: receive_bytes()
Await a binary message from the client. Returns bytes. Raises
- :class:`~micropie.ConnectionClosed` if the client has disconnected or
- ``ValueError`` if a text message is received.
+ :class:`~micropie.ConnectionClosed` if the client has disconnected.
+ If the client sends text, MicroPie returns the UTF-8 encoded bytes.
.. method:: send_text(data)
@@ -67,8 +68,6 @@ Attributes
Exceptions
----------
-.. class:: ConnectionClosed
-
- Raised by :meth:`receive_text` and :meth:`receive_bytes` when the
- client has closed the connection. Catch this exception in your
- handlers to perform cleanup after a disconnect.
\ No newline at end of file
+MicroPie raises :class:`~micropie.ConnectionClosed` from
+:meth:`receive_text` and :meth:`receive_bytes` when the client
+disconnects. See :doc:`exceptions` for exception details.
diff --git a/docs/apidocs/tutorial/quickstart.rst b/docs/apidocs/tutorial/quickstart.rst
index 9531525..0325272 100644
--- a/docs/apidocs/tutorial/quickstart.rst
+++ b/docs/apidocs/tutorial/quickstart.rst
@@ -26,8 +26,8 @@ install all optional extras:
$ pip install micropie[all]
-See :ref:`reference/session` for details about session back‑ends and
-the :ref:`howto/templates` guide for information on templates.
+See :doc:`../reference/session` for details about session back-ends and
+:doc:`../howto/templates` for information on templates.
Writing your first application
------------------------------
@@ -77,4 +77,4 @@ What’s next?
Now that you have a running MicroPie application, proceed to the
:doc:`routing <routing>` tutorial to learn how URL paths map to
-methods and how to pass parameters to your handlers.
\ No newline at end of file
+methods and how to pass parameters to your handlers.
diff --git a/docs/apidocs/tutorial/routing.rst b/docs/apidocs/tutorial/routing.rst
index d4a3be5..77418dd 100644
--- a/docs/apidocs/tutorial/routing.rst
+++ b/docs/apidocs/tutorial/routing.rst
@@ -22,7 +22,7 @@ Handlers may be synchronous or asynchronous functions. They return
either a string, bytes, a JSON‑serialisable object, a tuple of
``(status_code, body)`` or ``(status_code, body, headers)``, or an
iterator/generator for streaming responses. See
-:doc:`howto/streaming` for details on streaming.
+:doc:`../howto/streaming` for details on streaming.
Parameters and arguments
------------------------
@@ -57,7 +57,7 @@ sources in the following order:
argument in your handler signature to receive a file object.
5. **Session data** – Values stored in :attr:`~micropie.Request.session`
- fill remaining parameters. See :doc:`howto/sessions` for details.
+ fill remaining parameters. See :doc:`../howto/sessions` for details.
6. **Default values** – If no other source provides a value, default
values in your function signature are used.
@@ -96,8 +96,9 @@ The following examples illustrate common patterns:
"""
return f"Form submitted by: {username}"
-See :ref:`request-object` for the attributes available on the current
-request and :ref:`app-class` for details about the ``App`` class.
+See :ref:`Request objects <request-object>` for the attributes
+available on the current request and :ref:`App class <app-class>` for
+details about the ``App`` class.
HTTP methods and responses
--------------------------
@@ -122,5 +123,5 @@ Advanced routing
You can implement explicit routing, path prefixing or complex
dispatching by writing a custom :class:`~micropie.HttpMiddleware`. See
-the :doc:`howto/middleware` guide and the examples in the
-``examples/explicit_routing`` directory of the source distribution.
\ No newline at end of file
+the :doc:`../howto/middleware` guide and the examples in the
+``examples/explicit_routing`` directory of the source distribution.
diff --git a/docs/apidocs/tutorial/websockets.rst b/docs/apidocs/tutorial/websockets.rst
index e4197a2..74c5384 100644
--- a/docs/apidocs/tutorial/websockets.rst
+++ b/docs/apidocs/tutorial/websockets.rst
@@ -32,12 +32,11 @@ receives. When the client disconnects, the handler finishes.
.. code-block:: python
- from micropie import App
+ from micropie import App, ConnectionClosed
class MyApp(App):
async def ws_echo(self, ws):
- # Accept the connection; without this call, MicroPie will
- # automatically reject the WebSocket.
+ # Accept the connection before receiving or sending messages.
await ws.accept()
while True:
try:
@@ -72,8 +71,9 @@ example:
Connecting to ``ws://localhost:8000/greet/Alice`` sends back
``"Hello Alice!"``. Connecting to ``ws://localhost:8000/greet?name=Bob``
-sends ``"Hello Bob!"``. See :ref:`websocket-reference` for the
-complete API of the :class:`~micropie.WebSocket` class.
+sends ``"Hello Bob!"``. See :ref:`WebSocket class
+<websocket-reference>` for the complete API of the
+:class:`~micropie.WebSocket` class.
Integrating Socket.IO
---------------------
@@ -85,4 +85,4 @@ fallback transports such as polling—you can integrate
``examples/socketio`` directory in the MicroPie source distribution for
sample code and instructions. When integrating Socket.IO, you still
run your MicroPie application behind an ASGI server and attach the
-Socket.IO server as additional middleware or route.
\ No newline at end of file
+Socket.IO server as additional middleware or route.
diff --git a/docs/apidocs/whats_new.rst b/docs/apidocs/whats_new.rst
index 7001783..c36269a 100644
--- a/docs/apidocs/whats_new.rst
+++ b/docs/apidocs/whats_new.rst
@@ -11,6 +11,13 @@ releases, consult the `GitHub releases page <https://github.com/patx/micropie/re
Version highlights
------------------
+* **0.26** – Makes sub-application handoff independent of middleware
+ ordering, improving reliability for mounted ASGI apps.
+* **0.25** – Fixes Unicode redirect handling by percent-encoding
+ non-ASCII path segments before writing the ``Location`` header.
+* **0.24** – Improves session lifecycle behaviour by expiring stale
+ in-memory sessions and deleting persisted sessions when they become
+ empty.
* **0.23** – Ensures background multipart parsing stops immediately when a
request is terminated by middleware, preventing unnecessary resource
usage.
@@ -20,8 +27,8 @@ Version highlights
parameters, aligning it with other handlers.
* **0.20** – Introduces concurrent multipart parsing with bounded queues
so that large uploads do not block other requests.
-* **0.19** – Improves debugging via richer tracebacks and adds the
- ``_sub_app`` attribute for mounting other ASGI applications.
+* **0.19** – Improves debugging via richer tracebacks and adds
+ middleware hooks for mounting sub-applications.
* **0.18** – Cancels asynchronous generator handlers when the client
disconnects to avoid leaking resources during streaming responses.
* **0.17** – Updates the lifespan hook API to match middleware APIs,
@@ -44,12 +51,15 @@ Upgrade tips
* **Review lifespan handlers.** Releases 0.16 and 0.17 reshape the
startup/shutdown API. Adjust custom startup hooks to use the new
``app.startup_handlers`` and ``app.shutdown_handlers`` lists.
+* **Validate redirects with non-ASCII paths.** If your app builds
+ redirect targets dynamically, verify behaviour after 0.25 where
+ redirect paths are safely encoded for ASGI header transport.
* **Audit long-lived streams.** If you emit server-sent events or
streaming responses, ensure your handlers handle cancellation so the
0.18 change does not mask cleanup bugs.
* **Evaluate mounted applications.** If you mount other ASGI apps using
- middleware, upgrade to at least 0.19 to benefit from the ``_sub_app``
- attribute and the body parsing fixes introduced in 0.22.
+ middleware, upgrade to at least 0.22 for body parsing fixes and to
+ 0.26 for middleware-ordering-safe sub-application routing.
Looking for more?
-----------------