nexo-schemas 0.0.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nexo/schemas/__init__.py +0 -0
- nexo/schemas/application.py +292 -0
- nexo/schemas/connection.py +134 -0
- nexo/schemas/data.py +27 -0
- nexo/schemas/document.py +237 -0
- nexo/schemas/error/__init__.py +476 -0
- nexo/schemas/error/constants.py +50 -0
- nexo/schemas/error/descriptor.py +354 -0
- nexo/schemas/error/enums.py +40 -0
- nexo/schemas/error/metadata.py +15 -0
- nexo/schemas/error/spec.py +312 -0
- nexo/schemas/exception/__init__.py +0 -0
- nexo/schemas/exception/exc.py +911 -0
- nexo/schemas/exception/factory.py +1928 -0
- nexo/schemas/exception/handlers.py +110 -0
- nexo/schemas/google.py +14 -0
- nexo/schemas/key/__init__.py +0 -0
- nexo/schemas/key/rsa.py +131 -0
- nexo/schemas/metadata.py +21 -0
- nexo/schemas/mixins/__init__.py +0 -0
- nexo/schemas/mixins/filter.py +140 -0
- nexo/schemas/mixins/general.py +65 -0
- nexo/schemas/mixins/hierarchy.py +19 -0
- nexo/schemas/mixins/identity.py +387 -0
- nexo/schemas/mixins/parameter.py +50 -0
- nexo/schemas/mixins/service.py +40 -0
- nexo/schemas/mixins/sort.py +111 -0
- nexo/schemas/mixins/timestamp.py +192 -0
- nexo/schemas/model.py +240 -0
- nexo/schemas/operation/__init__.py +0 -0
- nexo/schemas/operation/action/__init__.py +9 -0
- nexo/schemas/operation/action/base.py +14 -0
- nexo/schemas/operation/action/resource.py +371 -0
- nexo/schemas/operation/action/status.py +8 -0
- nexo/schemas/operation/action/system.py +6 -0
- nexo/schemas/operation/action/websocket.py +6 -0
- nexo/schemas/operation/base.py +289 -0
- nexo/schemas/operation/constants.py +18 -0
- nexo/schemas/operation/context.py +68 -0
- nexo/schemas/operation/dependency.py +26 -0
- nexo/schemas/operation/enums.py +168 -0
- nexo/schemas/operation/extractor.py +36 -0
- nexo/schemas/operation/mixins.py +53 -0
- nexo/schemas/operation/request.py +1066 -0
- nexo/schemas/operation/resource.py +839 -0
- nexo/schemas/operation/system.py +55 -0
- nexo/schemas/operation/websocket.py +55 -0
- nexo/schemas/pagination.py +67 -0
- nexo/schemas/parameter.py +60 -0
- nexo/schemas/payload.py +116 -0
- nexo/schemas/resource.py +64 -0
- nexo/schemas/response.py +1041 -0
- nexo/schemas/security/__init__.py +0 -0
- nexo/schemas/security/api_key.py +63 -0
- nexo/schemas/security/authentication.py +848 -0
- nexo/schemas/security/authorization.py +922 -0
- nexo/schemas/security/enums.py +32 -0
- nexo/schemas/security/impersonation.py +179 -0
- nexo/schemas/security/token.py +402 -0
- nexo/schemas/security/types.py +17 -0
- nexo/schemas/success/__init__.py +0 -0
- nexo/schemas/success/descriptor.py +100 -0
- nexo/schemas/success/enums.py +23 -0
- nexo/schemas/user_agent.py +46 -0
- nexo_schemas-0.0.16.dist-info/METADATA +87 -0
- nexo_schemas-0.0.16.dist-info/RECORD +69 -0
- nexo_schemas-0.0.16.dist-info/WHEEL +5 -0
- nexo_schemas-0.0.16.dist-info/licenses/LICENSE +21 -0
- nexo_schemas-0.0.16.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,922 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
from collections.abc import Iterable, Sequence
|
|
4
|
+
from Crypto.PublicKey.RSA import RsaKey
|
|
5
|
+
from datetime import timedelta
|
|
6
|
+
from enum import StrEnum
|
|
7
|
+
from fastapi import status, HTTPException, Security, Query
|
|
8
|
+
from fastapi.requests import HTTPConnection, Request
|
|
9
|
+
from fastapi.security import (
|
|
10
|
+
APIKeyHeader,
|
|
11
|
+
HTTPAuthorizationCredentials,
|
|
12
|
+
HTTPBearer,
|
|
13
|
+
)
|
|
14
|
+
from fastapi.websockets import WebSocket
|
|
15
|
+
from pydantic import BaseModel, Field
|
|
16
|
+
from typing import (
|
|
17
|
+
Annotated,
|
|
18
|
+
Callable,
|
|
19
|
+
Generator,
|
|
20
|
+
Generic,
|
|
21
|
+
Literal,
|
|
22
|
+
Self,
|
|
23
|
+
TypeGuard,
|
|
24
|
+
TypeVar,
|
|
25
|
+
overload,
|
|
26
|
+
)
|
|
27
|
+
from nexo.enums.connection import Header, Protocol, OptProtocol
|
|
28
|
+
from nexo.types.misc import BytesOrStr
|
|
29
|
+
from nexo.types.string import ListOfStrs, OptStr
|
|
30
|
+
from .enums import Domain, OptDomain
|
|
31
|
+
from .token import TenantToken, SystemToken, AnyToken, TokenFactory
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Scheme(StrEnum):
|
|
35
|
+
API_KEY = "api_key"
|
|
36
|
+
BEARER_TOKEN = "bearer_token"
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def choices(cls) -> ListOfStrs:
|
|
40
|
+
return [e.value for e in cls]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
SchemeT = TypeVar("SchemeT", bound=Scheme)
|
|
44
|
+
OptScheme = Scheme | None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class Source(StrEnum):
|
|
48
|
+
HEADER = "header"
|
|
49
|
+
QUERY = "query"
|
|
50
|
+
STATE = "state"
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def choices(cls) -> ListOfStrs:
|
|
54
|
+
return [e.value for e in cls]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
OptSource = Source | None
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class GenericAuthorization(ABC, BaseModel, Generic[SchemeT]):
|
|
61
|
+
scheme: SchemeT = Field(..., description="Authorization's scheme")
|
|
62
|
+
credentials: Annotated[str, Field(..., description="Authorization's credentials")]
|
|
63
|
+
|
|
64
|
+
@overload
|
|
65
|
+
@classmethod
|
|
66
|
+
def from_state(
|
|
67
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[False]
|
|
68
|
+
) -> Self | None: ...
|
|
69
|
+
@overload
|
|
70
|
+
@classmethod
|
|
71
|
+
def from_state(
|
|
72
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[True] = True
|
|
73
|
+
) -> Self: ...
|
|
74
|
+
@classmethod
|
|
75
|
+
def from_state(
|
|
76
|
+
cls, conn: HTTPConnection, *, auto_error: bool = True
|
|
77
|
+
) -> Self | None:
|
|
78
|
+
authorization = getattr(conn.state, "authorization", None)
|
|
79
|
+
if isinstance(authorization, cls):
|
|
80
|
+
return authorization
|
|
81
|
+
|
|
82
|
+
if auto_error:
|
|
83
|
+
raise HTTPException(
|
|
84
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
85
|
+
detail="Invalid or unable to determine authorization in state",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
@abstractmethod
|
|
92
|
+
def from_header(
|
|
93
|
+
cls, conn: HTTPConnection, *, auto_error: bool = True
|
|
94
|
+
) -> Self | None:
|
|
95
|
+
"""Extract authorization from Header"""
|
|
96
|
+
|
|
97
|
+
@classmethod
|
|
98
|
+
@abstractmethod
|
|
99
|
+
def from_query(
|
|
100
|
+
cls, conn: HTTPConnection, *, auto_error: bool = True
|
|
101
|
+
) -> Self | None:
|
|
102
|
+
"""Extract authorization from Query"""
|
|
103
|
+
|
|
104
|
+
@overload
|
|
105
|
+
@classmethod
|
|
106
|
+
def extract(
|
|
107
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[False]
|
|
108
|
+
) -> Self | None: ...
|
|
109
|
+
@overload
|
|
110
|
+
@classmethod
|
|
111
|
+
def extract(
|
|
112
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[True] = True
|
|
113
|
+
) -> Self: ...
|
|
114
|
+
@classmethod
|
|
115
|
+
def extract(cls, conn: HTTPConnection, *, auto_error: bool = True) -> Self | None:
|
|
116
|
+
authorization = cls.from_state(conn, auto_error=auto_error)
|
|
117
|
+
if authorization is not None:
|
|
118
|
+
return authorization
|
|
119
|
+
|
|
120
|
+
authorization = cls.from_header(conn, auto_error=auto_error)
|
|
121
|
+
if authorization is not None:
|
|
122
|
+
return authorization
|
|
123
|
+
|
|
124
|
+
authorization = cls.from_query(conn, auto_error=auto_error)
|
|
125
|
+
if authorization is not None:
|
|
126
|
+
return authorization
|
|
127
|
+
|
|
128
|
+
if auto_error:
|
|
129
|
+
raise HTTPException(
|
|
130
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
131
|
+
detail="Invalid or unable to determine authorization",
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
return None
|
|
135
|
+
|
|
136
|
+
@overload
|
|
137
|
+
@classmethod
|
|
138
|
+
def as_dependency(
|
|
139
|
+
cls,
|
|
140
|
+
protocol: None = None,
|
|
141
|
+
*,
|
|
142
|
+
auto_error: Literal[False],
|
|
143
|
+
) -> Callable[
|
|
144
|
+
[HTTPConnection, HTTPAuthorizationCredentials | None, OptStr],
|
|
145
|
+
Self | None,
|
|
146
|
+
]: ...
|
|
147
|
+
@overload
|
|
148
|
+
@classmethod
|
|
149
|
+
def as_dependency(
|
|
150
|
+
cls,
|
|
151
|
+
protocol: None = None,
|
|
152
|
+
*,
|
|
153
|
+
auto_error: Literal[True] = True,
|
|
154
|
+
) -> Callable[
|
|
155
|
+
[HTTPConnection, HTTPAuthorizationCredentials | None, OptStr], Self
|
|
156
|
+
]: ...
|
|
157
|
+
@overload
|
|
158
|
+
@classmethod
|
|
159
|
+
def as_dependency(
|
|
160
|
+
cls,
|
|
161
|
+
protocol: Literal[Protocol.HTTP],
|
|
162
|
+
*,
|
|
163
|
+
auto_error: Literal[False],
|
|
164
|
+
) -> Callable[
|
|
165
|
+
[Request, HTTPAuthorizationCredentials | None, OptStr],
|
|
166
|
+
Self | None,
|
|
167
|
+
]: ...
|
|
168
|
+
@overload
|
|
169
|
+
@classmethod
|
|
170
|
+
def as_dependency(
|
|
171
|
+
cls,
|
|
172
|
+
protocol: Literal[Protocol.HTTP],
|
|
173
|
+
*,
|
|
174
|
+
auto_error: Literal[True] = True,
|
|
175
|
+
) -> Callable[[Request, HTTPAuthorizationCredentials | None, OptStr], Self]: ...
|
|
176
|
+
@overload
|
|
177
|
+
@classmethod
|
|
178
|
+
def as_dependency(
|
|
179
|
+
cls, protocol: Literal[Protocol.WEBSOCKET], *, auto_error: Literal[False]
|
|
180
|
+
) -> Callable[[WebSocket, OptStr, OptStr], Self | None]: ...
|
|
181
|
+
@overload
|
|
182
|
+
@classmethod
|
|
183
|
+
def as_dependency(
|
|
184
|
+
cls, protocol: Literal[Protocol.WEBSOCKET], *, auto_error: Literal[True] = True
|
|
185
|
+
) -> Callable[[WebSocket, OptStr, OptStr], Self]: ...
|
|
186
|
+
@classmethod
|
|
187
|
+
def as_dependency(
|
|
188
|
+
cls, protocol: OptProtocol = None, *, auto_error: bool = True
|
|
189
|
+
) -> (
|
|
190
|
+
Callable[
|
|
191
|
+
[HTTPConnection, HTTPAuthorizationCredentials | None, OptStr],
|
|
192
|
+
Self | None,
|
|
193
|
+
]
|
|
194
|
+
| Callable[
|
|
195
|
+
[HTTPConnection, HTTPAuthorizationCredentials | None, OptStr],
|
|
196
|
+
Self,
|
|
197
|
+
]
|
|
198
|
+
| Callable[
|
|
199
|
+
[Request, HTTPAuthorizationCredentials | None, OptStr],
|
|
200
|
+
Self | None,
|
|
201
|
+
]
|
|
202
|
+
| Callable[
|
|
203
|
+
[Request, HTTPAuthorizationCredentials | None, OptStr],
|
|
204
|
+
Self,
|
|
205
|
+
]
|
|
206
|
+
| Callable[[WebSocket, OptStr, OptStr], Self | None]
|
|
207
|
+
| Callable[[WebSocket, OptStr, OptStr], Self]
|
|
208
|
+
):
|
|
209
|
+
def _dependency(
|
|
210
|
+
conn: HTTPConnection,
|
|
211
|
+
# These are for documentation purpose only
|
|
212
|
+
bearer: Annotated[
|
|
213
|
+
HTTPAuthorizationCredentials | None,
|
|
214
|
+
Security(HTTPBearer(auto_error=False)),
|
|
215
|
+
],
|
|
216
|
+
api_key: Annotated[
|
|
217
|
+
OptStr,
|
|
218
|
+
Security(APIKeyHeader(name=Header.X_API_KEY.value, auto_error=False)),
|
|
219
|
+
],
|
|
220
|
+
) -> Self | None:
|
|
221
|
+
return cls.extract(conn, auto_error=auto_error)
|
|
222
|
+
|
|
223
|
+
def _request_dependency(
|
|
224
|
+
request: Request,
|
|
225
|
+
# These are for documentation purpose only
|
|
226
|
+
bearer: Annotated[
|
|
227
|
+
HTTPAuthorizationCredentials | None,
|
|
228
|
+
Security(HTTPBearer(auto_error=False)),
|
|
229
|
+
],
|
|
230
|
+
api_key: Annotated[
|
|
231
|
+
OptStr,
|
|
232
|
+
Security(APIKeyHeader(name=Header.X_API_KEY.value, auto_error=False)),
|
|
233
|
+
],
|
|
234
|
+
) -> Self | None:
|
|
235
|
+
return cls.extract(request, auto_error=auto_error)
|
|
236
|
+
|
|
237
|
+
def _websocket_dependency(
|
|
238
|
+
websocket: WebSocket,
|
|
239
|
+
# These are for documentation purpose only
|
|
240
|
+
bearer: Annotated[
|
|
241
|
+
OptStr,
|
|
242
|
+
Query(
|
|
243
|
+
alias=Header.AUTHORIZATION.value,
|
|
244
|
+
description="Authorization Query",
|
|
245
|
+
),
|
|
246
|
+
] = None,
|
|
247
|
+
api_key: Annotated[
|
|
248
|
+
OptStr,
|
|
249
|
+
Query(alias=Header.X_API_KEY.value, description="API Key Query"),
|
|
250
|
+
] = None,
|
|
251
|
+
) -> Self | None:
|
|
252
|
+
return cls.extract(websocket, auto_error=auto_error)
|
|
253
|
+
|
|
254
|
+
if protocol is None:
|
|
255
|
+
return _dependency
|
|
256
|
+
elif protocol is Protocol.HTTP:
|
|
257
|
+
return _request_dependency
|
|
258
|
+
elif protocol is Protocol.WEBSOCKET:
|
|
259
|
+
return _websocket_dependency
|
|
260
|
+
|
|
261
|
+
@overload
|
|
262
|
+
def parse_token(
|
|
263
|
+
self,
|
|
264
|
+
domain: Literal[Domain.TENANT],
|
|
265
|
+
*,
|
|
266
|
+
key: BytesOrStr | RsaKey,
|
|
267
|
+
audience: str | Iterable[str] | None = None,
|
|
268
|
+
subject: OptStr = None,
|
|
269
|
+
issuer: str | Sequence[str] | None = None,
|
|
270
|
+
leeway: float | timedelta = 0,
|
|
271
|
+
) -> TenantToken: ...
|
|
272
|
+
@overload
|
|
273
|
+
def parse_token(
|
|
274
|
+
self,
|
|
275
|
+
domain: Literal[Domain.SYSTEM],
|
|
276
|
+
*,
|
|
277
|
+
key: BytesOrStr | RsaKey,
|
|
278
|
+
audience: str | Iterable[str] | None = None,
|
|
279
|
+
subject: OptStr = None,
|
|
280
|
+
issuer: str | Sequence[str] | None = None,
|
|
281
|
+
leeway: float | timedelta = 0,
|
|
282
|
+
) -> SystemToken: ...
|
|
283
|
+
@overload
|
|
284
|
+
def parse_token(
|
|
285
|
+
self,
|
|
286
|
+
domain: None = None,
|
|
287
|
+
*,
|
|
288
|
+
key: BytesOrStr | RsaKey,
|
|
289
|
+
audience: str | Iterable[str] | None = None,
|
|
290
|
+
subject: OptStr = None,
|
|
291
|
+
issuer: str | Sequence[str] | None = None,
|
|
292
|
+
leeway: float | timedelta = 0,
|
|
293
|
+
) -> AnyToken: ...
|
|
294
|
+
def parse_token(
|
|
295
|
+
self,
|
|
296
|
+
domain: OptDomain = None,
|
|
297
|
+
*,
|
|
298
|
+
key: BytesOrStr | RsaKey,
|
|
299
|
+
audience: str | Iterable[str] | None = None,
|
|
300
|
+
subject: OptStr = None,
|
|
301
|
+
issuer: str | Sequence[str] | None = None,
|
|
302
|
+
leeway: float | timedelta = 0,
|
|
303
|
+
) -> AnyToken:
|
|
304
|
+
if self.scheme is not Scheme.BEARER_TOKEN:
|
|
305
|
+
raise ValueError(
|
|
306
|
+
f"Authorization scheme must be '{Scheme.BEARER_TOKEN}' to parse token"
|
|
307
|
+
)
|
|
308
|
+
return TokenFactory.from_string(
|
|
309
|
+
self.credentials,
|
|
310
|
+
domain,
|
|
311
|
+
key=key,
|
|
312
|
+
audience=audience,
|
|
313
|
+
subject=subject,
|
|
314
|
+
issuer=issuer,
|
|
315
|
+
leeway=leeway,
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
class BaseAuthorization(GenericAuthorization[Scheme]):
|
|
320
|
+
scheme: Annotated[Scheme, Field(..., description="Authorization's scheme")]
|
|
321
|
+
|
|
322
|
+
@overload
|
|
323
|
+
@classmethod
|
|
324
|
+
def from_header(
|
|
325
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[False]
|
|
326
|
+
) -> Self | None: ...
|
|
327
|
+
@overload
|
|
328
|
+
@classmethod
|
|
329
|
+
def from_header(
|
|
330
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[True] = True
|
|
331
|
+
) -> Self: ...
|
|
332
|
+
@classmethod
|
|
333
|
+
def from_header(
|
|
334
|
+
cls, conn: HTTPConnection, *, auto_error: bool = True
|
|
335
|
+
) -> Self | None:
|
|
336
|
+
token = conn.headers.get(Header.AUTHORIZATION, "")
|
|
337
|
+
scheme, _, credentials = token.partition(" ")
|
|
338
|
+
if token and scheme and credentials and scheme.lower() == "bearer":
|
|
339
|
+
return cls(scheme=Scheme.BEARER_TOKEN, credentials=credentials)
|
|
340
|
+
|
|
341
|
+
api_key = conn.headers.get(Header.X_API_KEY)
|
|
342
|
+
if api_key is not None:
|
|
343
|
+
return cls(scheme=Scheme.API_KEY, credentials=api_key)
|
|
344
|
+
|
|
345
|
+
if auto_error:
|
|
346
|
+
raise HTTPException(
|
|
347
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
348
|
+
detail="Invalid or unable to determine authorization from Headers",
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
return None
|
|
352
|
+
|
|
353
|
+
@overload
|
|
354
|
+
@classmethod
|
|
355
|
+
def from_query(
|
|
356
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[False]
|
|
357
|
+
) -> Self | None: ...
|
|
358
|
+
@overload
|
|
359
|
+
@classmethod
|
|
360
|
+
def from_query(
|
|
361
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[True] = True
|
|
362
|
+
) -> Self: ...
|
|
363
|
+
@classmethod
|
|
364
|
+
def from_query(
|
|
365
|
+
cls, conn: HTTPConnection, *, auto_error: bool = True
|
|
366
|
+
) -> Self | None:
|
|
367
|
+
token = conn.query_params.get(Header.AUTHORIZATION.value, None)
|
|
368
|
+
if token is not None:
|
|
369
|
+
return cls(scheme=Scheme.BEARER_TOKEN, credentials=token)
|
|
370
|
+
|
|
371
|
+
api_key = conn.query_params.get(Header.X_API_KEY.value)
|
|
372
|
+
if api_key is not None:
|
|
373
|
+
return cls(scheme=Scheme.API_KEY, credentials=api_key)
|
|
374
|
+
|
|
375
|
+
if auto_error:
|
|
376
|
+
raise HTTPException(
|
|
377
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
378
|
+
detail="Invalid or unable to determine authorization from Headers",
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
return None
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
class APIKeyAuthorization(GenericAuthorization[Literal[Scheme.API_KEY]]):
|
|
385
|
+
scheme: Annotated[
|
|
386
|
+
Literal[Scheme.API_KEY],
|
|
387
|
+
Field(Scheme.API_KEY, description="Authorization's scheme"),
|
|
388
|
+
] = Scheme.API_KEY
|
|
389
|
+
|
|
390
|
+
@overload
|
|
391
|
+
@classmethod
|
|
392
|
+
def from_header(
|
|
393
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[False]
|
|
394
|
+
) -> Self | None: ...
|
|
395
|
+
@overload
|
|
396
|
+
@classmethod
|
|
397
|
+
def from_header(
|
|
398
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[True] = True
|
|
399
|
+
) -> Self: ...
|
|
400
|
+
@classmethod
|
|
401
|
+
def from_header(
|
|
402
|
+
cls, conn: HTTPConnection, *, auto_error: bool = True
|
|
403
|
+
) -> Self | None:
|
|
404
|
+
api_key = conn.headers.get(Header.X_API_KEY)
|
|
405
|
+
if api_key is not None:
|
|
406
|
+
return cls(scheme=Scheme.API_KEY, credentials=api_key)
|
|
407
|
+
|
|
408
|
+
if auto_error:
|
|
409
|
+
raise HTTPException(
|
|
410
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
411
|
+
detail=f"Invalid or unable to determine authorization from {Header.X_API_KEY} Header",
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
return None
|
|
415
|
+
|
|
416
|
+
@overload
|
|
417
|
+
@classmethod
|
|
418
|
+
def from_query(
|
|
419
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[False]
|
|
420
|
+
) -> Self | None: ...
|
|
421
|
+
@overload
|
|
422
|
+
@classmethod
|
|
423
|
+
def from_query(
|
|
424
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[True] = True
|
|
425
|
+
) -> Self: ...
|
|
426
|
+
@classmethod
|
|
427
|
+
def from_query(
|
|
428
|
+
cls, conn: HTTPConnection, *, auto_error: bool = True
|
|
429
|
+
) -> Self | None:
|
|
430
|
+
api_key = conn.query_params.get(Header.X_API_KEY.value)
|
|
431
|
+
if api_key is not None:
|
|
432
|
+
return cls(scheme=Scheme.API_KEY, credentials=api_key)
|
|
433
|
+
|
|
434
|
+
if auto_error:
|
|
435
|
+
raise HTTPException(
|
|
436
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
437
|
+
detail=f"Invalid or unable to determine authorization from {Header.X_API_KEY} Query",
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
return None
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
class BearerTokenAuthorization(GenericAuthorization[Literal[Scheme.BEARER_TOKEN]]):
|
|
444
|
+
scheme: Annotated[
|
|
445
|
+
Literal[Scheme.BEARER_TOKEN],
|
|
446
|
+
Field(Scheme.BEARER_TOKEN, description="Authorization's scheme"),
|
|
447
|
+
] = Scheme.BEARER_TOKEN
|
|
448
|
+
|
|
449
|
+
@overload
|
|
450
|
+
@classmethod
|
|
451
|
+
def from_header(
|
|
452
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[False]
|
|
453
|
+
) -> Self | None: ...
|
|
454
|
+
@overload
|
|
455
|
+
@classmethod
|
|
456
|
+
def from_header(
|
|
457
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[True] = True
|
|
458
|
+
) -> Self: ...
|
|
459
|
+
@classmethod
|
|
460
|
+
def from_header(
|
|
461
|
+
cls, conn: HTTPConnection, *, auto_error: bool = True
|
|
462
|
+
) -> Self | None:
|
|
463
|
+
token = conn.headers.get(Header.AUTHORIZATION, "")
|
|
464
|
+
scheme, _, credentials = token.partition(" ")
|
|
465
|
+
if token and scheme and credentials and scheme.lower() == "bearer":
|
|
466
|
+
return cls(scheme=Scheme.BEARER_TOKEN, credentials=credentials)
|
|
467
|
+
|
|
468
|
+
if auto_error:
|
|
469
|
+
raise HTTPException(
|
|
470
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
471
|
+
detail=f"Invalid or unable to determine authorization from {Header.AUTHORIZATION} Header",
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
return None
|
|
475
|
+
|
|
476
|
+
@overload
|
|
477
|
+
@classmethod
|
|
478
|
+
def from_query(
|
|
479
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[False]
|
|
480
|
+
) -> Self | None: ...
|
|
481
|
+
@overload
|
|
482
|
+
@classmethod
|
|
483
|
+
def from_query(
|
|
484
|
+
cls, conn: HTTPConnection, *, auto_error: Literal[True] = True
|
|
485
|
+
) -> Self: ...
|
|
486
|
+
@classmethod
|
|
487
|
+
def from_query(
|
|
488
|
+
cls, conn: HTTPConnection, *, auto_error: bool = True
|
|
489
|
+
) -> Self | None:
|
|
490
|
+
token = conn.query_params.get(Header.AUTHORIZATION.value, None)
|
|
491
|
+
if token is not None:
|
|
492
|
+
return cls(scheme=Scheme.BEARER_TOKEN, credentials=token)
|
|
493
|
+
|
|
494
|
+
if auto_error:
|
|
495
|
+
raise HTTPException(
|
|
496
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
497
|
+
detail=f"Invalid or unable to determine authorization from {Header.AUTHORIZATION} Query",
|
|
498
|
+
)
|
|
499
|
+
|
|
500
|
+
return None
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
AnyAuthorization = BaseAuthorization | BearerTokenAuthorization | APIKeyAuthorization
|
|
504
|
+
AnyAuthorizationT = TypeVar("AnyAuthorizationT", bound=AnyAuthorization)
|
|
505
|
+
OptAnyAuthorization = AnyAuthorization | None
|
|
506
|
+
OptAnyAuthorizationT = TypeVar("OptAnyAuthorizationT", bound=OptAnyAuthorization)
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
def is_bearer_token(
|
|
510
|
+
authorization: AnyAuthorization,
|
|
511
|
+
) -> TypeGuard[BearerTokenAuthorization]:
|
|
512
|
+
return authorization.scheme is Scheme.BEARER_TOKEN
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
def is_api_key(authorization: AnyAuthorization) -> TypeGuard[APIKeyAuthorization]:
|
|
516
|
+
return authorization.scheme is Scheme.API_KEY
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
class AuthorizationMixin(BaseModel, Generic[OptAnyAuthorizationT]):
|
|
520
|
+
authorization: OptAnyAuthorizationT = Field(
|
|
521
|
+
...,
|
|
522
|
+
description="Authorization",
|
|
523
|
+
)
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
class APIKeyAuth(httpx.Auth):
|
|
527
|
+
def __init__(self, api_key: str) -> None:
|
|
528
|
+
self._auth_header = self._build_auth_header(api_key)
|
|
529
|
+
|
|
530
|
+
def auth_flow(
|
|
531
|
+
self, request: httpx.Request
|
|
532
|
+
) -> Generator[httpx.Request, httpx.Response, None]:
|
|
533
|
+
request.headers[Header.X_API_KEY.value] = self._auth_header
|
|
534
|
+
yield request
|
|
535
|
+
|
|
536
|
+
def _build_auth_header(self, api_key: str) -> str:
|
|
537
|
+
return api_key
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
class BearerTokenAuth(httpx.Auth):
|
|
541
|
+
def __init__(self, token: str) -> None:
|
|
542
|
+
self._auth_header = self._build_auth_header(token)
|
|
543
|
+
|
|
544
|
+
def auth_flow(
|
|
545
|
+
self, request: httpx.Request
|
|
546
|
+
) -> Generator[httpx.Request, httpx.Response, None]:
|
|
547
|
+
request.headers[Header.AUTHORIZATION] = self._auth_header
|
|
548
|
+
yield request
|
|
549
|
+
|
|
550
|
+
def _build_auth_header(self, token: str) -> str:
|
|
551
|
+
return f"Bearer {token}"
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
AnyHTTPXAuthorization = APIKeyAuth | BearerTokenAuth
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
class AuthorizationFactory:
|
|
558
|
+
@overload
|
|
559
|
+
@classmethod
|
|
560
|
+
def extract(
|
|
561
|
+
cls,
|
|
562
|
+
scheme: None = None,
|
|
563
|
+
source: OptSource = None,
|
|
564
|
+
*,
|
|
565
|
+
conn: HTTPConnection,
|
|
566
|
+
auto_error: Literal[False],
|
|
567
|
+
) -> BaseAuthorization | None: ...
|
|
568
|
+
@overload
|
|
569
|
+
@classmethod
|
|
570
|
+
def extract(
|
|
571
|
+
cls,
|
|
572
|
+
scheme: Literal[Scheme.API_KEY],
|
|
573
|
+
source: OptSource = None,
|
|
574
|
+
*,
|
|
575
|
+
conn: HTTPConnection,
|
|
576
|
+
auto_error: Literal[False],
|
|
577
|
+
) -> APIKeyAuthorization | None: ...
|
|
578
|
+
@overload
|
|
579
|
+
@classmethod
|
|
580
|
+
def extract(
|
|
581
|
+
cls,
|
|
582
|
+
scheme: Literal[Scheme.BEARER_TOKEN],
|
|
583
|
+
source: OptSource = None,
|
|
584
|
+
*,
|
|
585
|
+
conn: HTTPConnection,
|
|
586
|
+
auto_error: Literal[False],
|
|
587
|
+
) -> BearerTokenAuthorization | None: ...
|
|
588
|
+
@overload
|
|
589
|
+
@classmethod
|
|
590
|
+
def extract(
|
|
591
|
+
cls,
|
|
592
|
+
scheme: None = None,
|
|
593
|
+
source: OptSource = None,
|
|
594
|
+
*,
|
|
595
|
+
conn: HTTPConnection,
|
|
596
|
+
auto_error: Literal[True] = True,
|
|
597
|
+
) -> BaseAuthorization: ...
|
|
598
|
+
@overload
|
|
599
|
+
@classmethod
|
|
600
|
+
def extract(
|
|
601
|
+
cls,
|
|
602
|
+
scheme: Literal[Scheme.API_KEY],
|
|
603
|
+
source: OptSource = None,
|
|
604
|
+
*,
|
|
605
|
+
conn: HTTPConnection,
|
|
606
|
+
auto_error: Literal[True] = True,
|
|
607
|
+
) -> APIKeyAuthorization: ...
|
|
608
|
+
@overload
|
|
609
|
+
@classmethod
|
|
610
|
+
def extract(
|
|
611
|
+
cls,
|
|
612
|
+
scheme: Literal[Scheme.BEARER_TOKEN],
|
|
613
|
+
source: OptSource = None,
|
|
614
|
+
*,
|
|
615
|
+
conn: HTTPConnection,
|
|
616
|
+
auto_error: Literal[True] = True,
|
|
617
|
+
) -> BearerTokenAuthorization: ...
|
|
618
|
+
@classmethod
|
|
619
|
+
def extract(
|
|
620
|
+
cls,
|
|
621
|
+
scheme: OptScheme = None,
|
|
622
|
+
source: OptSource = None,
|
|
623
|
+
*,
|
|
624
|
+
conn: HTTPConnection,
|
|
625
|
+
auto_error: bool = True,
|
|
626
|
+
) -> OptAnyAuthorization:
|
|
627
|
+
if scheme is None:
|
|
628
|
+
if source is None:
|
|
629
|
+
return BaseAuthorization.extract(conn, auto_error=auto_error)
|
|
630
|
+
elif source is Source.HEADER:
|
|
631
|
+
return BaseAuthorization.from_header(conn, auto_error=auto_error)
|
|
632
|
+
elif source is Source.QUERY:
|
|
633
|
+
return BaseAuthorization.from_query(conn, auto_error=auto_error)
|
|
634
|
+
elif source is Source.STATE:
|
|
635
|
+
return BaseAuthorization.from_state(conn, auto_error=auto_error)
|
|
636
|
+
elif scheme is Scheme.API_KEY:
|
|
637
|
+
if source is None:
|
|
638
|
+
return APIKeyAuthorization.extract(conn, auto_error=auto_error)
|
|
639
|
+
elif source is Source.HEADER:
|
|
640
|
+
return APIKeyAuthorization.from_header(conn, auto_error=auto_error)
|
|
641
|
+
elif source is Source.QUERY:
|
|
642
|
+
return APIKeyAuthorization.from_query(conn, auto_error=auto_error)
|
|
643
|
+
elif source is Source.STATE:
|
|
644
|
+
return APIKeyAuthorization.from_state(conn, auto_error=auto_error)
|
|
645
|
+
elif scheme is Scheme.BEARER_TOKEN:
|
|
646
|
+
if source is None:
|
|
647
|
+
return BearerTokenAuthorization.extract(conn, auto_error=auto_error)
|
|
648
|
+
elif source is Source.HEADER:
|
|
649
|
+
return BearerTokenAuthorization.from_header(conn, auto_error=auto_error)
|
|
650
|
+
elif source is Source.QUERY:
|
|
651
|
+
return BearerTokenAuthorization.from_query(conn, auto_error=auto_error)
|
|
652
|
+
elif source is Source.STATE:
|
|
653
|
+
return BearerTokenAuthorization.from_state(conn, auto_error=auto_error)
|
|
654
|
+
|
|
655
|
+
@overload
|
|
656
|
+
@classmethod
|
|
657
|
+
def as_dependency(
|
|
658
|
+
cls,
|
|
659
|
+
protocol: None = None,
|
|
660
|
+
*,
|
|
661
|
+
scheme: None = None,
|
|
662
|
+
auto_error: Literal[False],
|
|
663
|
+
) -> Callable[
|
|
664
|
+
[HTTPConnection, HTTPAuthorizationCredentials | None, OptStr],
|
|
665
|
+
BaseAuthorization | None,
|
|
666
|
+
]: ...
|
|
667
|
+
@overload
|
|
668
|
+
@classmethod
|
|
669
|
+
def as_dependency(
|
|
670
|
+
cls,
|
|
671
|
+
protocol: None = None,
|
|
672
|
+
*,
|
|
673
|
+
scheme: Literal[Scheme.API_KEY],
|
|
674
|
+
auto_error: Literal[False],
|
|
675
|
+
) -> Callable[
|
|
676
|
+
[HTTPConnection, HTTPAuthorizationCredentials | None, OptStr],
|
|
677
|
+
APIKeyAuthorization | None,
|
|
678
|
+
]: ...
|
|
679
|
+
@overload
|
|
680
|
+
@classmethod
|
|
681
|
+
def as_dependency(
|
|
682
|
+
cls,
|
|
683
|
+
protocol: None = None,
|
|
684
|
+
*,
|
|
685
|
+
scheme: Literal[Scheme.BEARER_TOKEN],
|
|
686
|
+
auto_error: Literal[False],
|
|
687
|
+
) -> Callable[
|
|
688
|
+
[HTTPConnection, HTTPAuthorizationCredentials | None, OptStr],
|
|
689
|
+
BearerTokenAuthorization | None,
|
|
690
|
+
]: ...
|
|
691
|
+
@overload
|
|
692
|
+
@classmethod
|
|
693
|
+
def as_dependency(
|
|
694
|
+
cls,
|
|
695
|
+
protocol: None = None,
|
|
696
|
+
*,
|
|
697
|
+
scheme: None = None,
|
|
698
|
+
auto_error: Literal[True] = True,
|
|
699
|
+
) -> Callable[
|
|
700
|
+
[HTTPConnection, HTTPAuthorizationCredentials | None, OptStr],
|
|
701
|
+
BaseAuthorization,
|
|
702
|
+
]: ...
|
|
703
|
+
@overload
|
|
704
|
+
@classmethod
|
|
705
|
+
def as_dependency(
|
|
706
|
+
cls,
|
|
707
|
+
protocol: None = None,
|
|
708
|
+
*,
|
|
709
|
+
scheme: Literal[Scheme.API_KEY],
|
|
710
|
+
auto_error: Literal[True] = True,
|
|
711
|
+
) -> Callable[
|
|
712
|
+
[HTTPConnection, HTTPAuthorizationCredentials | None, OptStr],
|
|
713
|
+
APIKeyAuthorization,
|
|
714
|
+
]: ...
|
|
715
|
+
@overload
|
|
716
|
+
@classmethod
|
|
717
|
+
def as_dependency(
|
|
718
|
+
cls,
|
|
719
|
+
protocol: None = None,
|
|
720
|
+
*,
|
|
721
|
+
scheme: Literal[Scheme.BEARER_TOKEN],
|
|
722
|
+
auto_error: Literal[True] = True,
|
|
723
|
+
) -> Callable[
|
|
724
|
+
[HTTPConnection, HTTPAuthorizationCredentials | None, OptStr],
|
|
725
|
+
BearerTokenAuthorization,
|
|
726
|
+
]: ...
|
|
727
|
+
|
|
728
|
+
@overload
|
|
729
|
+
@classmethod
|
|
730
|
+
def as_dependency(
|
|
731
|
+
cls,
|
|
732
|
+
protocol: Literal[Protocol.HTTP] = Protocol.HTTP,
|
|
733
|
+
*,
|
|
734
|
+
scheme: None = None,
|
|
735
|
+
auto_error: Literal[False],
|
|
736
|
+
) -> Callable[
|
|
737
|
+
[Request, HTTPAuthorizationCredentials | None, OptStr],
|
|
738
|
+
BaseAuthorization | None,
|
|
739
|
+
]: ...
|
|
740
|
+
@overload
|
|
741
|
+
@classmethod
|
|
742
|
+
def as_dependency(
|
|
743
|
+
cls,
|
|
744
|
+
protocol: Literal[Protocol.HTTP] = Protocol.HTTP,
|
|
745
|
+
*,
|
|
746
|
+
scheme: Literal[Scheme.API_KEY],
|
|
747
|
+
auto_error: Literal[False],
|
|
748
|
+
) -> Callable[
|
|
749
|
+
[Request, HTTPAuthorizationCredentials | None, OptStr],
|
|
750
|
+
APIKeyAuthorization | None,
|
|
751
|
+
]: ...
|
|
752
|
+
@overload
|
|
753
|
+
@classmethod
|
|
754
|
+
def as_dependency(
|
|
755
|
+
cls,
|
|
756
|
+
protocol: Literal[Protocol.HTTP] = Protocol.HTTP,
|
|
757
|
+
*,
|
|
758
|
+
scheme: Literal[Scheme.BEARER_TOKEN],
|
|
759
|
+
auto_error: Literal[False],
|
|
760
|
+
) -> Callable[
|
|
761
|
+
[Request, HTTPAuthorizationCredentials | None, OptStr],
|
|
762
|
+
BearerTokenAuthorization | None,
|
|
763
|
+
]: ...
|
|
764
|
+
@overload
|
|
765
|
+
@classmethod
|
|
766
|
+
def as_dependency(
|
|
767
|
+
cls,
|
|
768
|
+
protocol: Literal[Protocol.HTTP] = Protocol.HTTP,
|
|
769
|
+
*,
|
|
770
|
+
scheme: None = None,
|
|
771
|
+
auto_error: Literal[True] = True,
|
|
772
|
+
) -> Callable[
|
|
773
|
+
[Request, HTTPAuthorizationCredentials | None, OptStr],
|
|
774
|
+
BaseAuthorization,
|
|
775
|
+
]: ...
|
|
776
|
+
@overload
|
|
777
|
+
@classmethod
|
|
778
|
+
def as_dependency(
|
|
779
|
+
cls,
|
|
780
|
+
protocol: Literal[Protocol.HTTP] = Protocol.HTTP,
|
|
781
|
+
*,
|
|
782
|
+
scheme: Literal[Scheme.API_KEY],
|
|
783
|
+
auto_error: Literal[True] = True,
|
|
784
|
+
) -> Callable[
|
|
785
|
+
[Request, HTTPAuthorizationCredentials | None, OptStr],
|
|
786
|
+
APIKeyAuthorization,
|
|
787
|
+
]: ...
|
|
788
|
+
@overload
|
|
789
|
+
@classmethod
|
|
790
|
+
def as_dependency(
|
|
791
|
+
cls,
|
|
792
|
+
protocol: Literal[Protocol.HTTP] = Protocol.HTTP,
|
|
793
|
+
*,
|
|
794
|
+
scheme: Literal[Scheme.BEARER_TOKEN],
|
|
795
|
+
auto_error: Literal[True] = True,
|
|
796
|
+
) -> Callable[
|
|
797
|
+
[Request, HTTPAuthorizationCredentials | None, OptStr],
|
|
798
|
+
BearerTokenAuthorization,
|
|
799
|
+
]: ...
|
|
800
|
+
|
|
801
|
+
@overload
|
|
802
|
+
@classmethod
|
|
803
|
+
def as_dependency(
|
|
804
|
+
cls,
|
|
805
|
+
protocol: Literal[Protocol.WEBSOCKET],
|
|
806
|
+
*,
|
|
807
|
+
scheme: None = None,
|
|
808
|
+
auto_error: Literal[False],
|
|
809
|
+
) -> Callable[[WebSocket, OptStr, OptStr], BaseAuthorization | None]: ...
|
|
810
|
+
@overload
|
|
811
|
+
@classmethod
|
|
812
|
+
def as_dependency(
|
|
813
|
+
cls,
|
|
814
|
+
protocol: Literal[Protocol.WEBSOCKET],
|
|
815
|
+
*,
|
|
816
|
+
scheme: Literal[Scheme.API_KEY],
|
|
817
|
+
auto_error: Literal[False],
|
|
818
|
+
) -> Callable[[WebSocket, OptStr, OptStr], APIKeyAuthorization | None]: ...
|
|
819
|
+
@overload
|
|
820
|
+
@classmethod
|
|
821
|
+
def as_dependency(
|
|
822
|
+
cls,
|
|
823
|
+
protocol: Literal[Protocol.WEBSOCKET],
|
|
824
|
+
*,
|
|
825
|
+
scheme: Literal[Scheme.BEARER_TOKEN],
|
|
826
|
+
auto_error: Literal[False],
|
|
827
|
+
) -> Callable[[WebSocket, OptStr, OptStr], BearerTokenAuthorization | None]: ...
|
|
828
|
+
@overload
|
|
829
|
+
@classmethod
|
|
830
|
+
def as_dependency(
|
|
831
|
+
cls,
|
|
832
|
+
protocol: Literal[Protocol.WEBSOCKET],
|
|
833
|
+
*,
|
|
834
|
+
scheme: None = None,
|
|
835
|
+
auto_error: Literal[True] = True,
|
|
836
|
+
) -> Callable[[WebSocket, OptStr, OptStr], BaseAuthorization]: ...
|
|
837
|
+
@overload
|
|
838
|
+
@classmethod
|
|
839
|
+
def as_dependency(
|
|
840
|
+
cls,
|
|
841
|
+
protocol: Literal[Protocol.WEBSOCKET],
|
|
842
|
+
*,
|
|
843
|
+
scheme: Literal[Scheme.API_KEY],
|
|
844
|
+
auto_error: Literal[True] = True,
|
|
845
|
+
) -> Callable[[WebSocket, OptStr, OptStr], APIKeyAuthorization]: ...
|
|
846
|
+
@overload
|
|
847
|
+
@classmethod
|
|
848
|
+
def as_dependency(
|
|
849
|
+
cls,
|
|
850
|
+
protocol: Literal[Protocol.WEBSOCKET],
|
|
851
|
+
*,
|
|
852
|
+
scheme: Literal[Scheme.BEARER_TOKEN],
|
|
853
|
+
auto_error: Literal[True] = True,
|
|
854
|
+
) -> Callable[[WebSocket, OptStr, OptStr], BearerTokenAuthorization]: ...
|
|
855
|
+
|
|
856
|
+
@classmethod
|
|
857
|
+
def as_dependency(
|
|
858
|
+
cls,
|
|
859
|
+
protocol: OptProtocol = None,
|
|
860
|
+
*,
|
|
861
|
+
scheme: OptScheme = None,
|
|
862
|
+
auto_error: bool = True,
|
|
863
|
+
) -> (
|
|
864
|
+
Callable[
|
|
865
|
+
[HTTPConnection, HTTPAuthorizationCredentials | None, OptStr],
|
|
866
|
+
OptAnyAuthorization,
|
|
867
|
+
]
|
|
868
|
+
| Callable[
|
|
869
|
+
[HTTPConnection, HTTPAuthorizationCredentials | None, OptStr],
|
|
870
|
+
AnyAuthorization,
|
|
871
|
+
]
|
|
872
|
+
| Callable[
|
|
873
|
+
[Request, HTTPAuthorizationCredentials | None, OptStr],
|
|
874
|
+
OptAnyAuthorization,
|
|
875
|
+
]
|
|
876
|
+
| Callable[
|
|
877
|
+
[Request, HTTPAuthorizationCredentials | None, OptStr],
|
|
878
|
+
AnyAuthorization,
|
|
879
|
+
]
|
|
880
|
+
| Callable[[WebSocket, OptStr, OptStr], OptAnyAuthorization]
|
|
881
|
+
| Callable[[WebSocket, OptStr, OptStr], AnyAuthorization]
|
|
882
|
+
):
|
|
883
|
+
if scheme is None:
|
|
884
|
+
return BaseAuthorization.as_dependency(protocol, auto_error=auto_error)
|
|
885
|
+
elif scheme is Scheme.API_KEY:
|
|
886
|
+
return APIKeyAuthorization.as_dependency(protocol, auto_error=auto_error)
|
|
887
|
+
elif scheme is Scheme.BEARER_TOKEN:
|
|
888
|
+
return BearerTokenAuthorization.as_dependency(
|
|
889
|
+
protocol, auto_error=auto_error
|
|
890
|
+
)
|
|
891
|
+
|
|
892
|
+
@overload
|
|
893
|
+
@classmethod
|
|
894
|
+
def httpx_auth(
|
|
895
|
+
cls,
|
|
896
|
+
scheme: Literal[Scheme.API_KEY],
|
|
897
|
+
*,
|
|
898
|
+
authorization: str | APIKeyAuthorization,
|
|
899
|
+
) -> APIKeyAuth: ...
|
|
900
|
+
@overload
|
|
901
|
+
@classmethod
|
|
902
|
+
def httpx_auth(
|
|
903
|
+
cls,
|
|
904
|
+
scheme: Literal[Scheme.BEARER_TOKEN] = Scheme.BEARER_TOKEN,
|
|
905
|
+
*,
|
|
906
|
+
authorization: str | BearerTokenAuthorization,
|
|
907
|
+
) -> BearerTokenAuth: ...
|
|
908
|
+
@classmethod
|
|
909
|
+
def httpx_auth(
|
|
910
|
+
cls,
|
|
911
|
+
scheme: Scheme = Scheme.BEARER_TOKEN,
|
|
912
|
+
*,
|
|
913
|
+
authorization: str | AnyAuthorization,
|
|
914
|
+
) -> AnyHTTPXAuthorization:
|
|
915
|
+
if isinstance(authorization, str):
|
|
916
|
+
token = authorization
|
|
917
|
+
else:
|
|
918
|
+
token = authorization.credentials
|
|
919
|
+
if scheme is Scheme.API_KEY:
|
|
920
|
+
return APIKeyAuth(token)
|
|
921
|
+
elif scheme is Scheme.BEARER_TOKEN:
|
|
922
|
+
return BearerTokenAuth(token)
|