Skip to content

Commit 74c4d1c

Browse files
authored
🐛 Fix declaring a single parameter per name (fastapi#994)
1 parent 7ccd81f commit 74c4d1c

File tree

2 files changed

+96
-1
lines changed

2 files changed

+96
-1
lines changed

fastapi/openapi/utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ def get_openapi_path(
180180
operation_parameters = get_openapi_operation_parameters(all_route_params)
181181
parameters.extend(operation_parameters)
182182
if parameters:
183-
operation["parameters"] = parameters
183+
operation["parameters"] = list(
184+
{param["name"]: param for param in parameters}.values()
185+
)
184186
if method in METHODS_WITH_BODY:
185187
request_body_oai = get_openapi_operation_request_body(
186188
body_field=route.body_field, model_name_map=model_name_map
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
from fastapi import Depends, FastAPI
2+
from starlette.testclient import TestClient
3+
4+
app = FastAPI()
5+
6+
7+
async def user_exists(user_id: int):
8+
return True
9+
10+
11+
@app.get("/users/{user_id}", dependencies=[Depends(user_exists)])
12+
async def read_users(user_id: int):
13+
pass
14+
15+
16+
client = TestClient(app)
17+
18+
openapi_schema = {
19+
"openapi": "3.0.2",
20+
"info": {"title": "FastAPI", "version": "0.1.0"},
21+
"paths": {
22+
"/users/{user_id}": {
23+
"get": {
24+
"summary": "Read Users",
25+
"operationId": "read_users_users__user_id__get",
26+
"parameters": [
27+
{
28+
"required": True,
29+
"schema": {"title": "User Id", "type": "integer"},
30+
"name": "user_id",
31+
"in": "path",
32+
},
33+
],
34+
"responses": {
35+
"200": {
36+
"description": "Successful Response",
37+
"content": {"application/json": {"schema": {}}},
38+
},
39+
"422": {
40+
"description": "Validation Error",
41+
"content": {
42+
"application/json": {
43+
"schema": {
44+
"$ref": "#/components/schemas/HTTPValidationError"
45+
}
46+
}
47+
},
48+
},
49+
},
50+
}
51+
}
52+
},
53+
"components": {
54+
"schemas": {
55+
"HTTPValidationError": {
56+
"title": "HTTPValidationError",
57+
"type": "object",
58+
"properties": {
59+
"detail": {
60+
"title": "Detail",
61+
"type": "array",
62+
"items": {"$ref": "#/components/schemas/ValidationError"},
63+
}
64+
},
65+
},
66+
"ValidationError": {
67+
"title": "ValidationError",
68+
"required": ["loc", "msg", "type"],
69+
"type": "object",
70+
"properties": {
71+
"loc": {
72+
"title": "Location",
73+
"type": "array",
74+
"items": {"type": "string"},
75+
},
76+
"msg": {"title": "Message", "type": "string"},
77+
"type": {"title": "Error Type", "type": "string"},
78+
},
79+
},
80+
}
81+
},
82+
}
83+
84+
85+
def test_reused_param():
86+
response = client.get("/openapi.json")
87+
data = response.json()
88+
assert data == openapi_schema
89+
90+
91+
def test_read_users():
92+
response = client.get("/users/42")
93+
assert response.status_code == 200

0 commit comments

Comments
 (0)