From aa168c045164cc956dcda7828a631f7eb5d9a795 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Thu, 30 Apr 2026 16:15:05 +0100 Subject: [PATCH] docs(python): add FormData class to Python API Adds the FormData class (already available in java/csharp) to the Python language bindings so it can be used for `form` (with repeated keys) and `multipart` (with multiple files per field) parameters of APIRequestContext. Fixes: https://github.com/microsoft/playwright-python/issues/2834 Fixes: https://github.com/microsoft/playwright-python/issues/2784 --- docs/src/api/class-formdata.md | 80 +++++++++++++++++++++++++++++++++- docs/src/api/params.md | 7 +-- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/docs/src/api/class-formdata.md b/docs/src/api/class-formdata.md index 8582333b3ed1d..ad93869411125 100644 --- a/docs/src/api/class-formdata.md +++ b/docs/src/api/class-formdata.md @@ -1,6 +1,6 @@ # class: FormData * since: v1.18 -* langs: java, csharp +* langs: java, csharp, python The [FormData] is used create form data that is sent via [APIRequestContext]. @@ -14,6 +14,22 @@ FormData form = FormData.create() page.request().post("http://localhost/submit", RequestOptions.create().setForm(form)); ``` +```python async +form = FormData() +form.set("firstName", "John") +form.set("lastName", "Doe") +form.set("age", 30) +await page.request.post("http://localhost/submit", form=form) +``` + +```python sync +form = FormData() +form.set("firstName", "John") +form.set("lastName", "Doe") +form.set("age", 30) +page.request.post("http://localhost/submit", form=form) +``` + ## method: FormData.append * since: v1.44 - returns: <[FormData]> @@ -60,6 +76,36 @@ multipart.Append("attachment", new FilePayload() await Page.APIRequest.PostAsync("https://localhost/submit", new() { Multipart = multipart }); ``` +```python async +form = FormData() +# Only name and value are set. +form.append("firstName", "John") +# Name and value are set, filename and Content-Type are inferred from the file path. +form.append("attachment", Path("pic.jpg")) +# Name, value, filename and Content-Type are set. +form.append("attachment", { + "name": "table.csv", + "mimeType": "text/csv", + "buffer": Path("my-table.csv").read_bytes(), +}) +await page.request.post("http://localhost/submit", multipart=form) +``` + +```python sync +form = FormData() +# Only name and value are set. +form.append("firstName", "John") +# Name and value are set, filename and Content-Type are inferred from the file path. +form.append("attachment", Path("pic.jpg")) +# Name, value, filename and Content-Type are set. +form.append("attachment", { + "name": "table.csv", + "mimeType": "text/csv", + "buffer": Path("my-table.csv").read_bytes(), +}) +page.request.post("http://localhost/submit", multipart=form) +``` + ### param: FormData.append.name * since: v1.44 - `name` <[string]> @@ -129,6 +175,38 @@ multipart.Set("age", 30); await Page.APIRequest.PostAsync("https://localhost/submit", new() { Multipart = multipart }); ``` +```python async +form = FormData() +# Only name and value are set. +form.set("firstName", "John") +# Name and value are set, filename and Content-Type are inferred from the file path. +form.set("profilePicture1", Path("john.jpg")) +# Name, value, filename and Content-Type are set. +form.set("profilePicture2", { + "name": "john.jpg", + "mimeType": "image/jpeg", + "buffer": Path("john.jpg").read_bytes(), +}) +form.set("age", 30) +await page.request.post("http://localhost/submit", multipart=form) +``` + +```python sync +form = FormData() +# Only name and value are set. +form.set("firstName", "John") +# Name and value are set, filename and Content-Type are inferred from the file path. +form.set("profilePicture1", Path("john.jpg")) +# Name, value, filename and Content-Type are set. +form.set("profilePicture2", { + "name": "john.jpg", + "mimeType": "image/jpeg", + "buffer": Path("john.jpg").read_bytes(), +}) +form.set("age", 30) +page.request.post("http://localhost/submit", multipart=form) +``` + ### param: FormData.set.name * since: v1.18 - `name` <[string]> diff --git a/docs/src/api/params.md b/docs/src/api/params.md index b976e9ac65878..df6b543ead2e4 100644 --- a/docs/src/api/params.md +++ b/docs/src/api/params.md @@ -486,11 +486,11 @@ unless explicitly provided. ## python-fetch-option-form * langs: python -- `form` <[Object]<[string], [string]|[float]|[boolean]>> +- `form` <[Object]<[string], [string]|[float]|[boolean]>|[FormData]> Provides an object that will be serialized as html form using `application/x-www-form-urlencoded` encoding and sent as this request body. If this parameter is specified `content-type` header will be set to `application/x-www-form-urlencoded` -unless explicitly provided. +unless explicitly provided. Use [FormData] to send multiple values for the same field. ## csharp-fetch-option-form * langs: csharp @@ -516,7 +516,7 @@ or as file-like object containing file name, mime-type and its content. ## python-fetch-option-multipart * langs: python -- `multipart` <[Object]<[string], [string]|[float]|[boolean]|[ReadStream]|[Object]>> +- `multipart` <[Object]<[string], [string]|[float]|[boolean]|[ReadStream]|[Object]>|[FormData]> - `name` <[string]> File name - `mimeType` <[string]> File type - `buffer` <[Buffer]> File content @@ -524,6 +524,7 @@ or as file-like object containing file name, mime-type and its content. Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless explicitly provided. File values can be passed as file-like object containing file name, mime-type and its content. +Use [FormData] to send multiple files in the same field. ## csharp-fetch-option-multipart * langs: csharp