Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3b2e891

Browse files
✨ Adddescription parameter to all the security scheme classes, e.g.APIKeyQuery(name="key", description="A very cool API key") (#1757)
Co-authored-by: Hylke Postma <h.postma@docuwork.nl>Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
1 parent9121fcc commit3b2e891

15 files changed

+1062
-16
lines changed

‎fastapi/security/api_key.py‎

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,16 @@ class APIKeyBase(SecurityBase):
1313

1414
classAPIKeyQuery(APIKeyBase):
1515
def__init__(
16-
self,*,name:str,scheme_name:Optional[str]=None,auto_error:bool=True
16+
self,
17+
*,
18+
name:str,
19+
scheme_name:Optional[str]=None,
20+
description:Optional[str]=None,
21+
auto_error:bool=True
1722
):
18-
self.model:APIKey=APIKey(**{"in":APIKeyIn.query},name=name)
23+
self.model:APIKey=APIKey(
24+
**{"in":APIKeyIn.query},name=name,description=description
25+
)
1926
self.scheme_name=scheme_nameorself.__class__.__name__
2027
self.auto_error=auto_error
2128

@@ -33,9 +40,16 @@ async def __call__(self, request: Request) -> Optional[str]:
3340

3441
classAPIKeyHeader(APIKeyBase):
3542
def__init__(
36-
self,*,name:str,scheme_name:Optional[str]=None,auto_error:bool=True
43+
self,
44+
*,
45+
name:str,
46+
scheme_name:Optional[str]=None,
47+
description:Optional[str]=None,
48+
auto_error:bool=True
3749
):
38-
self.model:APIKey=APIKey(**{"in":APIKeyIn.header},name=name)
50+
self.model:APIKey=APIKey(
51+
**{"in":APIKeyIn.header},name=name,description=description
52+
)
3953
self.scheme_name=scheme_nameorself.__class__.__name__
4054
self.auto_error=auto_error
4155

@@ -53,9 +67,16 @@ async def __call__(self, request: Request) -> Optional[str]:
5367

5468
classAPIKeyCookie(APIKeyBase):
5569
def__init__(
56-
self,*,name:str,scheme_name:Optional[str]=None,auto_error:bool=True
70+
self,
71+
*,
72+
name:str,
73+
scheme_name:Optional[str]=None,
74+
description:Optional[str]=None,
75+
auto_error:bool=True
5776
):
58-
self.model:APIKey=APIKey(**{"in":APIKeyIn.cookie},name=name)
77+
self.model:APIKey=APIKey(
78+
**{"in":APIKeyIn.cookie},name=name,description=description
79+
)
5980
self.scheme_name=scheme_nameorself.__class__.__name__
6081
self.auto_error=auto_error
6182

‎fastapi/security/http.py‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,14 @@ class HTTPAuthorizationCredentials(BaseModel):
2424

2525
classHTTPBase(SecurityBase):
2626
def__init__(
27-
self,*,scheme:str,scheme_name:Optional[str]=None,auto_error:bool=True
27+
self,
28+
*,
29+
scheme:str,
30+
scheme_name:Optional[str]=None,
31+
description:Optional[str]=None,
32+
auto_error:bool=True,
2833
):
29-
self.model=HTTPBaseModel(scheme=scheme)
34+
self.model=HTTPBaseModel(scheme=scheme,description=description)
3035
self.scheme_name=scheme_nameorself.__class__.__name__
3136
self.auto_error=auto_error
3237

@@ -51,9 +56,10 @@ def __init__(
5156
*,
5257
scheme_name:Optional[str]=None,
5358
realm:Optional[str]=None,
59+
description:Optional[str]=None,
5460
auto_error:bool=True,
5561
):
56-
self.model=HTTPBaseModel(scheme="basic")
62+
self.model=HTTPBaseModel(scheme="basic",description=description)
5763
self.scheme_name=scheme_nameorself.__class__.__name__
5864
self.realm=realm
5965
self.auto_error=auto_error
@@ -97,9 +103,10 @@ def __init__(
97103
*,
98104
bearerFormat:Optional[str]=None,
99105
scheme_name:Optional[str]=None,
106+
description:Optional[str]=None,
100107
auto_error:bool=True,
101108
):
102-
self.model=HTTPBearerModel(bearerFormat=bearerFormat)
109+
self.model=HTTPBearerModel(bearerFormat=bearerFormat,description=description)
103110
self.scheme_name=scheme_nameorself.__class__.__name__
104111
self.auto_error=auto_error
105112

@@ -127,8 +134,14 @@ async def __call__(
127134

128135

129136
classHTTPDigest(HTTPBase):
130-
def__init__(self,*,scheme_name:Optional[str]=None,auto_error:bool=True):
131-
self.model=HTTPBaseModel(scheme="digest")
137+
def__init__(
138+
self,
139+
*,
140+
scheme_name:Optional[str]=None,
141+
description:Optional[str]=None,
142+
auto_error:bool=True,
143+
):
144+
self.model=HTTPBaseModel(scheme="digest",description=description)
132145
self.scheme_name=scheme_nameorself.__class__.__name__
133146
self.auto_error=auto_error
134147

‎fastapi/security/oauth2.py‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,10 @@ def __init__(
118118
*,
119119
flows:Union[OAuthFlowsModel,Dict[str,Dict[str,Any]]]=OAuthFlowsModel(),
120120
scheme_name:Optional[str]=None,
121+
description:Optional[str]=None,
121122
auto_error:Optional[bool]=True
122123
):
123-
self.model=OAuth2Model(flows=flows)
124+
self.model=OAuth2Model(flows=flows,description=description)
124125
self.scheme_name=scheme_nameorself.__class__.__name__
125126
self.auto_error=auto_error
126127

@@ -142,12 +143,18 @@ def __init__(
142143
tokenUrl:str,
143144
scheme_name:Optional[str]=None,
144145
scopes:Optional[Dict[str,str]]=None,
146+
description:Optional[str]=None,
145147
auto_error:bool=True,
146148
):
147149
ifnotscopes:
148150
scopes= {}
149151
flows=OAuthFlowsModel(password={"tokenUrl":tokenUrl,"scopes":scopes})
150-
super().__init__(flows=flows,scheme_name=scheme_name,auto_error=auto_error)
152+
super().__init__(
153+
flows=flows,
154+
scheme_name=scheme_name,
155+
description=description,
156+
auto_error=auto_error,
157+
)
151158

152159
asyncdef__call__(self,request:Request)->Optional[str]:
153160
authorization:str=request.headers.get("Authorization")
@@ -172,6 +179,7 @@ def __init__(
172179
refreshUrl:Optional[str]=None,
173180
scheme_name:Optional[str]=None,
174181
scopes:Optional[Dict[str,str]]=None,
182+
description:Optional[str]=None,
175183
auto_error:bool=True,
176184
):
177185
ifnotscopes:
@@ -184,7 +192,12 @@ def __init__(
184192
"scopes":scopes,
185193
}
186194
)
187-
super().__init__(flows=flows,scheme_name=scheme_name,auto_error=auto_error)
195+
super().__init__(
196+
flows=flows,
197+
scheme_name=scheme_name,
198+
description=description,
199+
auto_error=auto_error,
200+
)
188201

189202
asyncdef__call__(self,request:Request)->Optional[str]:
190203
authorization:str=request.headers.get("Authorization")

‎fastapi/security/open_id_connect_url.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ def __init__(
1313
*,
1414
openIdConnectUrl:str,
1515
scheme_name:Optional[str]=None,
16+
description:Optional[str]=None,
1617
auto_error:bool=True
1718
):
18-
self.model=OpenIdConnectModel(openIdConnectUrl=openIdConnectUrl)
19+
self.model=OpenIdConnectModel(
20+
openIdConnectUrl=openIdConnectUrl,description=description
21+
)
1922
self.scheme_name=scheme_nameorself.__class__.__name__
2023
self.auto_error=auto_error
2124

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
fromfastapiimportDepends,FastAPI,Security
2+
fromfastapi.securityimportAPIKeyCookie
3+
fromfastapi.testclientimportTestClient
4+
frompydanticimportBaseModel
5+
6+
app=FastAPI()
7+
8+
api_key=APIKeyCookie(name="key",description="An API Cookie Key")
9+
10+
11+
classUser(BaseModel):
12+
username:str
13+
14+
15+
defget_current_user(oauth_header:str=Security(api_key)):
16+
user=User(username=oauth_header)
17+
returnuser
18+
19+
20+
@app.get("/users/me")
21+
defread_current_user(current_user:User=Depends(get_current_user)):
22+
returncurrent_user
23+
24+
25+
client=TestClient(app)
26+
27+
openapi_schema= {
28+
"openapi":"3.0.2",
29+
"info": {"title":"FastAPI","version":"0.1.0"},
30+
"paths": {
31+
"/users/me": {
32+
"get": {
33+
"responses": {
34+
"200": {
35+
"description":"Successful Response",
36+
"content": {"application/json": {"schema": {}}},
37+
}
38+
},
39+
"summary":"Read Current User",
40+
"operationId":"read_current_user_users_me_get",
41+
"security": [{"APIKeyCookie": []}],
42+
}
43+
}
44+
},
45+
"components": {
46+
"securitySchemes": {
47+
"APIKeyCookie": {
48+
"type":"apiKey",
49+
"name":"key",
50+
"in":"cookie",
51+
"description":"An API Cookie Key",
52+
}
53+
}
54+
},
55+
}
56+
57+
58+
deftest_openapi_schema():
59+
response=client.get("/openapi.json")
60+
assertresponse.status_code==200,response.text
61+
assertresponse.json()==openapi_schema
62+
63+
64+
deftest_security_api_key():
65+
response=client.get("/users/me",cookies={"key":"secret"})
66+
assertresponse.status_code==200,response.text
67+
assertresponse.json()== {"username":"secret"}
68+
69+
70+
deftest_security_api_key_no_key():
71+
response=client.get("/users/me")
72+
assertresponse.status_code==403,response.text
73+
assertresponse.json()== {"detail":"Not authenticated"}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
fromfastapiimportDepends,FastAPI,Security
2+
fromfastapi.securityimportAPIKeyHeader
3+
fromfastapi.testclientimportTestClient
4+
frompydanticimportBaseModel
5+
6+
app=FastAPI()
7+
8+
api_key=APIKeyHeader(name="key",description="An API Key Header")
9+
10+
11+
classUser(BaseModel):
12+
username:str
13+
14+
15+
defget_current_user(oauth_header:str=Security(api_key)):
16+
user=User(username=oauth_header)
17+
returnuser
18+
19+
20+
@app.get("/users/me")
21+
defread_current_user(current_user:User=Depends(get_current_user)):
22+
returncurrent_user
23+
24+
25+
client=TestClient(app)
26+
27+
openapi_schema= {
28+
"openapi":"3.0.2",
29+
"info": {"title":"FastAPI","version":"0.1.0"},
30+
"paths": {
31+
"/users/me": {
32+
"get": {
33+
"responses": {
34+
"200": {
35+
"description":"Successful Response",
36+
"content": {"application/json": {"schema": {}}},
37+
}
38+
},
39+
"summary":"Read Current User",
40+
"operationId":"read_current_user_users_me_get",
41+
"security": [{"APIKeyHeader": []}],
42+
}
43+
}
44+
},
45+
"components": {
46+
"securitySchemes": {
47+
"APIKeyHeader": {
48+
"type":"apiKey",
49+
"name":"key",
50+
"in":"header",
51+
"description":"An API Key Header",
52+
}
53+
}
54+
},
55+
}
56+
57+
58+
deftest_openapi_schema():
59+
response=client.get("/openapi.json")
60+
assertresponse.status_code==200,response.text
61+
assertresponse.json()==openapi_schema
62+
63+
64+
deftest_security_api_key():
65+
response=client.get("/users/me",headers={"key":"secret"})
66+
assertresponse.status_code==200,response.text
67+
assertresponse.json()== {"username":"secret"}
68+
69+
70+
deftest_security_api_key_no_key():
71+
response=client.get("/users/me")
72+
assertresponse.status_code==403,response.text
73+
assertresponse.json()== {"detail":"Not authenticated"}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp