Skip to content
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

Feature/get delete body #1712

Merged
merged 11 commits into from
Oct 23, 2023
28 changes: 17 additions & 11 deletions connexion/decorators/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,18 +211,21 @@ def get_arguments(
)
)

if operation.method.upper() in ["PATCH", "POST", "PUT"]:
ret.update(
_get_body_argument(
body,
operation=operation,
arguments=arguments,
has_kwargs=has_kwargs,
sanitize=sanitize,
content_type=content_type,
)
if operation.method.upper() == "TRACE":
# TRACE requests MUST NOT include a body (RFC7231 section 4.3.8)
return ret

ret.update(
_get_body_argument(
body,
operation=operation,
arguments=arguments,
has_kwargs=has_kwargs,
sanitize=sanitize,
content_type=content_type,
)
ret.update(_get_file_arguments(files, arguments, has_kwargs))
)
ret.update(_get_file_arguments(files, arguments, has_kwargs))
return ret


Expand Down Expand Up @@ -377,6 +380,9 @@ def _get_body_argument(
if len(arguments) <= 0 and not has_kwargs:
return {}

if not operation.is_request_body_defined:
return {}

body_name = sanitize(operation.body_name(content_type))

if content_type in FORM_CONTENT_TYPES:
Expand Down
5 changes: 5 additions & 0 deletions connexion/operations/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ def method(self):
def request_body(self):
"""The request body for this operation"""

@property
def is_request_body_defined(self) -> bool:
"""Whether the request body is defined for this operation"""
return self.request_body != {}

@property
def path(self):
"""
Expand Down
1 change: 1 addition & 0 deletions docs/v3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ Smaller breaking changes
* The ``MethodViewResolver`` has been renamed to ``MethodResolver``, and a new ``MethodViewResolver``
has been added to work with Flask's ``MethodView`` specifically.
* Built-in support for uWSGI has been removed. You can re-add this functionality using a custom middleware.
* The request body is now passed through for ``GET``, ``HEAD``, ``DELETE``, ``CONNECT`` and ``OPTIONS`` methods as well.


Non-breaking changes
Expand Down
12 changes: 12 additions & 0 deletions tests/api/test_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,18 @@ def test_body_not_allowed_additional_properties(simple_app):
assert "Additional properties are not allowed" in response["detail"]


def test_body_in_get_request(simple_app):
app_client = simple_app.test_client()
body = {"body1": "bodyString"}
resp = app_client.request(
"GET",
"/v1.0/body-in-get-request",
json=body,
)
assert resp.status_code == 200
assert resp.json() == body


def test_bool_as_default_param(simple_app):
app_client = simple_app.test_client()
resp = app_client.get("/v1.0/test-bool-param")
Expand Down
10 changes: 10 additions & 0 deletions tests/decorators/test_parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
def test_sync_injection():
request = MagicMock(name="request")
request.path_params = {"p1": "123"}
request.get_body.return_value = {}

func = MagicMock()

def handler(**kwargs):
func(**kwargs)

operation = MagicMock(name="operation")
operation.is_request_body_defined = False
operation.body_name = lambda _: "body"

with TestContext(operation=operation):
Expand All @@ -43,13 +45,16 @@ def handler(**kwargs):
async def test_async_injection():
request = AsyncMock(name="request")
request.path_params = {"p1": "123"}
request.get_body.return_value = {}
request.files.return_value = {}

func = MagicMock()

async def handler(**kwargs):
func(**kwargs)

operation = MagicMock(name="operation")
operation.is_request_body_defined = False
operation.body_name = lambda _: "body"

with TestContext(operation=operation):
Expand All @@ -62,6 +67,7 @@ async def handler(**kwargs):
def test_sync_injection_with_context():
request = MagicMock(name="request")
request.path_params = {"p1": "123"}
request.get_body.return_value = {}

func = MagicMock()

Expand All @@ -71,6 +77,7 @@ def handler(context_, **kwargs):
context = {"test": "success"}

operation = MagicMock(name="operation")
operation.is_request_body_defined = False
operation.body_name = lambda _: "body"

with TestContext(context=context, operation=operation):
Expand All @@ -86,6 +93,8 @@ def handler(context_, **kwargs):
async def test_async_injection_with_context():
request = AsyncMock(name="request")
request.path_params = {"p1": "123"}
request.get_body.return_value = {}
request.files.return_value = {}

func = MagicMock()

Expand All @@ -95,6 +104,7 @@ async def handler(context_, **kwargs):
context = {"test": "success"}

operation = MagicMock(name="operation")
operation.is_request_body_defined = False
operation.body_name = lambda _: "body"

with TestContext(context=context, operation=operation):
Expand Down
4 changes: 4 additions & 0 deletions tests/fakeapi/hello/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,10 @@ def test_body_not_allowed_additional_properties(body):
return body


def test_body_in_get_request(body):
return body


def post_wrong_content_type():
return "NOT OK"

Expand Down
14 changes: 14 additions & 0 deletions tests/fixtures/simple/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,20 @@ paths:
body1:
type: string
additionalProperties: false
/body-in-get-request:
get:
operationId: fakeapi.hello.test_body_in_get_request
responses:
'200':
description: OK
requestBody:
content:
application/json:
schema:
type: object
properties:
body1:
type: string
/get_non_conforming_response:
get:
operationId: fakeapi.hello.get_empty_dict
Expand Down
21 changes: 21 additions & 0 deletions tests/fixtures/simple/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,27 @@ paths:
200:
description: OK

/body-in-get-request:
get:
operationId: fakeapi.hello.test_body_in_get_request
consumes:
- application/json
produces:
- application/json
parameters:
- name: $body
description: A request body in a GET method.
in: body
required: true
schema:
type: object
properties:
body1:
type: string
responses:
200:
description: OK

/get_non_conforming_response:
get:
operationId: fakeapi.hello.get_empty_dict
Expand Down
Loading