Skip to content

Support multiple bodies #900

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Dec 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/always_use_correct_content_type_for_requests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
default: patch
---

# Always use correct content type for requests

In previous versions, a request body that was similar to a known content type would use that content type in the request. For example `application/json` would be used for `application/vnd.api+json`. This was incorrect and could result in invalid requests being sent.

Now, the content type defined in the OpenAPI document will always be used.
29 changes: 29 additions & 0 deletions .changeset/renamed_body_types_and_parameters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
default: major
---

# Renamed body types and parameters

PR #900 addresses #822.

Where previously there would be one body parameter per supported content type, now there is a single `body` parameter which takes a union of all the possible inputs. This correctly models the fact that only one body can be sent (and ever would be sent) in a request.

For example, when calling a generated endpoint, code which used to look like this:

```python
post_body_multipart.sync_detailed(
client=client,
multipart_data=PostBodyMultipartMultipartData(),
)
```

Will now look like this:

```python
post_body_multipart.sync_detailed(
client=client,
body=PostBodyMultipartBody(),
)
```

Note that both the input parameter name _and_ the class name have changed. This should result in simpler code when there is only a single body type and now produces correct code when there are multiple body types.
16 changes: 16 additions & 0 deletions .changeset/support_multiple_possible_requestbody.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
default: minor
---

# Support multiple possible `requestBody`

PR #900 addresses #822.

It is now possible in some circumstances to generate valid code for OpenAPI documents which have multiple possible `requestBody` values. Previously, invalid code could have been generated with no warning (only one body could actually be sent).

Only one content type per "category" is currently supported at a time. The categories are:

- JSON, like `application/json`
- Binary data, like `application/octet-stream`
- Encoded form data, like `application/x-www-form-urlencoded`
- Files, like `multipart/form-data`
180 changes: 148 additions & 32 deletions end_to_end_tests/baseline_openapi_3.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,85 @@
"version": "0.1.0"
},
"paths": {
"/bodies/multiple": {
"post": {
"description": "Test multiple bodies",
"tags": [
"bodies"
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"a": {
"type": "string"
}
}
}
},
"application/octet-stream": {
"schema": {
"type": "string",
"format": "binary"
}
},
"application/x-www-form-urlencoded": {
"schema": {
"type": "object",
"properties": {
"a": {
"type": "string"
}
}
}
},
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"a": {
"type": "string"
}
}
}
}
}
},
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/bodies/json-like": {
"post": {
"tags": ["bodies"],
"description": "A content type that works like json but isn't application/json",
"operationId": "json-like",
"requestBody": {
"content": {
"application/vnd+json": {
"schema": {
"type": "object",
"properties": {
"a": {
"type": "string"
}
}
}
}
}
},
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/tests/": {
"get": {
"tags": [
Expand Down Expand Up @@ -806,7 +885,9 @@
},
"/responses/unions/simple_before_complex": {
"post": {
"tags": ["responses"],
"tags": [
"responses"
],
"description": "Regression test for #603",
"responses": {
"200": {
Expand All @@ -815,12 +896,18 @@
"application/json": {
"schema": {
"type": "object",
"required": ["a"],
"required": [
"a"
],
"properties": {
"a": {
"oneOf": [
{"type": "string"},
{"type": "object"}
{
"type": "string"
},
{
"type": "object"
}
]
}
}
Expand Down Expand Up @@ -948,20 +1035,20 @@
},
"parameters": [
{
"name": "param",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "param",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
"name": "param",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "param",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
]
},
"/same-name-multiple-locations/{param}": {
Expand Down Expand Up @@ -1010,7 +1097,9 @@
},
"/tag_with_number": {
"get": {
"tags": ["1"],
"tags": [
"1"
],
"responses": {
"200": {
"description": "Success"
Expand Down Expand Up @@ -1253,7 +1342,9 @@
"/naming/property-conflict-with-import": {
"description": "Ensure that property names don't conflict with imports",
"post": {
"tags": ["naming"],
"tags": [
"naming"
],
"requestBody": {
"content": {
"application/json": {
Expand Down Expand Up @@ -1310,9 +1401,15 @@
{
"$ref": "#/components/parameters/integer-param"
},
{"$ref": "#/components/parameters/header-param"},
{"$ref": "#/components/parameters/cookie-param"},
{"$ref": "#/components/parameters/path-param"}
{
"$ref": "#/components/parameters/header-param"
},
{
"$ref": "#/components/parameters/cookie-param"
},
{
"$ref": "#/components/parameters/path-param"
}
],
"responses": {
"200": {
Expand Down Expand Up @@ -1643,7 +1740,11 @@
},
"Body_upload_file_tests_upload_post": {
"title": "Body_upload_file_tests_upload_post",
"required": ["some_file", "some_object", "some_nullable_object"],
"required": [
"some_file",
"some_object",
"some_nullable_object"
],
"type": "object",
"properties": {
"some_file": {
Expand Down Expand Up @@ -1685,7 +1786,10 @@
"some_object": {
"title": "Some Object",
"type": "object",
"required": ["num", "text"],
"required": [
"num",
"text"
],
"properties": {
"num": {
"type": "number"
Expand All @@ -1698,7 +1802,9 @@
"some_optional_object": {
"title": "Some Optional Object",
"type": "object",
"required": ["foo"],
"required": [
"foo"
],
"properties": {
"foo": {
"type": "string"
Expand Down Expand Up @@ -1921,7 +2027,10 @@
},
"type_enum": {
"type": "integer",
"enum": [0, 1]
"enum": [
0,
1
]
}
}
},
Expand All @@ -1934,11 +2043,15 @@
},
"type": {
"type": "string",
"enum": ["submodel"]
"enum": [
"submodel"
]
},
"type_enum": {
"type": "integer",
"enum": [0]
"enum": [
0
]
}
}
},
Expand All @@ -1953,7 +2066,10 @@
},
"type_enum": {
"type": "integer",
"enum": [0, 1]
"enum": [
0,
1
]
}
}
},
Expand Down Expand Up @@ -2096,7 +2212,7 @@
}
}
},
"ModelWithDateTimeProperty" : {
"ModelWithDateTimeProperty": {
"type": "object",
"properties": {
"datetime": {
Expand Down Expand Up @@ -2274,10 +2390,10 @@
"type": "string",
"format": "byte"
},
"import": {
"import": {
"type": "object"
},
"None": {
"None": {
"type": "object"
},
"model.reference.with.Periods": {
Expand Down
Loading