Skip to content

Commit 7084a79

Browse files
johnboyeswing328
andauthored
[BUG][PYTHON] Do not set Content-Type for GET, HEAD or DELETE requests (#9852)
* [BUG][PYTHON] Do not set Content-Type for GET, HEAD or DELETE requests The Python generator no longer sets a default `Content-Type` of `application/json` for `GET`, `HEAD` and `DELETE` requests. Having the `Content-Type` set for these requests was causing issues with other tools which insist that GET, HEAD and DELETE requests do not have a Content-Type (as per the OpenAPI 3 specification). An example of the problem that this commit fixes is when using [Prism][1] as a [validation proxy][2]. [Prism rejects any GET request that has a Content-Type][3]. Here is [an example of the problem manifesting itself][4]. To validate the fix in this commit: 1. Start with any OpenAPI3 spec e.g. the Petstore example at https://editor.swagger.io/ 2. Generate Python client code for the spec 3. Look at the generated `rest.py` e.g. in the [standard sample in this repo][5] and see that the `Content-Type` defaults to `application/json` for all HTTP methods (including `GET`, `HEAD` and `DELETE`), rather than there being no `Content-Type` for `GET`, `HEAD` and `DELETE`. Fixes #9831 [1]: https://github.com/stoplightio/prism [2]: https://meta.stoplight.io/docs/prism/docs/guides/03-validation-proxy.md [3]: stoplightio/prism#1408 (comment) [4]: https://github.com/agilepathway/gauge-openapi-example/pull/28/checks?check_run_id=2888606052#step:13:18 [5]: https://github.com/OpenAPITools/openapi-generator/blob/969cea8ce10cb9d012c3936fb377d631c0d044c9/samples/openapi3/client/petstore/python/petstore_api/rest.py#L141 * update samples * Fix Python DELETE bug introduced in earlier commit The earlier commit 9dfe1f6 introduced a bug for `DELETE` requests on the standard Python generator. This commit fixes that bug and also includes the updated samples. Co-authored-by: William Cheng <wing328hk@gmail.com>
1 parent 60c4c88 commit 7084a79

File tree

6 files changed

+24
-24
lines changed
  • modules/openapi-generator/src/main/resources/python
  • samples
    • client/petstore
      • python/petstore_api
      • python_disallowAdditionalPropertiesIfNotPresent/petstore_api
    • openapi3/client
      • extensions/x-auth-id-alias/python/x_auth_id_alias
      • features/dynamic-servers/python/dynamic_servers
      • petstore/python/petstore_api

6 files changed

+24
-24
lines changed

modules/openapi-generator/src/main/resources/python/rest.mustache

+4-4
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,15 @@ class RESTClientObject(object):
129129
timeout = urllib3.Timeout(
130130
connect=_request_timeout[0], read=_request_timeout[1])
131131

132-
if 'Content-Type' not in headers:
133-
headers['Content-Type'] = 'application/json'
134-
135132
try:
136133
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
137134
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
135+
# Only set a default Content-Type for POST, PUT, PATCH and OPTIONS requests
136+
if (method != 'DELETE') and ('Content-Type' not in headers):
137+
headers['Content-Type'] = 'application/json'
138138
if query_params:
139139
url += '?' + urlencode(query_params)
140-
if re.search('json', headers['Content-Type'], re.IGNORECASE):
140+
if ('Content-Type' not in headers) or (re.search('json', headers['Content-Type'], re.IGNORECASE)):
141141
request_body = None
142142
if body is not None:
143143
request_body = json.dumps(body)

samples/client/petstore/python/petstore_api/rest.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,15 @@ def request(self, method, url, query_params=None, headers=None,
137137
timeout = urllib3.Timeout(
138138
connect=_request_timeout[0], read=_request_timeout[1])
139139

140-
if 'Content-Type' not in headers:
141-
headers['Content-Type'] = 'application/json'
142-
143140
try:
144141
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
145142
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
143+
# Only set a default Content-Type for POST, PUT, PATCH and OPTIONS requests
144+
if (method != 'DELETE') and ('Content-Type' not in headers):
145+
headers['Content-Type'] = 'application/json'
146146
if query_params:
147147
url += '?' + urlencode(query_params)
148-
if re.search('json', headers['Content-Type'], re.IGNORECASE):
148+
if ('Content-Type' not in headers) or (re.search('json', headers['Content-Type'], re.IGNORECASE)):
149149
request_body = None
150150
if body is not None:
151151
request_body = json.dumps(body)

samples/client/petstore/python_disallowAdditionalPropertiesIfNotPresent/petstore_api/rest.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,15 @@ def request(self, method, url, query_params=None, headers=None,
137137
timeout = urllib3.Timeout(
138138
connect=_request_timeout[0], read=_request_timeout[1])
139139

140-
if 'Content-Type' not in headers:
141-
headers['Content-Type'] = 'application/json'
142-
143140
try:
144141
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
145142
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
143+
# Only set a default Content-Type for POST, PUT, PATCH and OPTIONS requests
144+
if (method != 'DELETE') and ('Content-Type' not in headers):
145+
headers['Content-Type'] = 'application/json'
146146
if query_params:
147147
url += '?' + urlencode(query_params)
148-
if re.search('json', headers['Content-Type'], re.IGNORECASE):
148+
if ('Content-Type' not in headers) or (re.search('json', headers['Content-Type'], re.IGNORECASE)):
149149
request_body = None
150150
if body is not None:
151151
request_body = json.dumps(body)

samples/openapi3/client/extensions/x-auth-id-alias/python/x_auth_id_alias/rest.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,15 @@ def request(self, method, url, query_params=None, headers=None,
137137
timeout = urllib3.Timeout(
138138
connect=_request_timeout[0], read=_request_timeout[1])
139139

140-
if 'Content-Type' not in headers:
141-
headers['Content-Type'] = 'application/json'
142-
143140
try:
144141
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
145142
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
143+
# Only set a default Content-Type for POST, PUT, PATCH and OPTIONS requests
144+
if (method != 'DELETE') and ('Content-Type' not in headers):
145+
headers['Content-Type'] = 'application/json'
146146
if query_params:
147147
url += '?' + urlencode(query_params)
148-
if re.search('json', headers['Content-Type'], re.IGNORECASE):
148+
if ('Content-Type' not in headers) or (re.search('json', headers['Content-Type'], re.IGNORECASE)):
149149
request_body = None
150150
if body is not None:
151151
request_body = json.dumps(body)

samples/openapi3/client/features/dynamic-servers/python/dynamic_servers/rest.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,15 @@ def request(self, method, url, query_params=None, headers=None,
137137
timeout = urllib3.Timeout(
138138
connect=_request_timeout[0], read=_request_timeout[1])
139139

140-
if 'Content-Type' not in headers:
141-
headers['Content-Type'] = 'application/json'
142-
143140
try:
144141
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
145142
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
143+
# Only set a default Content-Type for POST, PUT, PATCH and OPTIONS requests
144+
if (method != 'DELETE') and ('Content-Type' not in headers):
145+
headers['Content-Type'] = 'application/json'
146146
if query_params:
147147
url += '?' + urlencode(query_params)
148-
if re.search('json', headers['Content-Type'], re.IGNORECASE):
148+
if ('Content-Type' not in headers) or (re.search('json', headers['Content-Type'], re.IGNORECASE)):
149149
request_body = None
150150
if body is not None:
151151
request_body = json.dumps(body)

samples/openapi3/client/petstore/python/petstore_api/rest.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,15 @@ def request(self, method, url, query_params=None, headers=None,
137137
timeout = urllib3.Timeout(
138138
connect=_request_timeout[0], read=_request_timeout[1])
139139

140-
if 'Content-Type' not in headers:
141-
headers['Content-Type'] = 'application/json'
142-
143140
try:
144141
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
145142
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
143+
# Only set a default Content-Type for POST, PUT, PATCH and OPTIONS requests
144+
if (method != 'DELETE') and ('Content-Type' not in headers):
145+
headers['Content-Type'] = 'application/json'
146146
if query_params:
147147
url += '?' + urlencode(query_params)
148-
if re.search('json', headers['Content-Type'], re.IGNORECASE):
148+
if ('Content-Type' not in headers) or (re.search('json', headers['Content-Type'], re.IGNORECASE)):
149149
request_body = None
150150
if body is not None:
151151
request_body = json.dumps(body)

0 commit comments

Comments
 (0)