fastapi-toolsets 2.4.0__tar.gz → 2.4.1__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-2.4.0 → fastapi_toolsets-2.4.1}/PKG-INFO +1 -1
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/pyproject.toml +1 -1
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/__init__.py +1 -1
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/crud/factory.py +174 -23
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/schemas.py +16 -3
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/LICENSE +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/README.md +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/_imports.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/cli/__init__.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/cli/app.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/cli/commands/__init__.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/cli/commands/fixtures.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/cli/config.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/cli/pyproject.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/cli/utils.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/crud/__init__.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/crud/search.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/db.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/dependencies.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/exceptions/__init__.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/exceptions/exceptions.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/exceptions/handler.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/fixtures/__init__.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/fixtures/enum.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/fixtures/registry.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/fixtures/utils.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/logger.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/metrics/__init__.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/metrics/handler.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/metrics/registry.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/models/__init__.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/models/columns.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/models/watched.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/py.typed +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/pytest/__init__.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/pytest/plugin.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/pytest/utils.py +0 -0
- {fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/types.py +0 -0
|
@@ -58,18 +58,33 @@ class _CursorDirection(str, Enum):
|
|
|
58
58
|
def _encode_cursor(
|
|
59
59
|
value: Any, *, direction: _CursorDirection = _CursorDirection.NEXT
|
|
60
60
|
) -> str:
|
|
61
|
-
"""Encode a cursor column value and navigation direction as a base64 string."""
|
|
62
|
-
return
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
"""Encode a cursor column value and navigation direction as a URL-safe base64 string."""
|
|
62
|
+
return (
|
|
63
|
+
base64.urlsafe_b64encode(
|
|
64
|
+
json.dumps({"val": str(value), "dir": direction}).encode()
|
|
65
|
+
)
|
|
66
|
+
.decode()
|
|
67
|
+
.rstrip("=")
|
|
68
|
+
)
|
|
65
69
|
|
|
66
70
|
|
|
67
71
|
def _decode_cursor(cursor: str) -> tuple[str, _CursorDirection]:
|
|
68
|
-
"""Decode a
|
|
69
|
-
|
|
72
|
+
"""Decode a URL-safe base64 cursor string into ``(raw_value, direction)``."""
|
|
73
|
+
padded = cursor + "=" * (-len(cursor) % 4)
|
|
74
|
+
payload = json.loads(base64.urlsafe_b64decode(padded).decode())
|
|
70
75
|
return payload["val"], _CursorDirection(payload["dir"])
|
|
71
76
|
|
|
72
77
|
|
|
78
|
+
def _page_size_query(default: int, max_size: int) -> int:
|
|
79
|
+
"""Return a FastAPI ``Query`` for the ``items_per_page`` parameter."""
|
|
80
|
+
return Query(
|
|
81
|
+
default,
|
|
82
|
+
ge=1,
|
|
83
|
+
le=max_size,
|
|
84
|
+
description=f"Number of items per page (max {max_size})",
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
73
88
|
def _parse_cursor_value(raw_val: str, col_type: Any) -> Any:
|
|
74
89
|
"""Parse a raw cursor string value back into the appropriate Python type."""
|
|
75
90
|
if isinstance(col_type, Integer):
|
|
@@ -254,6 +269,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
254
269
|
facet_fields: Sequence[FacetFieldType] | None = None,
|
|
255
270
|
) -> Callable[..., Awaitable[dict[str, list[str]]]]:
|
|
256
271
|
"""Return a FastAPI dependency that collects facet filter values from query parameters.
|
|
272
|
+
|
|
257
273
|
Args:
|
|
258
274
|
facet_fields: Override the facet fields for this dependency. Falls back to the
|
|
259
275
|
class-level ``facet_fields`` if not provided.
|
|
@@ -293,6 +309,121 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
293
309
|
|
|
294
310
|
return dependency
|
|
295
311
|
|
|
312
|
+
@classmethod
|
|
313
|
+
def offset_params(
|
|
314
|
+
cls: type[Self],
|
|
315
|
+
*,
|
|
316
|
+
default_page_size: int = 20,
|
|
317
|
+
max_page_size: int = 100,
|
|
318
|
+
include_total: bool = True,
|
|
319
|
+
) -> Callable[..., Awaitable[dict[str, Any]]]:
|
|
320
|
+
"""Return a FastAPI dependency that collects offset pagination params from query params.
|
|
321
|
+
|
|
322
|
+
Args:
|
|
323
|
+
default_page_size: Default value for the ``items_per_page`` query parameter.
|
|
324
|
+
max_page_size: Maximum allowed value for ``items_per_page`` (enforced via
|
|
325
|
+
``le`` on the ``Query``).
|
|
326
|
+
include_total: Server-side flag forwarded as-is to ``include_total`` in
|
|
327
|
+
:meth:`offset_paginate`. Not exposed as a query parameter.
|
|
328
|
+
|
|
329
|
+
Returns:
|
|
330
|
+
An async dependency that resolves to a dict with ``page``,
|
|
331
|
+
``items_per_page``, and ``include_total`` keys, ready to be
|
|
332
|
+
unpacked into :meth:`offset_paginate`.
|
|
333
|
+
"""
|
|
334
|
+
|
|
335
|
+
async def dependency(
|
|
336
|
+
page: int = Query(1, ge=1, description="Page number (1-indexed)"),
|
|
337
|
+
items_per_page: int = _page_size_query(default_page_size, max_page_size),
|
|
338
|
+
) -> dict[str, Any]:
|
|
339
|
+
return {
|
|
340
|
+
"page": page,
|
|
341
|
+
"items_per_page": items_per_page,
|
|
342
|
+
"include_total": include_total,
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
dependency.__name__ = f"{cls.model.__name__}OffsetParams"
|
|
346
|
+
return dependency
|
|
347
|
+
|
|
348
|
+
@classmethod
|
|
349
|
+
def cursor_params(
|
|
350
|
+
cls: type[Self],
|
|
351
|
+
*,
|
|
352
|
+
default_page_size: int = 20,
|
|
353
|
+
max_page_size: int = 100,
|
|
354
|
+
) -> Callable[..., Awaitable[dict[str, Any]]]:
|
|
355
|
+
"""Return a FastAPI dependency that collects cursor pagination params from query params.
|
|
356
|
+
|
|
357
|
+
Args:
|
|
358
|
+
default_page_size: Default value for the ``items_per_page`` query parameter.
|
|
359
|
+
max_page_size: Maximum allowed value for ``items_per_page`` (enforced via
|
|
360
|
+
``le`` on the ``Query``).
|
|
361
|
+
|
|
362
|
+
Returns:
|
|
363
|
+
An async dependency that resolves to a dict with ``cursor`` and
|
|
364
|
+
``items_per_page`` keys, ready to be unpacked into
|
|
365
|
+
:meth:`cursor_paginate`.
|
|
366
|
+
"""
|
|
367
|
+
|
|
368
|
+
async def dependency(
|
|
369
|
+
cursor: str | None = Query(
|
|
370
|
+
None, description="Cursor token from a previous response"
|
|
371
|
+
),
|
|
372
|
+
items_per_page: int = _page_size_query(default_page_size, max_page_size),
|
|
373
|
+
) -> dict[str, Any]:
|
|
374
|
+
return {"cursor": cursor, "items_per_page": items_per_page}
|
|
375
|
+
|
|
376
|
+
dependency.__name__ = f"{cls.model.__name__}CursorParams"
|
|
377
|
+
return dependency
|
|
378
|
+
|
|
379
|
+
@classmethod
|
|
380
|
+
def paginate_params(
|
|
381
|
+
cls: type[Self],
|
|
382
|
+
*,
|
|
383
|
+
default_page_size: int = 20,
|
|
384
|
+
max_page_size: int = 100,
|
|
385
|
+
default_pagination_type: PaginationType = PaginationType.OFFSET,
|
|
386
|
+
include_total: bool = True,
|
|
387
|
+
) -> Callable[..., Awaitable[dict[str, Any]]]:
|
|
388
|
+
"""Return a FastAPI dependency that collects all pagination params from query params.
|
|
389
|
+
|
|
390
|
+
Args:
|
|
391
|
+
default_page_size: Default value for the ``items_per_page`` query parameter.
|
|
392
|
+
max_page_size: Maximum allowed value for ``items_per_page`` (enforced via
|
|
393
|
+
``le`` on the ``Query``).
|
|
394
|
+
default_pagination_type: Default pagination strategy.
|
|
395
|
+
include_total: Server-side flag forwarded as-is to ``include_total`` in
|
|
396
|
+
:meth:`paginate`. Not exposed as a query parameter.
|
|
397
|
+
|
|
398
|
+
Returns:
|
|
399
|
+
An async dependency that resolves to a dict with ``pagination_type``,
|
|
400
|
+
``page``, ``cursor``, ``items_per_page``, and ``include_total`` keys,
|
|
401
|
+
ready to be unpacked into :meth:`paginate`.
|
|
402
|
+
"""
|
|
403
|
+
|
|
404
|
+
async def dependency(
|
|
405
|
+
pagination_type: PaginationType = Query(
|
|
406
|
+
default_pagination_type, description="Pagination strategy"
|
|
407
|
+
),
|
|
408
|
+
page: int = Query(
|
|
409
|
+
1, ge=1, description="Page number (1-indexed, offset only)"
|
|
410
|
+
),
|
|
411
|
+
cursor: str | None = Query(
|
|
412
|
+
None, description="Cursor token from a previous response (cursor only)"
|
|
413
|
+
),
|
|
414
|
+
items_per_page: int = _page_size_query(default_page_size, max_page_size),
|
|
415
|
+
) -> dict[str, Any]:
|
|
416
|
+
return {
|
|
417
|
+
"pagination_type": pagination_type,
|
|
418
|
+
"page": page,
|
|
419
|
+
"cursor": cursor,
|
|
420
|
+
"items_per_page": items_per_page,
|
|
421
|
+
"include_total": include_total,
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
dependency.__name__ = f"{cls.model.__name__}PaginateParams"
|
|
425
|
+
return dependency
|
|
426
|
+
|
|
296
427
|
@classmethod
|
|
297
428
|
def order_params(
|
|
298
429
|
cls: type[Self],
|
|
@@ -922,6 +1053,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
922
1053
|
order_by: OrderByClause | None = None,
|
|
923
1054
|
page: int = 1,
|
|
924
1055
|
items_per_page: int = 20,
|
|
1056
|
+
include_total: bool = True,
|
|
925
1057
|
search: str | SearchConfig | None = None,
|
|
926
1058
|
search_fields: Sequence[SearchFieldType] | None = None,
|
|
927
1059
|
facet_fields: Sequence[FacetFieldType] | None = None,
|
|
@@ -939,6 +1071,8 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
939
1071
|
order_by: Column or list of columns to order by
|
|
940
1072
|
page: Page number (1-indexed)
|
|
941
1073
|
items_per_page: Number of items per page
|
|
1074
|
+
include_total: When ``False``, skip the ``COUNT`` query;
|
|
1075
|
+
``pagination.total_count`` will be ``None``.
|
|
942
1076
|
search: Search query string or SearchConfig object
|
|
943
1077
|
search_fields: Fields to search in (overrides class default)
|
|
944
1078
|
facet_fields: Columns to compute distinct values for (overrides class default)
|
|
@@ -983,27 +1117,38 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
983
1117
|
if order_by is not None:
|
|
984
1118
|
q = q.order_by(order_by)
|
|
985
1119
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1120
|
+
if include_total:
|
|
1121
|
+
q = q.offset(offset).limit(items_per_page)
|
|
1122
|
+
result = await session.execute(q)
|
|
1123
|
+
raw_items = cast(list[ModelType], result.unique().scalars().all())
|
|
990
1124
|
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1125
|
+
# Count query (with same joins and filters)
|
|
1126
|
+
pk_col = cls.model.__mapper__.primary_key[0]
|
|
1127
|
+
count_q = select(func.count(func.distinct(getattr(cls.model, pk_col.name))))
|
|
1128
|
+
count_q = count_q.select_from(cls.model)
|
|
995
1129
|
|
|
996
|
-
|
|
997
|
-
|
|
1130
|
+
# Apply explicit joins to count query
|
|
1131
|
+
count_q = _apply_joins(count_q, joins, outer_join)
|
|
998
1132
|
|
|
999
|
-
|
|
1000
|
-
|
|
1133
|
+
# Apply search joins to count query
|
|
1134
|
+
count_q = _apply_search_joins(count_q, search_joins)
|
|
1001
1135
|
|
|
1002
|
-
|
|
1003
|
-
|
|
1136
|
+
if filters:
|
|
1137
|
+
count_q = count_q.where(and_(*filters))
|
|
1004
1138
|
|
|
1005
|
-
|
|
1006
|
-
|
|
1139
|
+
count_result = await session.execute(count_q)
|
|
1140
|
+
total_count: int | None = count_result.scalar_one()
|
|
1141
|
+
has_more = page * items_per_page < total_count
|
|
1142
|
+
else:
|
|
1143
|
+
# Fetch one extra row to detect if a next page exists without COUNT
|
|
1144
|
+
q = q.offset(offset).limit(items_per_page + 1)
|
|
1145
|
+
result = await session.execute(q)
|
|
1146
|
+
raw_items = cast(list[ModelType], result.unique().scalars().all())
|
|
1147
|
+
has_more = len(raw_items) > items_per_page
|
|
1148
|
+
raw_items = raw_items[:items_per_page]
|
|
1149
|
+
total_count = None
|
|
1150
|
+
|
|
1151
|
+
items: list[Any] = [schema.model_validate(item) for item in raw_items]
|
|
1007
1152
|
|
|
1008
1153
|
filter_attributes = await cls._build_filter_attributes(
|
|
1009
1154
|
session, facet_fields, filters, search_joins
|
|
@@ -1015,7 +1160,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
1015
1160
|
total_count=total_count,
|
|
1016
1161
|
items_per_page=items_per_page,
|
|
1017
1162
|
page=page,
|
|
1018
|
-
has_more=
|
|
1163
|
+
has_more=has_more,
|
|
1019
1164
|
),
|
|
1020
1165
|
filter_attributes=filter_attributes,
|
|
1021
1166
|
)
|
|
@@ -1190,6 +1335,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
1190
1335
|
page: int = ...,
|
|
1191
1336
|
cursor: str | None = ...,
|
|
1192
1337
|
items_per_page: int = ...,
|
|
1338
|
+
include_total: bool = ...,
|
|
1193
1339
|
search: str | SearchConfig | None = ...,
|
|
1194
1340
|
search_fields: Sequence[SearchFieldType] | None = ...,
|
|
1195
1341
|
facet_fields: Sequence[FacetFieldType] | None = ...,
|
|
@@ -1212,6 +1358,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
1212
1358
|
page: int = ...,
|
|
1213
1359
|
cursor: str | None = ...,
|
|
1214
1360
|
items_per_page: int = ...,
|
|
1361
|
+
include_total: bool = ...,
|
|
1215
1362
|
search: str | SearchConfig | None = ...,
|
|
1216
1363
|
search_fields: Sequence[SearchFieldType] | None = ...,
|
|
1217
1364
|
facet_fields: Sequence[FacetFieldType] | None = ...,
|
|
@@ -1233,6 +1380,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
1233
1380
|
page: int = 1,
|
|
1234
1381
|
cursor: str | None = None,
|
|
1235
1382
|
items_per_page: int = 20,
|
|
1383
|
+
include_total: bool = True,
|
|
1236
1384
|
search: str | SearchConfig | None = None,
|
|
1237
1385
|
search_fields: Sequence[SearchFieldType] | None = None,
|
|
1238
1386
|
facet_fields: Sequence[FacetFieldType] | None = None,
|
|
@@ -1258,6 +1406,8 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
1258
1406
|
:class:`.CursorPaginatedResponse`. Only used when
|
|
1259
1407
|
``pagination_type`` is ``CURSOR``.
|
|
1260
1408
|
items_per_page: Number of items per page (default 20).
|
|
1409
|
+
include_total: When ``False``, skip the ``COUNT`` query;
|
|
1410
|
+
only applies when ``pagination_type`` is ``OFFSET``.
|
|
1261
1411
|
search: Search query string or :class:`.SearchConfig` object.
|
|
1262
1412
|
search_fields: Fields to search in (overrides class default).
|
|
1263
1413
|
facet_fields: Columns to compute distinct values for (overrides
|
|
@@ -1304,6 +1454,7 @@ class AsyncCrud(Generic[ModelType]):
|
|
|
1304
1454
|
order_by=order_by,
|
|
1305
1455
|
page=page,
|
|
1306
1456
|
items_per_page=items_per_page,
|
|
1457
|
+
include_total=include_total,
|
|
1307
1458
|
search=search,
|
|
1308
1459
|
search_fields=search_fields,
|
|
1309
1460
|
facet_fields=facet_fields,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""Base Pydantic schemas for API responses."""
|
|
2
2
|
|
|
3
|
+
import math
|
|
3
4
|
from enum import Enum
|
|
4
5
|
from typing import Annotated, Any, ClassVar, Generic, Literal, TypeVar, Union
|
|
5
6
|
|
|
6
|
-
from pydantic import BaseModel, ConfigDict, Field
|
|
7
|
+
from pydantic import BaseModel, ConfigDict, Field, computed_field
|
|
7
8
|
|
|
8
9
|
from .types import DataT
|
|
9
10
|
|
|
@@ -98,17 +99,29 @@ class OffsetPagination(PydanticBase):
|
|
|
98
99
|
"""Pagination metadata for offset-based list responses.
|
|
99
100
|
|
|
100
101
|
Attributes:
|
|
101
|
-
total_count: Total number of items across all pages
|
|
102
|
+
total_count: Total number of items across all pages.
|
|
103
|
+
``None`` when ``include_total=False``.
|
|
102
104
|
items_per_page: Number of items per page
|
|
103
105
|
page: Current page number (1-indexed)
|
|
104
106
|
has_more: Whether there are more pages
|
|
107
|
+
pages: Total number of pages
|
|
105
108
|
"""
|
|
106
109
|
|
|
107
|
-
total_count: int
|
|
110
|
+
total_count: int | None
|
|
108
111
|
items_per_page: int
|
|
109
112
|
page: int
|
|
110
113
|
has_more: bool
|
|
111
114
|
|
|
115
|
+
@computed_field
|
|
116
|
+
@property
|
|
117
|
+
def pages(self) -> int | None:
|
|
118
|
+
"""Total number of pages, or ``None`` when ``total_count`` is unknown."""
|
|
119
|
+
if self.total_count is None:
|
|
120
|
+
return None
|
|
121
|
+
if self.items_per_page == 0:
|
|
122
|
+
return 0
|
|
123
|
+
return math.ceil(self.total_count / self.items_per_page)
|
|
124
|
+
|
|
112
125
|
|
|
113
126
|
class CursorPagination(PydanticBase):
|
|
114
127
|
"""Pagination metadata for cursor-based list responses.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/cli/commands/__init__.py
RENAMED
|
File without changes
|
{fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/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
|
|
File without changes
|
{fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/exceptions/__init__.py
RENAMED
|
File without changes
|
{fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/src/fastapi_toolsets/exceptions/exceptions.py
RENAMED
|
File without changes
|
{fastapi_toolsets-2.4.0 → fastapi_toolsets-2.4.1}/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
|