fastapi-toolsets 4.0.0__tar.gz → 4.1.0__tar.gz
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.
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/PKG-INFO +1 -1
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/pyproject.toml +1 -1
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/__init__.py +1 -1
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/crud/factory.py +37 -14
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/db.py +73 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/LICENSE +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/README.md +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/_imports.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/cli/__init__.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/cli/app.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/cli/commands/__init__.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/cli/commands/fixtures.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/cli/config.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/cli/pyproject.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/cli/utils.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/crud/__init__.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/crud/search.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/dependencies.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/exceptions/__init__.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/exceptions/exceptions.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/exceptions/handler.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/fixtures/__init__.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/fixtures/enum.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/fixtures/registry.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/fixtures/utils.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/logger.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/metrics/__init__.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/metrics/handler.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/metrics/registry.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/models/__init__.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/models/columns.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/models/watched.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/py.typed +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/pytest/__init__.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/pytest/plugin.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/pytest/utils.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/schemas.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/__init__.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/abc.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/oauth.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/sources/__init__.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/sources/bearer.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/sources/cookie.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/sources/header.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/sources/multi.py +0 -0
- {fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/types.py +0 -0
|
@@ -10,7 +10,7 @@ from collections.abc import Awaitable, Callable, Sequence
|
|
|
10
10
|
from datetime import date, datetime
|
|
11
11
|
from decimal import Decimal
|
|
12
12
|
from enum import Enum
|
|
13
|
-
from typing import Any, ClassVar, Generic, Literal, Self, cast, overload
|
|
13
|
+
from typing import Any, ClassVar, Generic, Literal, Self, TypeAlias, cast, overload
|
|
14
14
|
|
|
15
15
|
from fastapi import Query
|
|
16
16
|
from pydantic import BaseModel
|
|
@@ -52,6 +52,19 @@ from .search import (
|
|
|
52
52
|
)
|
|
53
53
|
|
|
54
54
|
|
|
55
|
+
_ForUpdateMode: TypeAlias = bool | Literal["nowait", "skip_locked"]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _apply_for_update(q: Any, mode: _ForUpdateMode) -> Any:
|
|
59
|
+
if not mode:
|
|
60
|
+
return q
|
|
61
|
+
if mode == "nowait":
|
|
62
|
+
return q.with_for_update(nowait=True)
|
|
63
|
+
if mode == "skip_locked":
|
|
64
|
+
return q.with_for_update(skip_locked=True)
|
|
65
|
+
return q.with_for_update()
|
|
66
|
+
|
|
67
|
+
|
|
55
68
|
class _CursorDirection(str, Enum):
|
|
56
69
|
NEXT = "next"
|
|
57
70
|
PREV = "prev"
|
|
@@ -733,7 +746,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
733
746
|
*,
|
|
734
747
|
joins: JoinType | None = None,
|
|
735
748
|
outer_join: bool = False,
|
|
736
|
-
with_for_update:
|
|
749
|
+
with_for_update: _ForUpdateMode = False,
|
|
737
750
|
load_options: Sequence[ExecutableOption] | None = None,
|
|
738
751
|
schema: type[SchemaType],
|
|
739
752
|
) -> Response[SchemaType]: ...
|
|
@@ -747,7 +760,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
747
760
|
*,
|
|
748
761
|
joins: JoinType | None = None,
|
|
749
762
|
outer_join: bool = False,
|
|
750
|
-
with_for_update:
|
|
763
|
+
with_for_update: _ForUpdateMode = False,
|
|
751
764
|
load_options: Sequence[ExecutableOption] | None = None,
|
|
752
765
|
schema: None = ...,
|
|
753
766
|
) -> ModelType: ...
|
|
@@ -760,7 +773,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
760
773
|
*,
|
|
761
774
|
joins: JoinType | None = None,
|
|
762
775
|
outer_join: bool = False,
|
|
763
|
-
with_for_update:
|
|
776
|
+
with_for_update: _ForUpdateMode = False,
|
|
764
777
|
load_options: Sequence[ExecutableOption] | None = None,
|
|
765
778
|
schema: type[BaseModel] | None = None,
|
|
766
779
|
) -> ModelType | Response[Any]:
|
|
@@ -805,7 +818,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
805
818
|
*,
|
|
806
819
|
joins: JoinType | None = None,
|
|
807
820
|
outer_join: bool = False,
|
|
808
|
-
with_for_update:
|
|
821
|
+
with_for_update: _ForUpdateMode = False,
|
|
809
822
|
load_options: Sequence[ExecutableOption] | None = None,
|
|
810
823
|
schema: type[SchemaType],
|
|
811
824
|
) -> Response[SchemaType] | None: ...
|
|
@@ -819,7 +832,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
819
832
|
*,
|
|
820
833
|
joins: JoinType | None = None,
|
|
821
834
|
outer_join: bool = False,
|
|
822
|
-
with_for_update:
|
|
835
|
+
with_for_update: _ForUpdateMode = False,
|
|
823
836
|
load_options: Sequence[ExecutableOption] | None = None,
|
|
824
837
|
schema: None = ...,
|
|
825
838
|
) -> ModelType | None: ...
|
|
@@ -832,7 +845,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
832
845
|
*,
|
|
833
846
|
joins: JoinType | None = None,
|
|
834
847
|
outer_join: bool = False,
|
|
835
|
-
with_for_update:
|
|
848
|
+
with_for_update: _ForUpdateMode = False,
|
|
836
849
|
load_options: Sequence[ExecutableOption] | None = None,
|
|
837
850
|
schema: type[BaseModel] | None = None,
|
|
838
851
|
) -> ModelType | Response[Any] | None:
|
|
@@ -864,8 +877,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
864
877
|
q = q.where(and_(*filters))
|
|
865
878
|
if resolved := cls._resolve_load_options(load_options):
|
|
866
879
|
q = q.options(*resolved)
|
|
867
|
-
|
|
868
|
-
q = q.with_for_update()
|
|
880
|
+
q = _apply_for_update(q, with_for_update)
|
|
869
881
|
result = await session.execute(q)
|
|
870
882
|
item = result.unique().scalar_one_or_none()
|
|
871
883
|
if item is None:
|
|
@@ -884,7 +896,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
884
896
|
*,
|
|
885
897
|
joins: JoinType | None = None,
|
|
886
898
|
outer_join: bool = False,
|
|
887
|
-
with_for_update:
|
|
899
|
+
with_for_update: _ForUpdateMode = False,
|
|
888
900
|
load_options: Sequence[ExecutableOption] | None = None,
|
|
889
901
|
schema: type[SchemaType],
|
|
890
902
|
) -> Response[SchemaType] | None: ...
|
|
@@ -898,7 +910,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
898
910
|
*,
|
|
899
911
|
joins: JoinType | None = None,
|
|
900
912
|
outer_join: bool = False,
|
|
901
|
-
with_for_update:
|
|
913
|
+
with_for_update: _ForUpdateMode = False,
|
|
902
914
|
load_options: Sequence[ExecutableOption] | None = None,
|
|
903
915
|
schema: None = ...,
|
|
904
916
|
) -> ModelType | None: ...
|
|
@@ -911,7 +923,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
911
923
|
*,
|
|
912
924
|
joins: JoinType | None = None,
|
|
913
925
|
outer_join: bool = False,
|
|
914
|
-
with_for_update:
|
|
926
|
+
with_for_update: _ForUpdateMode = False,
|
|
915
927
|
load_options: Sequence[ExecutableOption] | None = None,
|
|
916
928
|
schema: type[BaseModel] | None = None,
|
|
917
929
|
) -> ModelType | Response[Any] | None:
|
|
@@ -937,8 +949,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
937
949
|
q = q.where(and_(*filters))
|
|
938
950
|
if resolved := cls._resolve_load_options(load_options):
|
|
939
951
|
q = q.options(*resolved)
|
|
940
|
-
|
|
941
|
-
q = q.with_for_update()
|
|
952
|
+
q = _apply_for_update(q, with_for_update)
|
|
942
953
|
result = await session.execute(q)
|
|
943
954
|
item = result.unique().scalars().first()
|
|
944
955
|
if item is None:
|
|
@@ -956,6 +967,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
956
967
|
filters: list[Any] | None = None,
|
|
957
968
|
joins: JoinType | None = None,
|
|
958
969
|
outer_join: bool = False,
|
|
970
|
+
with_for_update: _ForUpdateMode = False,
|
|
959
971
|
load_options: Sequence[ExecutableOption] | None = None,
|
|
960
972
|
order_by: OrderByClause | None = None,
|
|
961
973
|
limit: int | None = None,
|
|
@@ -968,6 +980,9 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
968
980
|
filters: List of SQLAlchemy filter conditions
|
|
969
981
|
joins: List of (model, condition) tuples for joining related tables
|
|
970
982
|
outer_join: Use LEFT OUTER JOIN instead of INNER JOIN
|
|
983
|
+
with_for_update: Lock rows for update. ``True`` for plain ``FOR UPDATE``,
|
|
984
|
+
``"nowait"`` for ``FOR UPDATE NOWAIT``, ``"skip_locked"`` for
|
|
985
|
+
``FOR UPDATE SKIP LOCKED``.
|
|
971
986
|
load_options: SQLAlchemy loader options
|
|
972
987
|
order_by: Column or list of columns to order by
|
|
973
988
|
limit: Max number of rows to return
|
|
@@ -982,6 +997,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
982
997
|
q = q.where(and_(*filters))
|
|
983
998
|
if resolved := cls._resolve_load_options(load_options):
|
|
984
999
|
q = q.options(*resolved)
|
|
1000
|
+
q = _apply_for_update(q, with_for_update)
|
|
985
1001
|
if order_by is not None:
|
|
986
1002
|
q = q.order_by(order_by)
|
|
987
1003
|
if offset is not None:
|
|
@@ -1001,6 +1017,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
1001
1017
|
*,
|
|
1002
1018
|
exclude_unset: bool = True,
|
|
1003
1019
|
exclude_none: bool = False,
|
|
1020
|
+
with_for_update: _ForUpdateMode = False,
|
|
1004
1021
|
schema: type[SchemaType],
|
|
1005
1022
|
) -> Response[SchemaType]: ...
|
|
1006
1023
|
|
|
@@ -1014,6 +1031,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
1014
1031
|
*,
|
|
1015
1032
|
exclude_unset: bool = True,
|
|
1016
1033
|
exclude_none: bool = False,
|
|
1034
|
+
with_for_update: _ForUpdateMode = False,
|
|
1017
1035
|
schema: None = ...,
|
|
1018
1036
|
) -> ModelType: ...
|
|
1019
1037
|
|
|
@@ -1026,6 +1044,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
1026
1044
|
*,
|
|
1027
1045
|
exclude_unset: bool = True,
|
|
1028
1046
|
exclude_none: bool = False,
|
|
1047
|
+
with_for_update: _ForUpdateMode = False,
|
|
1029
1048
|
schema: type[BaseModel] | None = None,
|
|
1030
1049
|
) -> ModelType | Response[Any]:
|
|
1031
1050
|
"""Update a record in the database.
|
|
@@ -1036,6 +1055,9 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
1036
1055
|
filters: List of SQLAlchemy filter conditions
|
|
1037
1056
|
exclude_unset: Exclude fields not explicitly set in the schema
|
|
1038
1057
|
exclude_none: Exclude fields with None value
|
|
1058
|
+
with_for_update: Lock the row before updating. ``True`` for plain
|
|
1059
|
+
``FOR UPDATE``, ``"nowait"`` for ``FOR UPDATE NOWAIT``,
|
|
1060
|
+
``"skip_locked"`` for ``FOR UPDATE SKIP LOCKED``.
|
|
1039
1061
|
schema: Pydantic schema to serialize the result into. When provided,
|
|
1040
1062
|
the result is automatically wrapped in a ``Response[schema]``.
|
|
1041
1063
|
|
|
@@ -1059,6 +1081,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
1059
1081
|
db_model = await cls.get(
|
|
1060
1082
|
session=session,
|
|
1061
1083
|
filters=filters,
|
|
1084
|
+
with_for_update=with_for_update,
|
|
1062
1085
|
load_options=m2m_load_options or None,
|
|
1063
1086
|
)
|
|
1064
1087
|
values = obj.model_dump(
|
|
@@ -16,6 +16,7 @@ from .exceptions import NotFoundError
|
|
|
16
16
|
|
|
17
17
|
__all__ = [
|
|
18
18
|
"LockMode",
|
|
19
|
+
"advisory_lock",
|
|
19
20
|
"cleanup_tables",
|
|
20
21
|
"create_database",
|
|
21
22
|
"create_db_context",
|
|
@@ -204,6 +205,78 @@ def lock_tables(
|
|
|
204
205
|
return _lock()
|
|
205
206
|
|
|
206
207
|
|
|
208
|
+
@asynccontextmanager
|
|
209
|
+
async def advisory_lock(
|
|
210
|
+
session: AsyncSession,
|
|
211
|
+
key: int | tuple[int, int],
|
|
212
|
+
*,
|
|
213
|
+
shared: bool = False,
|
|
214
|
+
nowait: bool = False,
|
|
215
|
+
timeout: str | None = None,
|
|
216
|
+
) -> AsyncGenerator[bool, None]:
|
|
217
|
+
"""Acquire a PostgreSQL session-level advisory lock.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
session: AsyncSession instance.
|
|
221
|
+
key: Lock key — a single ``int`` (bigint) or a ``(int, int)`` pair for namespacing.
|
|
222
|
+
shared: Acquire a shared lock (multiple holders allowed). Default is exclusive.
|
|
223
|
+
nowait: Return ``False`` immediately if the lock is unavailable instead of waiting.
|
|
224
|
+
timeout: Maximum wait time (e.g. ``"5s"``, ``"500ms"``). Raises ``DBAPIError``
|
|
225
|
+
if exceeded. Ignored when *nowait* is ``True``.
|
|
226
|
+
|
|
227
|
+
Yields:
|
|
228
|
+
``True`` if the lock was acquired, ``False`` if *nowait* is ``True`` and the lock
|
|
229
|
+
is already held.
|
|
230
|
+
|
|
231
|
+
Raises:
|
|
232
|
+
sqlalchemy.exc.DBAPIError: If *timeout* is set and the lock cannot be acquired
|
|
233
|
+
in time.
|
|
234
|
+
|
|
235
|
+
Example:
|
|
236
|
+
```python
|
|
237
|
+
from fastapi_toolsets.db import advisory_lock
|
|
238
|
+
|
|
239
|
+
async with advisory_lock(session, 42):
|
|
240
|
+
...
|
|
241
|
+
|
|
242
|
+
async with advisory_lock(session, 42, nowait=True) as acquired:
|
|
243
|
+
if not acquired:
|
|
244
|
+
raise HTTPException(409, "Resource is locked")
|
|
245
|
+
|
|
246
|
+
async with advisory_lock(session, 42, timeout="5s"):
|
|
247
|
+
...
|
|
248
|
+
|
|
249
|
+
async with advisory_lock(session, (1, user_id), shared=True):
|
|
250
|
+
...
|
|
251
|
+
```
|
|
252
|
+
"""
|
|
253
|
+
suffix = "_shared" if shared else ""
|
|
254
|
+
acquire_fn = f"{'pg_try_advisory_lock' if nowait else 'pg_advisory_lock'}{suffix}"
|
|
255
|
+
release_fn = f"pg_advisory_unlock{suffix}"
|
|
256
|
+
|
|
257
|
+
if isinstance(key, tuple):
|
|
258
|
+
k1, k2 = key
|
|
259
|
+
args = "CAST(:k1 AS integer), CAST(:k2 AS integer)"
|
|
260
|
+
params: dict[str, int] = {"k1": k1, "k2": k2}
|
|
261
|
+
else:
|
|
262
|
+
args = ":k"
|
|
263
|
+
params = {"k": key}
|
|
264
|
+
|
|
265
|
+
acquire_sql = text(f"SELECT {acquire_fn}({args})")
|
|
266
|
+
release_sql = text(f"SELECT {release_fn}({args})")
|
|
267
|
+
|
|
268
|
+
if timeout is not None and not nowait:
|
|
269
|
+
await session.execute(text(f"SET LOCAL lock_timeout='{timeout}'"))
|
|
270
|
+
|
|
271
|
+
result = await session.execute(acquire_sql, params)
|
|
272
|
+
acquired = result.scalar() if nowait else True
|
|
273
|
+
try:
|
|
274
|
+
yield acquired
|
|
275
|
+
finally:
|
|
276
|
+
if acquired:
|
|
277
|
+
await session.execute(release_sql, params)
|
|
278
|
+
|
|
279
|
+
|
|
207
280
|
async def create_database(
|
|
208
281
|
db_name: str,
|
|
209
282
|
*,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/cli/commands/__init__.py
RENAMED
|
File without changes
|
{fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/cli/commands/fixtures.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/exceptions/__init__.py
RENAMED
|
File without changes
|
{fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/exceptions/exceptions.py
RENAMED
|
File without changes
|
{fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/exceptions/handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/sources/__init__.py
RENAMED
|
File without changes
|
{fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/sources/bearer.py
RENAMED
|
File without changes
|
{fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/sources/cookie.py
RENAMED
|
File without changes
|
{fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/sources/header.py
RENAMED
|
File without changes
|
{fastapi_toolsets-4.0.0 → fastapi_toolsets-4.1.0}/src/fastapi_toolsets/security/sources/multi.py
RENAMED
|
File without changes
|
|
File without changes
|