# Using email module as a replacement for CGI?

**URL:** <https://discuss.python.org/t/using-email-module-as-a-replacement-for-cgi/26430>\
**Category:** Documentation\
**Created:** [May 2, 2023, 9:54pm UTC](https://discuss.python.org/t/using-email-module-as-a-replacement-for-cgi/26430 "2023-05-02T21:54:00Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![James\_E](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/james_e/32/12337_2.png) [@James\_E](https://discuss.python.org/u/James_E)\
**Post date:** [May 2, 2023, 9:54pm UTC](https://discuss.python.org/t/using-email-module-as-a-replacement-for-cgi/26430/1 "2023-05-02T21:54:00Z")

</div>

The deprecation documentation for the CGI module currently recommends two paths forward when it comes to parsing POST request bodies going forward:

- 3rd-party library `multipart`
- Standard-library `email.message`

I’m wondering if the latter is really appropriate to recommend, given how non-obvious and non-trivial the implementation of that seems to actually be.

I’d like to propose either removing that bit of phrasing (that suggests `email` be used) to avoid throwing new programmers into a tarpit, or adding a HOWTO page targeting the average person googling “python cgi deprecated how to parse file form upload 2023”.

* * *

Porting this over from elsewhere—

> [@Alternative function for deprecated cgi](https://discuss.python.org/t/alternative-function-for-deprecated-cgi/21960/9):
>
> I spent a few hours trying to go from the CGI module documentation’s vague exhortation “maybe you can use the `email` module somehow” to the multi-kilobyte shim I shared earlier. It took a lot of experimentation, a lot of creative labor, and I’m still not sure I did it right. If my code’s correct, I’d be happy to contribute a HOWTO page with a cleaned-up version of it to direct other CGI deprecatees to; but if (as I suspect) it’s totally doing it wrong, then I don’t see how an average person is supposed to interpret that suggestion of using the `email` module; maybe it should be removed?

---

<div class="post-metadata">

**Author:** ![barry](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/barry/32/42_2.png) [@barry](https://discuss.python.org/u/barry)\
**Post date:** [May 3, 2023, 11:53am UTC](https://discuss.python.org/t/using-email-module-as-a-replacement-for-cgi/26430/2 "2023-05-03T11:53:15Z")

</div>

It would at least be interesting to better understand why using `email.message` is so cumbersome. Is there a way to use an [email policy](https://docs.python.org/3/library/email.policy.html) to make the job easier?

---

<div class="post-metadata">

**Author:** ![defnull](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/defnull/32/23296_2.png) [@defnull](https://discuss.python.org/u/defnull)\
**Post date:** [October 11, 2024, 1:23pm UTC](https://discuss.python.org/t/using-email-module-as-a-replacement-for-cgi/26430/3 "2024-10-11T13:23:56Z")

</div>

I would strongly advise against using the `email` parser for `multipart/form-data` for several reasons:

- `email.Message` holds everything in memory, including large file uploads.
- The line-based `email` parser is [very slow](https://github.com/defnull/multipart_bench) for certain inputs. So much so that this might be abused for denial of service attacks.
- Email is a mess, parses have to deal with broken clients, dozens of RFCs and decades of technical dept. Modern `multipart/form-data` on the other hand is (relatively) well defined and most modern browsers and HTTP clients emit clean and correct data. A specialized parser with stricter parsing rules is usually way faster, way less complex and as a consequence, more secure.

---

<div class="post-metadata">

**Author:** ![barry](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/barry/32/42_2.png) [@barry](https://discuss.python.org/u/barry)\
**Post date:** [October 11, 2024, 5:18pm UTC](https://discuss.python.org/t/using-email-module-as-a-replacement-for-cgi/26430/4 "2024-10-11T17:18:23Z")

</div>

I can’t argue about any of this, especially:

> [@defnull](#):
>
> Email is a mess, parses have to deal with broken clients, dozens of RFCs and decades of technical dept.

However\[1\]:

> [@defnull](#):
>
> `email.Message` holds everything in memory, including large file uploads.

I do recall designing hooks for this problem, such that large files _could_ be stored on disk rather than in memory. I don’t quite remember whether that’s still\[2\] actually possible.

* * *

1. and my memory about the email library technical details details degrades daily 

2. or ever

---

<div class="post-metadata">

**Author:** ![defnull](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/defnull/32/23296_2.png) [@defnull](https://discuss.python.org/u/defnull)\
**Post date:** [October 12, 2024, 12:11pm UTC](https://discuss.python.org/t/using-email-module-as-a-replacement-for-cgi/26430/5 "2024-10-12T12:11:52Z")

</div>

The default behavior is still to buffer everything in-memory and most code bases I have seen that switched from `cgi` to `email` made this mistake. This is fine for emails, which usually have a reasonable size limit and are processed in batches, but dangerous for a web application that need to deal with untrusted and potentially large inputs.
