Python WebAcademy Blog

FastAPIのフォームを支えるpython-multipart 0.0.33が公開。送られてくる項目の数と大きさに上限を設けられるようになったニュースを初心者向けに解説

|

2026年10月31日、FastAPIやStarletteでフォームを受け取るときに使われるpython-multipartの0.0.33が公開されました。URLエンコードされたフォームで、項目の数と1項目の大きさに上限を設けられるようになり、Python 3.10のサポートも終わっています。上限がなぜ必要なのか、FastAPIではどうなっているのかを、実際に動かしたコードとともに整理します。

2026年10月31日、Pythonでフォームのデータを読み取るライブラリpython-multipartの0.0.33が公開されました。FastAPIやStarletteで、HTMLのフォームを受け取るときに使われているライブラリです。

今回の目玉は、送られてくる項目の数と、1つの項目の大きさに、上限を設けられるようになったことです。あわせて、Python 3.10のサポートを終え、3.15に対応しました。

なぜ、わざわざ上限が必要なのでしょうか。今回は、0.0.32と0.0.33で同じコードを動かしながら、上限の意味と、FastAPIでの扱いを見ていきます。

まずはpython-multipartとはどんなものか

最初に、python-multipartがどんなライブラリなのかを確認しておきましょう。ブラウザのフォームから送られるデータは、主に2つの形式のどちらかで届きます。

形式 中身の例 よく使う場面
application/x-www-form-urlencoded name=taro&age=20 文字だけのふつうのフォーム
multipart/form-data 区切り線で項目を分けた形式 ファイルのアップロードを含むフォーム

python-multipartは、この2つの形式を読み取って、項目ごとに取り出すためのライブラリです。名前にmultipartとありますが、1つ目のURLエンコードの形式も扱えます。

FastAPIとの関係

FastAPIでForm()を使うには、python-multipartを入れておく必要があります。手元の環境でも、FastAPI 0.162.0と一緒に、Starlette 1.10.0とpython-multipart 0.0.33が入っていました。

フォームの扱いが最近どう変わったのかは、こちらで紹介しています。【関連記事】FastAPIが3日で0.150へ。HTMLフォームの扱いが変わった

0.0.33で何が変わったのかを整理しよう

続いて、0.0.33の主な変更を表にまとめます。内容は、python-multipartの公式リポジトリにある変更履歴CHANGELOG.mdにもとづいています。

分類 主な変更
Pythonの対応範囲 3.10のサポートを終了し、3.15に対応
新機能 URLエンコードのフォームで、項目の数と大きさの上限を設定できるように
不具合の修正 Content-Transfer-Encodingの解読を、項目を渡す前に終えるように
不具合の修正 名前のないアップロードや、文字列で指定した保存先の扱いを修正
速度 区切り線の照合やコールバックの呼び出しを高速化

PyPIの記録によると、0.0.33が必要とするPythonは3.11以上です。ひとつ前の0.0.32は、2026年6月4日に公開されていました。

主要なライブラリがPython 3.10を外していく流れは、こちらでもまとめています。【関連記事】Python 3.10のサポート終了から2週間、主要ライブラリの対応状況

なぜ上限が必要なのか

新機能の話に入る前に、上限がなぜ大事なのかを考えてみましょう。Webアプリは、誰から送られてくるかわからないデータを受け取ります。

もし、項目が何十万個も並んだフォームや、1つの項目に何百メガバイトもの文字を詰め込んだフォームが送られてきたらどうでしょうか。読み取るだけでメモリや処理の時間を使い果たし、ほかの利用者の操作まで遅くなってしまいます。

サービス妨害という攻撃

このように、大量のデータや重い処理を押し付けてサービスを止めようとする攻撃を、サービス妨害、英語ではDoS(Denial of Service)と呼びます。項目の数や大きさに上限を設けるのは、DoSを防ぐ基本的な守りの1つです。

上限があれば、想定を超えたデータは早い段階で断れます。全部を読み終えてから判断するより、ずっと少ない負担で済むわけです。

0.0.32と0.0.33で上限を試してみた

では、実際に新しい上限を試してみましょう。python-multipartのFormParserに、configで上限を渡します。

項目の数の上限

まずは、項目の数の上限です。MAX_FIELDSを3にして、4つの項目が入ったデータを読ませてみました。

from python_multipart.exceptions import FormParserError
from python_multipart.multipart import FormParser

fields = []
parser = FormParser(
    "application/x-www-form-urlencoded",
    on_field=lambda f: fields.append((f.field_name, f.value)),
    on_file=None,
    config={"MAX_FIELDS": 3},
)
try:
    parser.write(b"a=1&b=2&c=3&d=4")
    parser.finalize()
except FormParserError as e:
    print("FormParserError:", e)
print(len(fields), "件:", fields)

0.0.32と0.0.33を、それぞれ新しい仮想環境に入れ、手元のPython 3.11で実行した結果です。

python-multipart 0.0.32
4 件: [(b'a', b'1'), (b'b', b'2'), (b'c', b'3'), (b'd', b'4')]

python-multipart 0.0.33
FormParserError: Too many fields. Maximum number of fields is 3.
3 件: [(b'a', b'1'), (b'b', b'2'), (b'c', b'3')]

0.0.32では、MAX_FIELDSという設定はまだなかったので、4つすべてが読み取られました。0.0.33では、4つ目に入ったところで、項目が多すぎるというエラーで止まっています。

1つの項目の大きさの上限

続いて、MAX_FIELD_SIZEを20バイトにして、100文字のコメントを含むデータを読ませました。コードは先ほどとほぼ同じなので、違う部分だけを載せます。

config={"MAX_FIELD_SIZE": 20}
parser.write(b"name=taro&comment=" + b"x" * 100)

結果は次のとおりです。

版 結果
0.0.32 nameとcommentの2つとも読み取られた
0.0.33 Field exceeded maximum size of 20 bytes.というエラーで止まり、読めたのはnameだけ

変更履歴によると、これらの上限は自分で指定したときだけ働く、オプトインの仕組みです。実際に既定の設定を見ると、MAX_FIELDSもMAX_FIELD_SIZEも、上限なしを表す無限大になっていました。

FastAPIでは、すでに上限がある

ここで気になるのが、FastAPIを使っている人への影響ですよね。調べてみると、少し意外なことがわかりました。

インストールされたStarlette 1.10.0のコードを見ると、Starletteはフォームを読むときに、自分で項目の数と大きさを数えていました。既定の上限は、項目が1,000個、1つの項目が1MBです。

1,001個の項目を送ってみた

実際に、FastAPIのアプリに、1,000個と1,001個の項目を持つフォームを送ってみました。

from fastapi import FastAPI, Request
from fastapi.testclient import TestClient

app = FastAPI()


@app.post("/survey")
async def survey(request: Request):
    form = await request.form()
    return {"fields": len(form)}


client = TestClient(app)
for n in (1000, 1001):
    body = "&".join(f"q{i}=yes" for i in range(n))
    res = client.post(
        "/survey",
        content=body,
        headers={"Content-Type": "application/x-www-form-urlencoded"},
    )
    print(n, res.status_code, res.text)

実行した結果です。

1000 200 {"fields":1000}
1001 400 {"detail":"Too many fields. Maximum number of fields is 1000."}

1,000個までは受け付けられ、1,001個目で400のエラーになりました。FastAPIやStarletteを使っている場合は、今回の新機能を使わなくても、すでに既定の上限で守られていることになります。

上限を自分で変えるには

もっと厳しくしたい場合は、await request.form(max_fields=10)のように、上限を指定できます。手元で11個の項目を送ると、Too many fields. Maximum number of fields is 10.という400のエラーになりました。

Starletteの最近の変更については、こちらで紹介しています。【関連記事】Starlette 1.9と1.10がリリース

では、誰にとって嬉しい変更なのか

ここまでをまとめると、今回の新機能が直接役立つのは、python-multipartを直接使っている人です。立場ごとに、表にまとめます。

立場 今回の変更との関係
FastAPIやStarletteでフォームを受け取る Starletteの既定の上限がすでにある。必要ならrequest.form()で調整
python-multipartのFormParserを直接使う 新しいMAX_FIELDSとMAX_FIELD_SIZEで、上限を設けられるようになった
自分でWebフレームワークやツールを作る 上限を指定し忘れると無制限のままなので、明示しておく

既定が無制限のままなのは、これまでの動きを変えないためだと考えられます。直接使っている方は、上げたうえで、自分のアプリに合った上限を指定しておきましょう。

FastAPIそのものの使い方は、こちらで紹介しています。【関連記事】PythonのFastAPIとは?

上げる前にやっておきたいこと

最後に、python-multipartを0.0.33へ上げる前に確かめておきたいことを整理します。

順番 確認すること
1 Python 3.11以上を使っているか
2 FormParserを直接使っているなら、MAX_FIELDSとMAX_FIELD_SIZEを決める
3 FastAPIで大きなフォームを受け取るなら、Starletteの上限に収まるか確かめる
4 使う版を、requirements.txtなどで固定しているか

私は10年ほどエンジニアとして開発に関わってきましたが、アンケートの管理画面で、想定の何十倍もの項目を持つ不正なリクエストが届き、サーバーが一時的に重くなったことがあります。それ以来、受け取るデータには、必ず上限を決めておくようにしています。

上限は、厳しすぎると正しい利用者まで困らせてしまいます。自分のフォームの項目数や、入力される文字の量を確かめたうえで、余裕を持った値を決めるのがおすすめです。

まとめ

2026年10月31日、python-multipart 0.0.33が公開されました。URLエンコードのフォームで、項目の数と1つの項目の大きさに上限を設けられるようになり、Python 3.10のサポートも終わっています。

FastAPIやStarletteでは、すでに既定の上限があります。直接python-multipartを使っている方は、この機会に上限を明示しておきましょう。

ここまでお読みいただきありがとうございました。

参考情報

次のアクション

記事で学んだ内容を実際に動かしてみよう

Python WebAcademyでは、ブラウザ上でコードを書きながら基礎から実践まで体系的に学べます。

Python WebAcademyの学習画面

あわせて読む

関連記事

ブログ一覧へ

Python学習ロードマップ

まずはこの3講座から

記事で気になったテーマを、順番に手を動かしながら学べます。

ロードマップを見る