Coverage for fastapi/security/api_key.py: 100%
45 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-08 03:53 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-08 03:53 +0000
1from typing import Optional 1abcde
3from fastapi.openapi.models import APIKey, APIKeyIn 1abcde
4from fastapi.security.base import SecurityBase 1abcde
5from starlette.exceptions import HTTPException 1abcde
6from starlette.requests import Request 1abcde
7from starlette.status import HTTP_403_FORBIDDEN 1abcde
8from typing_extensions import Annotated, Doc 1abcde
11class APIKeyBase(SecurityBase): 1abcde
12 pass 1abcde
15class APIKeyQuery(APIKeyBase): 1abcde
16 """
17 API key authentication using a query parameter.
19 This defines the name of the query parameter that should be provided in the request
20 with the API key and integrates that into the OpenAPI documentation. It extracts
21 the key value sent in the query parameter automatically and provides it as the
22 dependency result. But it doesn't define how to send that API key to the client.
24 ## Usage
26 Create an instance object and use that object as the dependency in `Depends()`.
28 The dependency result will be a string containing the key value.
30 ## Example
32 ```python
33 from fastapi import Depends, FastAPI
34 from fastapi.security import APIKeyQuery
36 app = FastAPI()
38 query_scheme = APIKeyQuery(name="api_key")
41 @app.get("/items/")
42 async def read_items(api_key: str = Depends(query_scheme)):
43 return {"api_key": api_key}
44 ```
45 """
47 def __init__( 1abcde
48 self,
49 *,
50 name: Annotated[
51 str,
52 Doc("Query parameter name."),
53 ],
54 scheme_name: Annotated[
55 Optional[str],
56 Doc(
57 """
58 Security scheme name.
60 It will be included in the generated OpenAPI (e.g. visible at `/docs`).
61 """
62 ),
63 ] = None,
64 description: Annotated[
65 Optional[str],
66 Doc(
67 """
68 Security scheme description.
70 It will be included in the generated OpenAPI (e.g. visible at `/docs`).
71 """
72 ),
73 ] = None,
74 auto_error: Annotated[
75 bool,
76 Doc(
77 """
78 By default, if the query parameter is not provided, `APIKeyQuery` will
79 automatically cancel the request and send the client an error.
81 If `auto_error` is set to `False`, when the query parameter is not
82 available, instead of erroring out, the dependency result will be
83 `None`.
85 This is useful when you want to have optional authentication.
87 It is also useful when you want to have authentication that can be
88 provided in one of multiple optional ways (for example, in a query
89 parameter or in an HTTP Bearer token).
90 """
91 ),
92 ] = True,
93 ):
94 self.model: APIKey = APIKey( 1abcde
95 **{"in": APIKeyIn.query}, # type: ignore[arg-type]
96 name=name,
97 description=description,
98 )
99 self.scheme_name = scheme_name or self.__class__.__name__ 1abcde
100 self.auto_error = auto_error 1abcde
102 async def __call__(self, request: Request) -> Optional[str]: 1abcde
103 api_key = request.query_params.get(self.model.name) 1abcde
104 if not api_key: 1abcde
105 if self.auto_error: 1abcde
106 raise HTTPException( 1abcde
107 status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
108 )
109 else:
110 return None 1abcde
111 return api_key 1abcde
114class APIKeyHeader(APIKeyBase): 1abcde
115 """
116 API key authentication using a header.
118 This defines the name of the header that should be provided in the request with
119 the API key and integrates that into the OpenAPI documentation. It extracts
120 the key value sent in the header automatically and provides it as the dependency
121 result. But it doesn't define how to send that key to the client.
123 ## Usage
125 Create an instance object and use that object as the dependency in `Depends()`.
127 The dependency result will be a string containing the key value.
129 ## Example
131 ```python
132 from fastapi import Depends, FastAPI
133 from fastapi.security import APIKeyHeader
135 app = FastAPI()
137 header_scheme = APIKeyHeader(name="x-key")
140 @app.get("/items/")
141 async def read_items(key: str = Depends(header_scheme)):
142 return {"key": key}
143 ```
144 """
146 def __init__( 1abcde
147 self,
148 *,
149 name: Annotated[str, Doc("Header name.")],
150 scheme_name: Annotated[
151 Optional[str],
152 Doc(
153 """
154 Security scheme name.
156 It will be included in the generated OpenAPI (e.g. visible at `/docs`).
157 """
158 ),
159 ] = None,
160 description: Annotated[
161 Optional[str],
162 Doc(
163 """
164 Security scheme description.
166 It will be included in the generated OpenAPI (e.g. visible at `/docs`).
167 """
168 ),
169 ] = None,
170 auto_error: Annotated[
171 bool,
172 Doc(
173 """
174 By default, if the header is not provided, `APIKeyHeader` will
175 automatically cancel the request and send the client an error.
177 If `auto_error` is set to `False`, when the header is not available,
178 instead of erroring out, the dependency result will be `None`.
180 This is useful when you want to have optional authentication.
182 It is also useful when you want to have authentication that can be
183 provided in one of multiple optional ways (for example, in a header or
184 in an HTTP Bearer token).
185 """
186 ),
187 ] = True,
188 ):
189 self.model: APIKey = APIKey( 1abcde
190 **{"in": APIKeyIn.header}, # type: ignore[arg-type]
191 name=name,
192 description=description,
193 )
194 self.scheme_name = scheme_name or self.__class__.__name__ 1abcde
195 self.auto_error = auto_error 1abcde
197 async def __call__(self, request: Request) -> Optional[str]: 1abcde
198 api_key = request.headers.get(self.model.name) 1abcde
199 if not api_key: 1abcde
200 if self.auto_error: 1abcde
201 raise HTTPException( 1abcde
202 status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
203 )
204 else:
205 return None 1abcde
206 return api_key 1abcde
209class APIKeyCookie(APIKeyBase): 1abcde
210 """
211 API key authentication using a cookie.
213 This defines the name of the cookie that should be provided in the request with
214 the API key and integrates that into the OpenAPI documentation. It extracts
215 the key value sent in the cookie automatically and provides it as the dependency
216 result. But it doesn't define how to set that cookie.
218 ## Usage
220 Create an instance object and use that object as the dependency in `Depends()`.
222 The dependency result will be a string containing the key value.
224 ## Example
226 ```python
227 from fastapi import Depends, FastAPI
228 from fastapi.security import APIKeyCookie
230 app = FastAPI()
232 cookie_scheme = APIKeyCookie(name="session")
235 @app.get("/items/")
236 async def read_items(session: str = Depends(cookie_scheme)):
237 return {"session": session}
238 ```
239 """
241 def __init__( 1abcde
242 self,
243 *,
244 name: Annotated[str, Doc("Cookie name.")],
245 scheme_name: Annotated[
246 Optional[str],
247 Doc(
248 """
249 Security scheme name.
251 It will be included in the generated OpenAPI (e.g. visible at `/docs`).
252 """
253 ),
254 ] = None,
255 description: Annotated[
256 Optional[str],
257 Doc(
258 """
259 Security scheme description.
261 It will be included in the generated OpenAPI (e.g. visible at `/docs`).
262 """
263 ),
264 ] = None,
265 auto_error: Annotated[
266 bool,
267 Doc(
268 """
269 By default, if the cookie is not provided, `APIKeyCookie` will
270 automatically cancel the request and send the client an error.
272 If `auto_error` is set to `False`, when the cookie is not available,
273 instead of erroring out, the dependency result will be `None`.
275 This is useful when you want to have optional authentication.
277 It is also useful when you want to have authentication that can be
278 provided in one of multiple optional ways (for example, in a cookie or
279 in an HTTP Bearer token).
280 """
281 ),
282 ] = True,
283 ):
284 self.model: APIKey = APIKey( 1abcde
285 **{"in": APIKeyIn.cookie}, # type: ignore[arg-type]
286 name=name,
287 description=description,
288 )
289 self.scheme_name = scheme_name or self.__class__.__name__ 1abcde
290 self.auto_error = auto_error 1abcde
292 async def __call__(self, request: Request) -> Optional[str]: 1abcde
293 api_key = request.cookies.get(self.model.name) 1abcde
294 if not api_key: 1abcde
295 if self.auto_error: 1abcde
296 raise HTTPException( 1abcde
297 status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
298 )
299 else:
300 return None 1abcde
301 return api_key 1abcde