Coverage for src/henrri_connect/items/asynchro.py: 61%
36 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-05 10:54 +0200
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-05 10:54 +0200
1"""
2Sous-client pour les endpoints /v1/items.
4Classes:
5- ``henrri_connect.items.asynchro.AsyncItemsClient``
6 Accès asynchrone aux endpoints articles.
8Notes:
9- Utiliser de préférence l'objet ``henrri_connect.AsyncHenrriClient`` pour acceder aux endpoints.
10"""
12from __future__ import annotations
14from typing import TYPE_CHECKING, overload, Optional
16from ..models import Item, PagedListResponse, ItemsQuery
17from ..utils import clean
19if TYPE_CHECKING:
20 from ..connect import AsyncHenrriClient
22ITEMS_ENDPOINT = "/v1/items"
25class AsyncItemsClient:
26 """
27 Accès asynchrone aux endpoints articles.
29 Arguments
30 - ``client`` : Objet ``henrri_connect.AsyncHenrriClient`` pour acceder aux endpoints.
32 Methods
33 - ``list_items`` : Liste les articles avec pagination et filtres optionnels.
34 - ``add`` : Crée un nouvel article.
35 - ``get`` : Récupère un article par son identifiant.
36 - ``modify`` : Modifie un article par son identifiant.
37 - ``delete`` : Supprime un article par son identifiant.
38 - ``get_most_used`` : Récupère les articles les plus utilisés.
39 - ``get_best_sales`` : Récupère les articles les plus vendus.
40 - ``list_with_selected_fields`` : Liste les articles avec sélection de champs.
41 """
43 def __init__(self, client: AsyncHenrriClient) -> None:
44 self._c = client
46 @overload
47 async def list_items(
48 self,
49 *,
50 request: ItemsQuery,
51 with_selected_fields: bool = True,
52 with_totals: bool = False,
53 only_current_page: bool = True
54 ) -> PagedListResponse[Item]:...
55 @overload
56 async def list_items(
57 self,
58 *,
59 request: ItemsQuery,
60 with_selected_fields: bool = False,
61 with_totals: None = None,
62 only_current_page: None = None,
63 ) -> PagedListResponse[Item]:...
64 async def list_items(
65 self,
66 *,
67 request: ItemsQuery,
68 with_selected_fields: bool = True,
69 with_totals: Optional[bool] = False,
70 only_current_page: Optional[bool] = True
71 ) -> PagedListResponse[Item]:
72 """
73 Liste les articles avec pagination et filtres optionnels.
75 Arguments
76 - ``request`` (ItemsQuery) : Paramètres de recherche.
77 - ``with_selected_fields`` (bool) : Si True, lance une requête de recherche avancée.
78 - ``with_totals`` (bool) : Si True, renvoie les totaux.
79 - ``only_current_page`` (bool) : Si True, renvoie uniquement les articles de la page
80 actuelle.
82 Returns
83 - ``PagedListResponse[Item]`` : Liste paginée d'articles.
84 """
85 params = clean(request.model_dump(by_alias=True))
86 if with_selected_fields:
87 if with_totals and only_current_page:
88 params["with_totals"] = with_totals
89 params["only_current_page"] = only_current_page
90 resp = await self._c.request(
91 "GET",
92 f"{ITEMS_ENDPOINT}/with-selected-fields",
93 params=params
94 )
95 else:
96 raise ValueError(
97 "with_totals and only_current_page must be True if with_selected_fields is True"
98 )
99 else:
100 resp = await self._c.request("GET", ITEMS_ENDPOINT, params=params)
101 return PagedListResponse[Item].model_validate(resp.json())
104 async def add(self, item: Item) -> Item:
105 """
106 Crée un nouvel article.
108 Arguments
109 - ``item`` (Item) : Article à créer.
111 Returns
112 - ``Item`` : Article créé.
113 """
114 resp = await self._c.request(
115 "POST",
116 ITEMS_ENDPOINT,
117 json=item.model_dump(by_alias=True, exclude_unset=True, exclude_none=True),
118 )
119 return Item.model_validate(resp.json())
121 async def get(self, item_id: int) -> Item:
122 """
123 Récupère un article par son identifiant.
125 Arguments
126 - ``item_id`` (int) : Identifiant de l'article.
128 Returns
129 - ``Item`` : Article trouvé.
130 """
131 resp = await self._c.request("GET", f"{ITEMS_ENDPOINT}/{item_id}")
132 return Item.model_validate(resp.json())
134 async def modify(self, item_id: int, item: Item) -> Item:
135 """
136 Met à jour un article existant.
138 Arguments
139 - ``item_id`` (int) : Identifiant de l'article.
140 - ``item`` (Item) : Article à mettre à jour.
142 Returns
143 - ``Item`` : Article mis à jour.
144 """
145 resp = await self._c.request(
146 "PUT",
147 f"{ITEMS_ENDPOINT}/{item_id}",
148 json=item.model_dump(by_alias=True, exclude_unset=True, exclude_none=True),
149 )
150 return Item.model_validate(resp.json())
152 async def delete(self, item_id: int) -> None:
153 """
154 Supprime un article.
156 Arguments
157 - ``item_id`` (int) : Identifiant de l'article à supprimer.
159 Returns
160 - ``None`` : Article supprimé.
161 """
162 await self._c.request("DELETE", f"{ITEMS_ENDPOINT}/{item_id}")
164 async def get_most_used(self) -> PagedListResponse[Item]:
165 """
166 Récupère les articles les plus utilisés.
168 Arguments
169 - None
171 Returns
172 - ``PagedListResponse[Item]`` : Liste paginée d'articles.
173 """
174 resp = await self._c.request("GET", f"{ITEMS_ENDPOINT}/most-used")
175 return PagedListResponse[Item].model_validate(resp.json())
177 async def get_best_sales(self, *, year: int) -> PagedListResponse[Item]:
178 """
179 Récupère les articles les plus vendus.
181 Arguments
182 - ``year`` (int) : Année de recherche.
184 Returns
185 - ``PagedListResponse[Item]`` : Liste paginée d'articles.
186 """
187 params = {
188 "year": year
189 }
190 resp = await self._c.request("GET", f"{ITEMS_ENDPOINT}/best-sales", params=params)
191 return PagedListResponse[Item].model_validate(resp.json())