Python Multipart
python-multipart is an Apache2-licensed streaming multipart parser for Python. It is designed for handling `multipart/form-data` POST requests, typically used in web servers for file uploads and complex form data. The library is actively maintained with frequent releases, currently at version 0.0.22, and supports modern Python versions (>=3.10).
Warnings
- breaking The import name was changed from `multipart` to `python_multipart` in version 0.0.13. Direct imports using `import multipart` will no longer work and may lead to `ModuleNotFoundError` or unexpected behavior if another `multipart` package is installed. Versions 0.0.13 and 0.0.14 were temporarily yanked due to breakage related to this change.
- breaking Support for Python 3.8 and 3.9 was dropped in version 0.0.21. The library now requires Python 3.10 or newer.
- gotcha A separate, unrelated package on PyPI is also named `multipart`. Installing `pip install multipart` instead of `pip install python-multipart` will install the wrong library, leading to `ModuleNotFoundError` if `from python_multipart import ...` is used, or unexpected behavior if `import multipart` is still in your code.
- gotcha In version 0.0.22, the `File` object produced by the parser will no longer include directory paths in its `filename` attribute. It will only contain the base filename.
- gotcha Version 0.0.18 introduced a 'hard break' if data is found after the last boundary in `MultipartParser`. This means the parser will now strictly enforce the end of the multipart body, potentially raising errors for malformed requests that previously might have been partially processed.
- deprecated In version 0.0.15, `FutureWarning` messages were replaced with `PendingDeprecationWarning`. While not a breaking change, it indicates that certain behaviors or features are slated for deprecation or removal in future major releases.
Install
-
pip install python-multipart
Imports
- MultipartParser
from python_multipart import MultipartParser
Quickstart
import io
from python_multipart import MultipartParser
# Simulate an HTTP request body with multipart/form-data
boundary = b"----WebKitFormBoundary7MA4YWxkTrZu0gW"
body_data = (
b"--" + boundary + b"\r\n"
b'Content-Disposition: form-data; name="username"\r\n'
b'\r\n'
b'testuser\r\n'
b"--" + boundary + b"\r\n"
b'Content-Disposition: form-data; name="upload_file"; filename="hello.txt"\r\n'
b'Content-Type: text/plain\r\n'
b'\r\n'
b'Hello, World!\nThis is a test file.\r\n'
b"--" + boundary + b"--\r\n"
)
# Simulate HTTP headers
headers = {
"Content-Type": f"multipart/form-data; boundary={boundary.decode()}",
"Content-Length": str(len(body_data)),
}
# Use BytesIO to simulate a file-like object for the body stream
body_stream = io.BytesIO(body_data)
# Create a parser instance
parser = MultipartParser(headers)
# Iterate through parts and process them
print("Parsing multipart data:")
for part in parser.parse(body_stream):
if hasattr(part, 'field_name'): # It's a form field
print(f" Field: name={part.field_name.decode()}, value={part.value.decode()}")
elif hasattr(part, 'file_name'): # It's an uploaded file
print(f" File: name={part.field_name.decode()}, filename={part.file_name.decode()}, content_type={part.content_type.decode()}")
file_content = part.value # The file content is available as bytes
print(f" File content length: {len(file_content)} bytes")
# In a real application, you would typically save or process file_content
print("\nParsing complete.")