Skip to content

Commit 705675f

Browse files
committed
Falcon multi-value query parameters fix
1 parent 059dd73 commit 705675f

File tree

4 files changed

+57
-6
lines changed

4 files changed

+57
-6
lines changed

Diff for: openapi_core/contrib/falcon/requests.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from werkzeug.datastructures import Headers
1212
from werkzeug.datastructures import ImmutableMultiDict
1313

14+
from openapi_core.contrib.falcon.util import unpack_params
1415
from openapi_core.datatypes import RequestParameters
1516

1617

@@ -29,7 +30,7 @@ def __init__(
2930

3031
# Path gets deduced by path finder against spec
3132
self.parameters = RequestParameters(
32-
query=ImmutableMultiDict(list(self.request.params.items())),
33+
query=ImmutableMultiDict(unpack_params(self.request.params)),
3334
header=Headers(self.request.headers),
3435
cookie=self.request.cookies,
3536
)

Diff for: openapi_core/contrib/falcon/util.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from typing import Any
2+
from typing import Dict
3+
from typing import Generator
4+
from typing import Tuple
5+
6+
7+
def unpack_params(
8+
params: Dict[str, Any]
9+
) -> Generator[Tuple[str, Any], None, None]:
10+
for k, v in params.items():
11+
if isinstance(v, list):
12+
for v2 in v:
13+
yield (k, v2)
14+
else:
15+
yield (k, v)

Diff for: tests/integration/contrib/falcon/data/v3.0/falconproject/pets/resources.py

+13-5
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,19 @@ class PetListResource:
1111
def on_get(self, request, response):
1212
assert request.context.openapi
1313
assert not request.context.openapi.errors
14-
assert request.context.openapi.parameters.query == {
15-
"page": 1,
16-
"limit": 12,
17-
"search": "",
18-
}
14+
if "ids" in request.params:
15+
assert request.context.openapi.parameters.query == {
16+
"page": 1,
17+
"limit": 2,
18+
"search": "",
19+
"ids": [1, 2],
20+
}
21+
else:
22+
assert request.context.openapi.parameters.query == {
23+
"page": 1,
24+
"limit": 12,
25+
"search": "",
26+
}
1927
data = [
2028
{
2129
"id": 12,

Diff for: tests/integration/contrib/falcon/test_falcon_project.py

+27
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,33 @@ def test_get_valid(self, client):
6767
],
6868
}
6969

70+
def test_get_valid_multiple_ids(self, client):
71+
headers = {
72+
"Content-Type": "application/json",
73+
}
74+
query_string = "limit=2&ids=1&ids=2"
75+
76+
with pytest.warns(DeprecationWarning):
77+
response = client.simulate_get(
78+
"/v1/pets",
79+
host="petstore.swagger.io",
80+
headers=headers,
81+
query_string=query_string,
82+
)
83+
84+
assert response.status_code == 200
85+
assert response.json == {
86+
"data": [
87+
{
88+
"id": 12,
89+
"name": "Cat",
90+
"ears": {
91+
"healthy": True,
92+
},
93+
},
94+
],
95+
}
96+
7097
def test_post_server_invalid(self, client):
7198
response = client.simulate_post(
7299
"/v1/pets",

0 commit comments

Comments
 (0)