Skip to content

Commit

Permalink
docs: Update readme examples and changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
defnull committed Oct 28, 2024
1 parent 379d8fa commit 28edd69
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 28 deletions.
14 changes: 13 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,19 @@ and may break applications that rely on *incorrect* or *undefined* behavior.
Release 1.2
===========

Not released yet.
This release improves error handling and adds new functionality. API changes are
backwards compatible.

* feat: New `is_form_request(environ)` helper.
* feat: Split up `MultipartError`` into more specific exceptions and added HTTP
status code info to each one. All exceptions are subclasses of `MultipartError`.
* feat: Added `parse_form_data(ignore_errors)` parameter to throw exceptions in
non-strict mode, or suppress exceptions in strict mode. Default behavior does
not change.
* fix: `parse_form_data` no longer checks the request method and `is_form_request`
also ignores it. All methods can carry parse-able form data, including unknown
methods. The only reliable way is to check the `Content-Type` header, which
both functions do.

Release 1.1
===========
Expand Down
52 changes: 25 additions & 27 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ low-level for framework authors and high-level for WSGI application developers:
* ``PushMultipartParser``: A low-level incremental `SansIO <https://sans-io.readthedocs.io/>`_
(non-blocking) parser suitable for asyncio and other time or memory constrained
environments.
* ``MultipartParser``: A streaming parser emitting memory- and disk-buffered
* ``MultipartParser``: A streaming parser emitting memory- or disk-buffered
``MultipartPart`` instances.
* ``parse_form_data``: A helper function to parse both ``multipart/form-data``
and ``application/x-www-form-urlencoded`` form submissions from a
`WSGI <https://peps.python.org/pep-3333/>`_ environment.
* ``parse_form_data`` and ``is_form_request``: Helper functions for
`WSGI <https://peps.python.org/pep-3333/>`_ applications with support for
``multipart/form-data`` as well as ``application/x-www-form-urlencoded`` form
submission requests.


Installation
Expand Down Expand Up @@ -70,14 +71,14 @@ instances in return, one for text fields and the other for file uploads:

.. code-block:: python
from multipart import parse_form_data
from multipart import parse_form_data, is_form_request
def wsgi(environ, start_response):
if environ["REQUEST_METHOD"] == "POST":
if is_form_request(environ):
forms, files = parse_form_data(environ)
title = forms["title"] # string
upload = files["upload"] # MultipartPart
title = forms["title"] # type: string
upload = files["upload"] # type: MultipartPart
upload.save_as(...)
Note that form fields that are too large to fit into memory will end up as
Expand Down Expand Up @@ -129,25 +130,22 @@ allows you to process ``MultipartPart`` instances as soon as they arrive:
from multipart import parse_options_header, MultipartParser
def wsgi(environ, start_response):
assert environ["REQUEST_METHOD"] == "POST"
content_type = environ["CONTENT_TYPE"]
content_type, content_params = parse_options_header(content_type)
assert content_type == "multipart/form-data"
stream = environ["wsgi.input"]
boundary = content_params.get("boundary")
charset = content_params.get("charset", "utf8")
parser = MultipartParser(stream, boundary, charset)
for part in parser:
if part.filename:
print(f"{part.name}: File upload ({part.size} bytes)")
part.save_as(...)
elif part.size < 1024:
print(f"{part.name}: Text field ({part.value!r})")
else:
print(f"{part.name}: Test field, but too big to print :/")
content_type, params = parse_options_header(environ["CONTENT_TYPE"])
if content_type == "multipart/form-data":
stream = environ["wsgi.input"]
boundary = params["boundary"]
charset = params.get("charset", "utf8")
parser = MultipartParser(stream, boundary, charset)
for part in parser:
if part.filename:
print(f"{part.name}: File upload ({part.size} bytes)")
part.save_as(...)
elif part.size < 1024:
print(f"{part.name}: Text field ({part.value!r})")
else:
print(f"{part.name}: Test field, but too big to print :/")
Non-blocking parser: ``PushMultipartParser``
Expand Down

0 comments on commit 28edd69

Please sign in to comment.