33from typing import Self
44from urllib .parse import urljoin
55
6+ from mpt_api_client .constants import APPLICATION_JSON
67from mpt_api_client .http .query_state import QueryState
78from mpt_api_client .http .types import FileTypes , Response
89from mpt_api_client .models import Collection , FileModel , ResourceData
@@ -84,7 +85,7 @@ def create(
8485 files [data_key ] = (
8586 None ,
8687 _json_to_file_payload (resource_data ),
87- "application/json" ,
88+ APPLICATION_JSON ,
8889 )
8990 response = self .http_client .request ("post" , self .path , files = files ) # type: ignore[attr-defined]
9091
@@ -105,6 +106,77 @@ def download(self, resource_id: str) -> FileModel:
105106 return FileModel (response )
106107
107108
109+ class CreateWithIconMixin [Model ]:
110+ """Create resource with icon mixin."""
111+
112+ def create (
113+ self ,
114+ resource_data : ResourceData ,
115+ icon : FileTypes ,
116+ data_key : str ,
117+ icon_key : str ,
118+ ) -> Model :
119+ """Create resource with icon.
120+
121+ Args:
122+ resource_data: Resource data.
123+ data_key: Key for the resource data.
124+ icon: Icon image in jpg, png, GIF, etc.
125+ icon_key: Key for the icon.
126+
127+ Returns:
128+ Created resource.
129+ """
130+ files : dict [str , FileTypes ] = {}
131+ files [data_key ] = (
132+ None ,
133+ json .dumps (resource_data ),
134+ APPLICATION_JSON ,
135+ )
136+ files [icon_key ] = icon
137+ response = self .http_client .request ("post" , self .path , files = files ) # type: ignore[attr-defined]
138+
139+ return self ._model_class .from_response (response ) # type: ignore[attr-defined, no-any-return]
140+
141+
142+ class UpdateWithIconMixin [Model ]:
143+ """Update resource with icon mixin."""
144+
145+ def update (
146+ self ,
147+ resource_id : str ,
148+ resource_data : ResourceData ,
149+ icon : FileTypes ,
150+ data_key : str ,
151+ icon_key : str ,
152+ ) -> Model :
153+ """Update resource with icon.
154+
155+ Args:
156+ resource_id: Resource ID.
157+ resource_data: Resource data.
158+ data_key: Key for the resource data.
159+ icon: Icon image in jpg, png, GIF, etc.
160+ icon_key: Key for the icon.
161+
162+ Returns:
163+ Updated resource.
164+ """
165+ files : dict [str , FileTypes ] = {}
166+ files [data_key ] = (
167+ None ,
168+ json .dumps (resource_data ),
169+ APPLICATION_JSON ,
170+ )
171+ files [icon_key ] = icon
172+
173+ url = urljoin (f"{ self .path } /" , resource_id ) # type: ignore[attr-defined]
174+
175+ response = self .http_client .request ("put" , url , files = files ) # type: ignore[attr-defined]
176+
177+ return self ._model_class .from_response (response ) # type: ignore[attr-defined, no-any-return]
178+
179+
108180class AsyncCreateMixin [Model ]:
109181 """Create resource mixin."""
110182
@@ -174,7 +246,7 @@ async def create(
174246 files [data_key ] = (
175247 None ,
176248 _json_to_file_payload (resource_data ),
177- "application/json" ,
249+ APPLICATION_JSON ,
178250 )
179251
180252 response = await self .http_client .request ("post" , self .path , files = files ) # type: ignore[attr-defined]
@@ -196,6 +268,77 @@ async def download(self, resource_id: str) -> FileModel:
196268 return FileModel (response )
197269
198270
271+ class AsyncCreateWithIconMixin [Model ]:
272+ """Create resource with icon mixin."""
273+
274+ async def create (
275+ self ,
276+ resource_data : ResourceData ,
277+ icon : FileTypes ,
278+ data_key : str ,
279+ icon_key : str ,
280+ ) -> Model :
281+ """Create resource with icon.
282+
283+ Args:
284+ resource_data: Resource data.
285+ data_key: Key for the resource data.
286+ icon: Icon image in jpg, png, GIF, etc.
287+ icon_key: Key for the icon.
288+
289+ Returns:
290+ Created resource.
291+ """
292+ files : dict [str , FileTypes ] = {}
293+ files [data_key ] = (
294+ None ,
295+ json .dumps (resource_data ),
296+ APPLICATION_JSON ,
297+ )
298+ files [icon_key ] = icon
299+ response = await self .http_client .request ("post" , self .path , files = files ) # type: ignore[attr-defined]
300+
301+ return self ._model_class .from_response (response ) # type: ignore[attr-defined, no-any-return]
302+
303+
304+ class AsyncUpdateWithIconMixin [Model ]:
305+ """Update resource with icon mixin."""
306+
307+ async def update (
308+ self ,
309+ resource_id : str ,
310+ resource_data : ResourceData ,
311+ icon : FileTypes ,
312+ data_key : str ,
313+ icon_key : str ,
314+ ) -> Model :
315+ """Update resource with icon.
316+
317+ Args:
318+ resource_id: Resource ID.
319+ resource_data: Resource data.
320+ data_key: Key for the resource data.
321+ icon: Icon image in jpg, png, GIF, etc.
322+ icon_key: Key for the icon.
323+
324+ Returns:
325+ Updated resource.
326+ """
327+ files : dict [str , FileTypes ] = {}
328+ files [data_key ] = (
329+ None ,
330+ json .dumps (resource_data ),
331+ APPLICATION_JSON ,
332+ )
333+ files [icon_key ] = icon
334+
335+ url = urljoin (f"{ self .path } /" , resource_id ) # type: ignore[attr-defined]
336+
337+ response = await self .http_client .request ("put" , url , files = files ) # type: ignore[attr-defined]
338+
339+ return self ._model_class .from_response (response ) # type: ignore[attr-defined, no-any-return]
340+
341+
199342class GetMixin [Model ]:
200343 """Get resource mixin."""
201344
0 commit comments