I read that multipart and email.message are candidates for using for processing HTML forms. Neither one works for me. Can somebody point me to an example for how to process an HTML form without using cgi.FieldStorage.
import multipart
parser = multipart.MultipartParser()
data = parser.parse_form()
print( data['number'])
Error: MultipartParser.init() missing 2 required positional arguments: 'stream' and 'boundary',
import email.message
msg = email.message.Message()
data = msg.parse_args()
print( str(data))
Error: Message' object has no attribute 'parse_args'
Here's how I did it using only standard library imports:
import io
import email
def parse_multipart(headers, body):
parsed_body = {}
em = email.message_from_bytes(
b"\r\n".join(headers) + b"\r\n\r\n" + body)
for part in em.walk():
if not part.is_multipart():
data = part.get_payload(decode=True)
params = {}
for header_name in part:
for k, v in part.get_params(header=header_name)[1:]:
params[k] = v
if "name" not in params:
raise IOError("Bad body data")
if "filename" in params:
fp = io.BytesIO(data)
fp.filename = params["filename"]
parsed_body[params["name"]] = fp
else:
parsed_body[params["name"]] = data
return parsed_body
You can then use it like this:
# notice headers is a list of byte strings
headers = [
b"Content-Type: multipart/form-data; boundary=340fd0"
]
# notice body is a byte string
body = b"\r\n".join([
b"--340fd0",
b"Content-Disposition: form-data; name=\"foo\"",
b"",
b"value-foo",
b"--340fd0",
b"Content-Disposition: form-data; name=\"baz\"",
b"",
b"value-baz",
b"--340fd0",
b"Content-Disposition: form-data; name=\"file\"; filename=\"filename.txt\"",
b"",
b"this is a text file to upload",
b"--340fd0--",
])
parsed_body = parse_multipart(headers, body)
print(len(parsed_body)) # 3
print(parsed_body["foo"]) # b'value-foo'
print(type(parsed_body["foo"])) # <class 'bytes'>
print(parsed_body["file"].filename) # filename.txt
print(parsed_body["file"].read()) # b'this is a text file to upload'
It wasn't as straightforward to parse the body as I was expecting it to be but hopefully this points someone in the right direction in the future.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With