fastapi-rtk 1.0.10__py3-none-any.whl → 1.0.12__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.
fastapi_rtk/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.0.10"
1
+ __version__ = "1.0.12"
@@ -462,6 +462,17 @@ class ModelRestApi(BaseApi):
462
462
  DO NOT MODIFY UNLESS YOU KNOW WHAT YOU ARE DOING.
463
463
  """
464
464
 
465
+ """
466
+ -------------
467
+ LIST
468
+ -------------
469
+ """
470
+
471
+ list_query_count_enabled = True
472
+ """
473
+ Whether to enable counting the total number of items in the list endpoint. Defaults to `True`.
474
+ """
475
+
465
476
  """
466
477
  -------------
467
478
  TITLES
@@ -1030,6 +1041,28 @@ class ModelRestApi(BaseApi):
1030
1041
  """
1031
1042
  return current_permissions(self)
1032
1043
 
1044
+ def get_q_and_session_count_factory(self):
1045
+ """
1046
+ Returns a dependency that yields a tuple of (QuerySchema, session or None).
1047
+
1048
+ If `list_query_count_enabled` is False or `q.with_count` is False, the session will be None.
1049
+
1050
+ Returns:
1051
+ Callable[..., Coroutine[Any, Any, Tuple[QuerySchema, AsyncSession | Session | None]]]: The dependency that yields the tuple.
1052
+ """
1053
+ session_factory = self.datamodel.get_session_factory()
1054
+
1055
+ async def dependency(q: self.query_schema = Depends()): # type: ignore
1056
+ q: QuerySchema = q
1057
+ if not self.list_query_count_enabled or not q.with_count:
1058
+ yield q, None
1059
+ return
1060
+
1061
+ async for session in session_factory():
1062
+ yield q, session
1063
+
1064
+ return dependency
1065
+
1033
1066
  """
1034
1067
  -------------
1035
1068
  ROUTES
@@ -1508,19 +1541,17 @@ class ModelRestApi(BaseApi):
1508
1541
 
1509
1542
  async def get_list_headless(
1510
1543
  self,
1511
- q: QuerySchema = SelfType.with_depends().query_schema,
1512
1544
  session: AsyncSession | Session = SelfDepends().datamodel.get_session_factory,
1513
- session_count: AsyncSession
1514
- | Session = SelfDepends().datamodel.get_session_factory,
1545
+ q_session_count: tuple[
1546
+ QuerySchema, AsyncSession | Session | None
1547
+ ] = SelfDepends().get_q_and_session_count_factory,
1515
1548
  ):
1516
1549
  """
1517
1550
  Retrieves all items in a headless mode.
1518
1551
 
1519
1552
  Args:
1520
- q (QuerySchema): The query schema.
1521
- query (QueryManager): The query manager object.
1522
1553
  session (AsyncSession | Session): A database scoped session.
1523
- session_count (AsyncSession | Session): A database scoped session for counting.
1554
+ q_session_count (tuple[QuerySchema, AsyncSession | Session | None]): A tuple of query schema and a database scoped session for counting.
1524
1555
 
1525
1556
  Returns:
1526
1557
  list_return_schema: The list return schema.
@@ -1529,6 +1560,7 @@ class ModelRestApi(BaseApi):
1529
1560
  If you are overriding this method, make sure to copy all the decorators too.
1530
1561
  """
1531
1562
  async with AsyncTaskRunner():
1563
+ q, session_count = q_session_count
1532
1564
  self._validate_query_parameters(q)
1533
1565
  params = self._handle_query_params(q)
1534
1566
  try:
@@ -1536,9 +1568,14 @@ class ModelRestApi(BaseApi):
1536
1568
  task_items = tg.create_task(
1537
1569
  smart_run(self.datamodel.get_many, session, params)
1538
1570
  )
1539
- task_count = tg.create_task(
1540
- smart_run(self.datamodel.count, session_count, params)
1541
- )
1571
+ if session_count:
1572
+ task_count = tg.create_task(
1573
+ smart_run(self.datamodel.count, session_count, params)
1574
+ )
1575
+ else:
1576
+ task_count = tg.create_task(
1577
+ asyncio.sleep(0, result=None)
1578
+ ) # Dummy task
1542
1579
  items, count = await task_items, await task_count
1543
1580
  pks, data = self.datamodel.convert_to_result(items)
1544
1581
  schema = self.list_return_schema
fastapi_rtk/db.py CHANGED
@@ -9,6 +9,7 @@ from typing import (
9
9
  Optional,
10
10
  )
11
11
 
12
+ import sqlalchemy.orm
12
13
  from fastapi import Depends
13
14
  from fastapi_users.db import SQLAlchemyUserDatabase
14
15
  from fastapi_users.models import ID, OAP, UP
@@ -91,6 +92,7 @@ class UserDatabase(SQLAlchemyUserDatabase[UP, ID]):
91
92
 
92
93
  statement = (
93
94
  select(self.user_table)
95
+ .options(sqlalchemy.orm.selectinload(self.user_table.oauth_accounts))
94
96
  .join(self.oauth_account_table)
95
97
  .where(self.oauth_account_table.oauth_name == oauth)
96
98
  .where(self.oauth_account_table.account_id == account_id)
fastapi_rtk/schemas.py CHANGED
@@ -323,7 +323,7 @@ class BaseResponseMany(BaseResponse):
323
323
  Represents a response containing multiple items.
324
324
 
325
325
  Attributes:
326
- count (int): The count of items.
326
+ count (int | None): The count of items. If None, count is not provided.
327
327
  ids (List[PRIMARY_KEY]): The IDs of the items.
328
328
  list_columns (List[str]): The columns to show in the list.
329
329
  list_title (str): The title for the list.
@@ -331,7 +331,7 @@ class BaseResponseMany(BaseResponse):
331
331
  result (List[BaseModel] | None): The result of the response.
332
332
  """
333
333
 
334
- count: int
334
+ count: int | None = None
335
335
  ids: list[PRIMARY_KEY]
336
336
  list_columns: list[str] = []
337
337
  list_title: str = ""
@@ -384,24 +384,26 @@ class QuerySchema(BaseModel):
384
384
  Represents the query parameters for selection, pagination, ordering, and filtering.
385
385
 
386
386
  Attributes:
387
- columns (str, optional): The columns to select in the query. Defaults to '[]'.
388
387
  page (int): The page number for pagination. Defaults to 0.
389
388
  page_size (int, optional): The number of items per page. Defaults to 25.
390
389
  order_column (str, optional): The column to order the results by.
391
390
  order_direction (Literal['asc', 'desc'], optional): The direction of the ordering (asc or desc).
391
+ columns (str, optional): The columns to select in the query. Defaults to '[]'.
392
392
  filters (str, optional): The filters to apply to the query. Defaults to '[]'.
393
393
  opr_filters (str, optional): The filters to apply without column name. Defaults to '[]'.
394
394
  global_filter (str, optional): The filter to apply globally across all columns.
395
+ with_count (bool): Whether to include the total count of items. Defaults to True.
395
396
  """
396
397
 
397
- columns: str = "[]"
398
398
  page: int = 0
399
399
  page_size: int | None = 25
400
400
  order_column: str | None = None
401
401
  order_direction: Literal["asc", "desc"] | None = None
402
+ columns: str = "[]"
402
403
  filters: str = "[]"
403
404
  opr_filters: str = "[]"
404
405
  global_filter: str | None = None
406
+ with_count: bool = True
405
407
 
406
408
  @field_validator("columns")
407
409
  @classmethod
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-rtk
3
- Version: 1.0.10
3
+ Version: 1.0.12
4
4
  Summary: A package that provides a set of tools to build a FastAPI application with a Class-Based CRUD API.
5
5
  Project-URL: Homepage, https://codeberg.org/datatactics/fastapi-rtk
6
6
  Project-URL: Issues, https://codeberg.org/datatactics/fastapi-rtk/issues
@@ -1,9 +1,9 @@
1
1
  fastapi_rtk/__init__.py,sha256=Lg6Er5blOMcbtQSRJMNWbRQ1VX4PWEPMVFm2ie5r8mA,6183
2
- fastapi_rtk/_version.py,sha256=5vGk-8GWz6jojEu9w36UP5aNA0LuiwgbNSJ8Umn2rLA,23
2
+ fastapi_rtk/_version.py,sha256=bQ8TKIXU3qSGr-K-gVtWDgjDfBlCgBju76OGKtY9tS8,23
3
3
  fastapi_rtk/apis.py,sha256=6X_Lhl98m7lKrDRybg2Oe24pLFLJ29eCOQSwCAvpKhY,172
4
4
  fastapi_rtk/config.py,sha256=9PZF9E5i1gxmnsZEprZZKxVHSk0dFEklJSplX9NEqdo,14036
5
5
  fastapi_rtk/const.py,sha256=sEj_cYeerj9pVwbCu0k5Sy1EYpdr1EHzUjqqbnporgc,4905
6
- fastapi_rtk/db.py,sha256=gItbbRYYAtAF7_1YqaZGBeQY5_E0cKvomGEzcCjIhpg,24548
6
+ fastapi_rtk/db.py,sha256=4bNlpG_HqJzMkhgQ4c7kxm1AH82UVWRSD2ajexHp1Cs,24654
7
7
  fastapi_rtk/decorators.py,sha256=HqAFSiO0l5_M0idWs0IcY24FdzbAcDQDQoifM_WgZAQ,14515
8
8
  fastapi_rtk/dependencies.py,sha256=jlcsMrh83yrJsgXvpWJet_mjqwDP3nBZfPSg4Lq8KKE,7757
9
9
  fastapi_rtk/exceptions.py,sha256=P0qwd4VkeWFotgMVQHgmdT1NphFQaEznKLFIvJzW4Zs,2594
@@ -15,13 +15,13 @@ fastapi_rtk/middlewares.py,sha256=ycdaAdLIUaNEZ7KotczTHS6OOqy98Mn1_O7Hpe7Sma8,10
15
15
  fastapi_rtk/mixins.py,sha256=78RqwrRJFOz6KAxf-GSNOmRdr7R3b-ws7OIENYlzRQQ,238
16
16
  fastapi_rtk/models.py,sha256=lQSqe-r0H7jWBVdqXjEi_bNL1cGQr0YWnyI1ToS_coc,178
17
17
  fastapi_rtk/routers.py,sha256=5gMGyH4Any9TwB3Fz23QDkmrX8MouzCxVgoAIcBqnTI,18988
18
- fastapi_rtk/schemas.py,sha256=zzzmf5qjSn6PtzrekD3Kll_WOn6XWR7h4AHQchW3GX8,17723
18
+ fastapi_rtk/schemas.py,sha256=mdIX93QRaQBLrQz-kBvG5wyKoi8H6OQpFuTBO9-mCK4,17894
19
19
  fastapi_rtk/setting.py,sha256=vpjnio0mp_yZhDajZaBl6uOFmrBYl-sqB0L_lSkBpfk,19529
20
20
  fastapi_rtk/types.py,sha256=-LPnTIbHvqJW81__gab3EWrhjNmznHhptz0BtXkEAHQ,3612
21
21
  fastapi_rtk/version.py,sha256=D2cmQf2LNeHOiEfcNzVOOfcAmuLvPEmGEtZv5G54D0c,195
22
22
  fastapi_rtk/api/__init__.py,sha256=MwFR7HHppnhbjZGg3sOdQ6nqy9uxnHHXvicpswNFMNA,245
23
23
  fastapi_rtk/api/base_api.py,sha256=42I9v3b25lqxNAMDGEtajA5-btIDSyUWF0xMDgGkA8c,8078
24
- fastapi_rtk/api/model_rest_api.py,sha256=R-zdfDK6QiVb8u6EBTpZt7cqvH4kP86udNMxdJRiphQ,105254
24
+ fastapi_rtk/api/model_rest_api.py,sha256=pLuwefPEunf0P1k_UlKFEINZaT8RTPEHcN0j784G8Z0,106536
25
25
  fastapi_rtk/auth/__init__.py,sha256=iX7O41NivBYDfdomEaqm4lUx9KD17wI4g3EFLF6kUTw,336
26
26
  fastapi_rtk/auth/auth.py,sha256=F2qZoR7go_7FnvVJrDxUCd6vtRz5XW8yyOv143MWPts,20664
27
27
  fastapi_rtk/auth/hashers/__init__.py,sha256=uBThFj2VPPSMSioxYTktNiM4-mVgtDAjTpKA3ZzWxxs,110
@@ -126,8 +126,8 @@ fastapi_rtk/utils/timezone.py,sha256=62S0pPWuDFFXxV1YTFCsc4uKiSP_Ba36Fv7S3gYjfhs
126
126
  fastapi_rtk/utils/update_signature.py,sha256=PIzZgNpGEwvDNgQ3G51Zi-QhVV3mbxvUvSwDwf_-yYs,2209
127
127
  fastapi_rtk/utils/use_default_when_none.py,sha256=H2HqhKy_8eYk3i1xijEjuaKak0oWkMIkrdz6T7DK9QU,469
128
128
  fastapi_rtk/utils/werkzeug.py,sha256=1Gv-oyqSmhVGrmNbB9fDqpqJzPpANOzWf4zMMrhW9UA,3245
129
- fastapi_rtk-1.0.10.dist-info/METADATA,sha256=FWjDKJQ40ntwOVswJo9zqpKqasIu4dugohhYo7bWaCU,1271
130
- fastapi_rtk-1.0.10.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
131
- fastapi_rtk-1.0.10.dist-info/entry_points.txt,sha256=UuTkxSVIokSlVN28TMhoxzRRUaPxlVRSH3Gsx6yip60,53
132
- fastapi_rtk-1.0.10.dist-info/licenses/LICENSE,sha256=NDrWi4Qwcxal3u1r2lBWGA6TVh3OeW7yMan098mQz98,1073
133
- fastapi_rtk-1.0.10.dist-info/RECORD,,
129
+ fastapi_rtk-1.0.12.dist-info/METADATA,sha256=nOPH5lvxtFDeEzmUw31wV2hfmnfFFn4Gtg2sZ9SSmpQ,1271
130
+ fastapi_rtk-1.0.12.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
131
+ fastapi_rtk-1.0.12.dist-info/entry_points.txt,sha256=UuTkxSVIokSlVN28TMhoxzRRUaPxlVRSH3Gsx6yip60,53
132
+ fastapi_rtk-1.0.12.dist-info/licenses/LICENSE,sha256=NDrWi4Qwcxal3u1r2lBWGA6TVh3OeW7yMan098mQz98,1073
133
+ fastapi_rtk-1.0.12.dist-info/RECORD,,