Coverage for fastapi/security/api_key.py: 100%
39 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-05-05 00:03 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-05-05 00:03 +0000
1from typing import Optional 1abcdef
3from fastapi.openapi.models import APIKey, APIKeyIn 1abcdef
4from fastapi.security.base import SecurityBase 1abcdef
5from starlette.exceptions import HTTPException 1abcdef
6from starlette.requests import Request 1abcdef
7from starlette.status import HTTP_403_FORBIDDEN 1abcdef
8from typing_extensions import Annotated, Doc 1abcdef
11class APIKeyBase(SecurityBase): 1abcdef
12 @staticmethod 1abcdef
13 def check_api_key(api_key: Optional[str], auto_error: bool) -> Optional[str]: 1abcdef
14 if not api_key: 28 g 9 h ! i # j $ k % l ' m ( n ) o * p + q , r - s . t / u : v ; w = x ? y @ z [ A ] B ^ C _ D ` E { F | G } H ~ I abJ bbK cbL dbM ebN fbO gbP hbQ ibR jbS kbT lbU mbV nbW obX pbY qbZ rb0 sb1 tb2 ub3 vb4 wb5 xb6 yb7
15 if auto_error: 1ghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567
16 raise HTTPException( 1ghjkmnpqstvwyzBCEFHIKLNOQRTUWXZ02356
17 status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
18 )
19 return None 1iloruxADGJMPSVY147
20 return api_key 28 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbyb
23class APIKeyQuery(APIKeyBase): 1abcdef
24 """
25 API key authentication using a query parameter.
27 This defines the name of the query parameter that should be provided in the request
28 with the API key and integrates that into the OpenAPI documentation. It extracts
29 the key value sent in the query parameter automatically and provides it as the
30 dependency result. But it doesn't define how to send that API key to the client.
32 ## Usage
34 Create an instance object and use that object as the dependency in `Depends()`.
36 The dependency result will be a string containing the key value.
38 ## Example
40 ```python
41 from fastapi import Depends, FastAPI
42 from fastapi.security import APIKeyQuery
44 app = FastAPI()
46 query_scheme = APIKeyQuery(name="api_key")
49 @app.get("/items/")
50 async def read_items(api_key: str = Depends(query_scheme)):
51 return {"api_key": api_key}
52 ```
53 """
55 def __init__( 1abcdef
56 self,
57 *,
58 name: Annotated[
59 str,
60 Doc("Query parameter name."),
61 ],
62 scheme_name: Annotated[
63 Optional[str],
64 Doc(
65 """
66 Security scheme name.
68 It will be included in the generated OpenAPI (e.g. visible at `/docs`).
69 """
70 ),
71 ] = None,
72 description: Annotated[
73 Optional[str],
74 Doc(
75 """
76 Security scheme description.
78 It will be included in the generated OpenAPI (e.g. visible at `/docs`).
79 """
80 ),
81 ] = None,
82 auto_error: Annotated[
83 bool,
84 Doc(
85 """
86 By default, if the query parameter is not provided, `APIKeyQuery` will
87 automatically cancel the request and send the client an error.
89 If `auto_error` is set to `False`, when the query parameter is not
90 available, instead of erroring out, the dependency result will be
91 `None`.
93 This is useful when you want to have optional authentication.
95 It is also useful when you want to have authentication that can be
96 provided in one of multiple optional ways (for example, in a query
97 parameter or in an HTTP Bearer token).
98 """
99 ),
100 ] = True,
101 ):
102 self.model: APIKey = APIKey( 1abcdef
103 **{"in": APIKeyIn.query}, # type: ignore[arg-type]
104 name=name,
105 description=description,
106 )
107 self.scheme_name = scheme_name or self.__class__.__name__ 1abcdef
108 self.auto_error = auto_error 1abcdef
110 async def __call__(self, request: Request) -> Optional[str]: 1abcdef
111 api_key = request.query_params.get(self.model.name) 2' m ( n ) o : v ; w = x ` E { F | G ebN fbO gbP nbW obX pbY wb5 xb6 yb7
112 return self.check_api_key(api_key, self.auto_error) 2' m ( n ) o : v ; w = x ` E { F | G ebN fbO gbP nbW obX pbY wb5 xb6 yb7
115class APIKeyHeader(APIKeyBase): 1abcdef
116 """
117 API key authentication using a header.
119 This defines the name of the header that should be provided in the request with
120 the API key and integrates that into the OpenAPI documentation. It extracts
121 the key value sent in the header automatically and provides it as the dependency
122 result. But it doesn't define how to send that key to the client.
124 ## Usage
126 Create an instance object and use that object as the dependency in `Depends()`.
128 The dependency result will be a string containing the key value.
130 ## Example
132 ```python
133 from fastapi import Depends, FastAPI
134 from fastapi.security import APIKeyHeader
136 app = FastAPI()
138 header_scheme = APIKeyHeader(name="x-key")
141 @app.get("/items/")
142 async def read_items(key: str = Depends(header_scheme)):
143 return {"key": key}
144 ```
145 """
147 def __init__( 1abcdef
148 self,
149 *,
150 name: Annotated[str, Doc("Header name.")],
151 scheme_name: Annotated[
152 Optional[str],
153 Doc(
154 """
155 Security scheme name.
157 It will be included in the generated OpenAPI (e.g. visible at `/docs`).
158 """
159 ),
160 ] = None,
161 description: Annotated[
162 Optional[str],
163 Doc(
164 """
165 Security scheme description.
167 It will be included in the generated OpenAPI (e.g. visible at `/docs`).
168 """
169 ),
170 ] = None,
171 auto_error: Annotated[
172 bool,
173 Doc(
174 """
175 By default, if the header is not provided, `APIKeyHeader` will
176 automatically cancel the request and send the client an error.
178 If `auto_error` is set to `False`, when the header is not available,
179 instead of erroring out, the dependency result will be `None`.
181 This is useful when you want to have optional authentication.
183 It is also useful when you want to have authentication that can be
184 provided in one of multiple optional ways (for example, in a header or
185 in an HTTP Bearer token).
186 """
187 ),
188 ] = True,
189 ):
190 self.model: APIKey = APIKey( 1abcdef
191 **{"in": APIKeyIn.header}, # type: ignore[arg-type]
192 name=name,
193 description=description,
194 )
195 self.scheme_name = scheme_name or self.__class__.__name__ 1abcdef
196 self.auto_error = auto_error 1abcdef
198 async def __call__(self, request: Request) -> Optional[str]: 1abcdef
199 api_key = request.headers.get(self.model.name) 2# j $ k % l - s . t / u ] B ^ C _ D bbK cbL dbM kbT lbU mbV tb2 ub3 vb4
200 return self.check_api_key(api_key, self.auto_error) 2# j $ k % l - s . t / u ] B ^ C _ D bbK cbL dbM kbT lbU mbV tb2 ub3 vb4
203class APIKeyCookie(APIKeyBase): 1abcdef
204 """
205 API key authentication using a cookie.
207 This defines the name of the cookie that should be provided in the request with
208 the API key and integrates that into the OpenAPI documentation. It extracts
209 the key value sent in the cookie automatically and provides it as the dependency
210 result. But it doesn't define how to set that cookie.
212 ## Usage
214 Create an instance object and use that object as the dependency in `Depends()`.
216 The dependency result will be a string containing the key value.
218 ## Example
220 ```python
221 from fastapi import Depends, FastAPI
222 from fastapi.security import APIKeyCookie
224 app = FastAPI()
226 cookie_scheme = APIKeyCookie(name="session")
229 @app.get("/items/")
230 async def read_items(session: str = Depends(cookie_scheme)):
231 return {"session": session}
232 ```
233 """
235 def __init__( 1abcdef
236 self,
237 *,
238 name: Annotated[str, Doc("Cookie name.")],
239 scheme_name: Annotated[
240 Optional[str],
241 Doc(
242 """
243 Security scheme name.
245 It will be included in the generated OpenAPI (e.g. visible at `/docs`).
246 """
247 ),
248 ] = None,
249 description: Annotated[
250 Optional[str],
251 Doc(
252 """
253 Security scheme description.
255 It will be included in the generated OpenAPI (e.g. visible at `/docs`).
256 """
257 ),
258 ] = None,
259 auto_error: Annotated[
260 bool,
261 Doc(
262 """
263 By default, if the cookie is not provided, `APIKeyCookie` will
264 automatically cancel the request and send the client an error.
266 If `auto_error` is set to `False`, when the cookie is not available,
267 instead of erroring out, the dependency result will be `None`.
269 This is useful when you want to have optional authentication.
271 It is also useful when you want to have authentication that can be
272 provided in one of multiple optional ways (for example, in a cookie or
273 in an HTTP Bearer token).
274 """
275 ),
276 ] = True,
277 ):
278 self.model: APIKey = APIKey( 1abcdef
279 **{"in": APIKeyIn.cookie}, # type: ignore[arg-type]
280 name=name,
281 description=description,
282 )
283 self.scheme_name = scheme_name or self.__class__.__name__ 1abcdef
284 self.auto_error = auto_error 1abcdef
286 async def __call__(self, request: Request) -> Optional[str]: 1abcdef
287 api_key = request.cookies.get(self.model.name) 28 g 9 h ! i * p + q , r ? y @ z [ A } H ~ I abJ hbQ ibR jbS qbZ rb0 sb1
288 return self.check_api_key(api_key, self.auto_error) 28 g 9 h ! i * p + q , r ? y @ z [ A } H ~ I abJ hbQ ibR jbS qbZ rb0 sb1