datasette/datasette/utils
Simon Willison 40a37307de
Add request.form() for multipart form data and file uploads
* Add request.form() for multipart form data and file uploads

New Request.form() method that handles both application/x-www-form-urlencoded
and multipart/form-data content types with streaming parsing.

Features:
- Streaming multipart parser that doesn't buffer entire body in memory
- Files spill to disk above 1MB threshold via SpooledTemporaryFile
- files=False (default) discards file content, files=True stores them
- Security limits: max_request_size, max_file_size, max_fields, max_files
- FormData container with dict-like access and getlist() for multiple values
- UploadedFile class with async read(), seek(), filename, content_type, size
- Support for RFC 5987 filename* encoding for international filenames

Uses multipart-form-data-conformance test suite for validation.

* Update views to use request.form() and document new API

- Migrate PermissionsDebugView, MessagesDebugView, and CreateTokenView
  from post_vars() to form()
- Add documentation for request.form(), FormData, and UploadedFile classes

Centralize multipart defaults and expose stricter limits via Request.form().

Enforce header, part, file, and disk space limits even when files are discarded; detect truncated bodies and client disconnects; and move blocking work off the event loop.

Add FormData close/aclose context managers, update internals docs, and expand multipart tests (including len semantics and stricter conformance expectations).
2026-01-28 18:41:03 -08:00
..
__init__.py Workaround for intermittent test failure on SQLite 3.25.3 2026-01-28 18:34:00 -08:00
actions_sql.py datasette.client.get(..., skip_permission_checks=True) 2025-11-05 13:38:01 -08:00
asgi.py Add request.form() for multipart form data and file uploads 2026-01-28 18:41:03 -08:00
baseconv.py Rename to_decimal/from_decimal to decode/encode, refs #1734 2022-05-02 12:44:09 -07:00
check_callable.py Fix for asyncio.iscoroutinefunction deprecation warnings 2025-10-08 20:32:16 -07:00
internal_db.py Better fix for stale catalog_databases, closes #2606 2025-12-02 19:00:13 -08:00
multipart.py Add request.form() for multipart form data and file uploads 2026-01-28 18:41:03 -08:00
permissions.py datasette.client.get(..., skip_permission_checks=True) 2025-11-05 13:38:01 -08:00
shutil_backport.py Upgrade to latest Black, closes #2239 2024-01-30 19:55:26 -08:00
sqlite.py Show pysqlite3 version on /-/versions, if installed - #1125 2020-12-03 14:08:50 -08:00
testing.py Fixed bug with ?_trace=1 and large responses, closes #2404 2024-08-21 10:58:17 -07:00