airia 0.1.12__py3-none-any.whl → 0.1.14__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.
Files changed (58) hide show
  1. airia/client/_request_handler/__init__.py +4 -0
  2. airia/client/_request_handler/async_request_handler.py +272 -0
  3. airia/client/_request_handler/base_request_handler.py +108 -0
  4. airia/client/_request_handler/sync_request_handler.py +255 -0
  5. airia/client/async_client.py +25 -584
  6. airia/client/base_client.py +2 -209
  7. airia/client/conversations/__init__.py +4 -0
  8. airia/client/conversations/async_conversations.py +187 -0
  9. airia/client/conversations/base_conversations.py +135 -0
  10. airia/client/conversations/sync_conversations.py +182 -0
  11. airia/client/pipeline_execution/__init__.py +4 -0
  12. airia/client/pipeline_execution/async_pipeline_execution.py +178 -0
  13. airia/client/pipeline_execution/base_pipeline_execution.py +96 -0
  14. airia/client/pipeline_execution/sync_pipeline_execution.py +178 -0
  15. airia/client/pipelines_config/__init__.py +4 -0
  16. airia/client/pipelines_config/async_pipelines_config.py +127 -0
  17. airia/client/pipelines_config/base_pipelines_config.py +76 -0
  18. airia/client/pipelines_config/sync_pipelines_config.py +127 -0
  19. airia/client/project/__init__.py +4 -0
  20. airia/client/project/async_project.py +122 -0
  21. airia/client/project/base_project.py +74 -0
  22. airia/client/project/sync_project.py +120 -0
  23. airia/client/store/__init__.py +4 -0
  24. airia/client/store/async_store.py +377 -0
  25. airia/client/store/base_store.py +243 -0
  26. airia/client/store/sync_store.py +352 -0
  27. airia/client/sync_client.py +25 -563
  28. airia/constants.py +13 -2
  29. airia/exceptions.py +8 -8
  30. airia/logs.py +10 -32
  31. airia/types/__init__.py +0 -0
  32. airia/types/_request_data.py +29 -2
  33. airia/types/api/__init__.py +0 -19
  34. airia/types/api/conversations/__init__.py +3 -0
  35. airia/types/api/conversations/_conversations.py +115 -0
  36. airia/types/api/pipeline_execution/__init__.py +13 -0
  37. airia/types/api/pipeline_execution/_pipeline_execution.py +76 -0
  38. airia/types/api/pipelines_config/__init__.py +3 -0
  39. airia/types/api/pipelines_config/get_pipeline_config.py +401 -0
  40. airia/types/api/project/__init__.py +3 -0
  41. airia/types/api/project/get_projects.py +91 -0
  42. airia/types/api/store/__init__.py +4 -0
  43. airia/types/api/store/get_file.py +145 -0
  44. airia/types/api/store/get_files.py +21 -0
  45. airia/types/sse/__init__.py +8 -0
  46. airia/types/sse/sse_messages.py +209 -0
  47. airia/utils/sse_parser.py +40 -7
  48. airia-0.1.14.dist-info/METADATA +221 -0
  49. airia-0.1.14.dist-info/RECORD +55 -0
  50. airia/types/api/conversations.py +0 -14
  51. airia/types/api/get_pipeline_config.py +0 -183
  52. airia/types/api/get_projects.py +0 -35
  53. airia/types/api/pipeline_execution.py +0 -29
  54. airia-0.1.12.dist-info/METADATA +0 -705
  55. airia-0.1.12.dist-info/RECORD +0 -23
  56. {airia-0.1.12.dist-info → airia-0.1.14.dist-info}/WHEEL +0 -0
  57. {airia-0.1.12.dist-info → airia-0.1.14.dist-info}/licenses/LICENSE +0 -0
  58. {airia-0.1.12.dist-info → airia-0.1.14.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,377 @@
1
+ from typing import Optional
2
+
3
+ from ...types._api_version import ApiVersion
4
+ from ...types.api.store import File, GetFileResponse, GetFilesResponse
5
+ from .._request_handler import AsyncRequestHandler
6
+ from .base_store import BaseStore
7
+
8
+
9
+ class AsyncStore(BaseStore):
10
+ def __init__(self, request_handler: AsyncRequestHandler):
11
+ super().__init__(request_handler)
12
+
13
+ async def upload_file(
14
+ self,
15
+ store_connector_id: str,
16
+ project_id: str,
17
+ file_path: str,
18
+ folder_id: Optional[str] = None,
19
+ pending_ingestion: bool = True,
20
+ correlation_id: Optional[str] = None,
21
+ ) -> File:
22
+ """
23
+ Upload a file to the Airia store asynchronously.
24
+
25
+ This method uploads a file to the specified store connector and project,
26
+ with optional folder organization and ingestion settings.
27
+
28
+ Args:
29
+ store_connector_id: The unique identifier of the store connector (GUID format)
30
+ project_id: The unique identifier of the project (GUID format)
31
+ file_path: Path to the file on disk
32
+ folder_id: Optional folder identifier for organizing the file (GUID format)
33
+ pending_ingestion: Whether the file should be marked as pending ingestion. Default is True.
34
+ correlation_id: Optional correlation ID for request tracing
35
+
36
+ Returns:
37
+ File: object containing details about the uploaded file.
38
+
39
+ Raises:
40
+ AiriaAPIError: If the API request fails, including cases where:
41
+ - The store_connector_id doesn't exist (404)
42
+ - The project_id doesn't exist (404)
43
+ - The folder_id is invalid (400)
44
+ - Authentication fails (401)
45
+ - Access is forbidden (403)
46
+ - Server errors (5xx)
47
+ ValueError: If required parameters are missing or invalid
48
+
49
+ Example:
50
+ ```python
51
+ import asyncio
52
+ from airia import AiriaAsyncClient
53
+
54
+ async def main():
55
+ client = AiriaAsyncClient(api_key="your_api_key")
56
+
57
+ # Upload file
58
+ uploaded_file = await client.store.upload_file(
59
+ store_connector_id="your_store_connector_id",
60
+ project_id="your_project_id",
61
+ file_path="document.pdf"
62
+ )
63
+
64
+ # Upload with folder organization
65
+ uploaded_file = await client.store.upload_file(
66
+ store_connector_id="your_store_connector_id",
67
+ project_id="your_project_id",
68
+ file_path="document.pdf",
69
+ folder_id="your_folder_id"
70
+ )
71
+
72
+ asyncio.run(main())
73
+ ```
74
+ """
75
+ request_data = self._pre_upload_file(
76
+ store_connector_id=store_connector_id,
77
+ project_id=project_id,
78
+ file_path=file_path,
79
+ folder_id=folder_id,
80
+ pending_ingestion=pending_ingestion,
81
+ correlation_id=correlation_id,
82
+ api_version=ApiVersion.V1.value,
83
+ )
84
+
85
+ try:
86
+ response = await self._request_handler.make_request_multipart(
87
+ "POST", request_data
88
+ )
89
+ return File(**response)
90
+ finally:
91
+ request_data.files["File"][1].close()
92
+
93
+ async def update_file(
94
+ self,
95
+ store_connector_id: str,
96
+ store_file_id: str,
97
+ project_id: str,
98
+ file_path: str,
99
+ pending_ingestion: bool = True,
100
+ correlation_id: Optional[str] = None,
101
+ ) -> str:
102
+ """
103
+ Update an existing file in the Airia store asynchronously.
104
+
105
+ This method updates an existing file in the specified store connector and project,
106
+ with optional ingestion settings.
107
+
108
+ Args:
109
+ store_connector_id: The unique identifier of the store connector (GUID format)
110
+ store_file_id: The unique identifier of the file to update (GUID format)
111
+ project_id: The unique identifier of the project (GUID format)
112
+ file_path: Path to the file on disk
113
+ pending_ingestion: Whether the file should be marked as pending ingestion. Default is True.
114
+ correlation_id: Optional correlation ID for request tracing
115
+
116
+ Returns:
117
+ The File ID of the updated file.
118
+
119
+ Raises:
120
+ AiriaAPIError: If the API request fails, including cases where:
121
+ - The store_connector_id doesn't exist (404)
122
+ - The store_file_id doesn't exist (404)
123
+ - The project_id doesn't exist (404)
124
+ - Authentication fails (401)
125
+ - Access is forbidden (403)
126
+ - Server errors (5xx)
127
+ ValueError: If required parameters are missing or invalid
128
+
129
+ Example:
130
+ ```python
131
+ import asyncio
132
+ from airia import AiriaAsyncClient
133
+
134
+ async def main():
135
+ client = AiriaAsyncClient(api_key="your_api_key")
136
+
137
+ # Update existing file
138
+ updated_file_id = await client.store.update_file(
139
+ store_connector_id="your_store_connector_id",
140
+ store_file_id="your_store_file_id",
141
+ project_id="your_project_id",
142
+ file_path="document.pdf"
143
+ )
144
+
145
+ asyncio.run(main())
146
+ ```
147
+ """
148
+ request_data = self._pre_update_file(
149
+ store_connector_id=store_connector_id,
150
+ store_file_id=store_file_id,
151
+ project_id=project_id,
152
+ file_path=file_path,
153
+ pending_ingestion=pending_ingestion,
154
+ correlation_id=correlation_id,
155
+ api_version=ApiVersion.V1.value,
156
+ )
157
+
158
+ try:
159
+ response = await self._request_handler.make_request_multipart(
160
+ "PUT", request_data
161
+ )
162
+ return response["fileId"]
163
+ finally:
164
+ request_data.files["File"][1].close()
165
+
166
+ async def get_file(
167
+ self,
168
+ project_id: str,
169
+ file_id: str,
170
+ correlation_id: Optional[str] = None,
171
+ ) -> GetFileResponse:
172
+ """
173
+ Retrieve a file from the Airia store asynchronously.
174
+
175
+ This method retrieves file information, download URL, and preview information
176
+ for a specific file in the given project.
177
+
178
+ Args:
179
+ project_id: The unique identifier of the project (GUID format)
180
+ file_id: The unique identifier of the file (GUID format)
181
+ correlation_id: Optional correlation ID for request tracing
182
+
183
+ Returns:
184
+ GetFileResponse: File information including metadata, download info, and preview info
185
+
186
+ Raises:
187
+ AiriaAPIError: If the API request fails, including cases where:
188
+ - The project_id doesn't exist (404)
189
+ - The file_id doesn't exist (404)
190
+ - Authentication fails (401)
191
+ - Access is forbidden (403)
192
+ - Server errors (5xx)
193
+ ValueError: If required parameters are missing or invalid
194
+
195
+ Example:
196
+ ```python
197
+ import asyncio
198
+ from airia import AiriaAsyncClient
199
+
200
+ async def main():
201
+ client = AiriaAsyncClient(api_key="your_api_key")
202
+
203
+ # Get file information
204
+ file_info = await client.store.get_file(
205
+ project_id="your_project_id",
206
+ file_id="your_file_id"
207
+ )
208
+
209
+ # Access file metadata
210
+ if file_info.file:
211
+ print(f"File name: {file_info.file.name}")
212
+ print(f"File size: {file_info.file.size}")
213
+ print(f"Status: {file_info.file.status}")
214
+
215
+ # Access download URL
216
+ if file_info.downloadInfo:
217
+ print(f"Download URL: {file_info.downloadInfo.url}")
218
+
219
+ # Access preview information
220
+ if file_info.previewInfo:
221
+ print(f"Preview URL: {file_info.previewInfo.previewUrl}")
222
+
223
+ asyncio.run(main())
224
+ ```
225
+
226
+ Note:
227
+ The response includes three optional components:
228
+ - file: File metadata and processing status
229
+ - downloadInfo: Direct download URL for the file
230
+ - previewInfo: Preview URL and connector information
231
+ """
232
+ request_data = self._pre_get_file(
233
+ project_id=project_id,
234
+ file_id=file_id,
235
+ correlation_id=correlation_id,
236
+ api_version=ApiVersion.V1.value,
237
+ )
238
+
239
+ response = await self._request_handler.make_request(
240
+ "GET", request_data, return_json=True
241
+ )
242
+
243
+ return GetFileResponse(**response)
244
+
245
+ async def get_files(
246
+ self,
247
+ project_id: str,
248
+ store_connector_id: str,
249
+ correlation_id: Optional[str] = None,
250
+ ) -> GetFilesResponse:
251
+ """
252
+ Retrieve all files from a store connector in the Airia store asynchronously.
253
+
254
+ This method retrieves information about all files in the specified store connector
255
+ and project, including file metadata, download URLs, and processing status.
256
+
257
+ Args:
258
+ project_id: The unique identifier of the project (GUID format)
259
+ store_connector_id: The unique identifier of the store connector (GUID format)
260
+ correlation_id: Optional correlation ID for request tracing
261
+
262
+ Returns:
263
+ GetFilesResponse: List of files with metadata, download info, and total count
264
+
265
+ Raises:
266
+ AiriaAPIError: If the API request fails, including cases where:
267
+ - The project_id doesn't exist (404)
268
+ - The store_connector_id doesn't exist (404)
269
+ - Authentication fails (401)
270
+ - Access is forbidden (403)
271
+ - Server errors (5xx)
272
+ ValueError: If required parameters are missing or invalid
273
+
274
+ Example:
275
+ ```python
276
+ import asyncio
277
+ from airia import AiriaAsyncClient
278
+
279
+ async def main():
280
+ client = AiriaAsyncClient(api_key="your_api_key")
281
+
282
+ # Get all files from a store connector
283
+ files_response = await client.store.get_files(
284
+ project_id="your_project_id",
285
+ store_connector_id="your_store_connector_id"
286
+ )
287
+
288
+ # Access files list
289
+ if files_response.files:
290
+ for file in files_response.files:
291
+ print(f"File: {file.name}, Status: {file.status}, Size: {file.size}")
292
+
293
+ # Access download URLs
294
+ if files_response.downloadInfos:
295
+ for download_info in files_response.downloadInfos:
296
+ print(f"File ID: {download_info.fileId}, URL: {download_info.url}")
297
+
298
+ # Access total count
299
+ print(f"Total files: {files_response.totalCount}")
300
+
301
+ asyncio.run(main())
302
+ ```
303
+
304
+ Note:
305
+ The response includes:
306
+ - files: List of file metadata and processing status
307
+ - downloadInfos: List of direct download URLs for files
308
+ - totalCount: Total number of files in the store connector
309
+ """
310
+ request_data = self._pre_get_files(
311
+ project_id=project_id,
312
+ store_connector_id=store_connector_id,
313
+ correlation_id=correlation_id,
314
+ api_version=ApiVersion.V1.value,
315
+ )
316
+
317
+ response = await self._request_handler.make_request(
318
+ "GET", request_data, return_json=True
319
+ )
320
+
321
+ return GetFilesResponse(**response)
322
+
323
+ async def delete_file(
324
+ self,
325
+ project_id: str,
326
+ file_id: str,
327
+ correlation_id: Optional[str] = None,
328
+ ) -> None:
329
+ """
330
+ Delete a file from the Airia store asynchronously.
331
+
332
+ This method deletes a specific file from the given project.
333
+
334
+ Args:
335
+ project_id: The unique identifier of the project (GUID format)
336
+ file_id: The unique identifier of the file to delete (GUID format)
337
+ correlation_id: Optional correlation ID for request tracing
338
+
339
+ Returns:
340
+ None
341
+
342
+ Raises:
343
+ AiriaAPIError: If the API request fails, including cases where:
344
+ - The project_id doesn't exist (404)
345
+ - The file_id doesn't exist (404)
346
+ - Authentication fails (401)
347
+ - Access is forbidden (403)
348
+ - Server errors (5xx)
349
+ ValueError: If required parameters are missing or invalid
350
+
351
+ Example:
352
+ ```python
353
+ import asyncio
354
+ from airia import AiriaAsyncClient
355
+
356
+ async def main():
357
+ client = AiriaAsyncClient(api_key="your_api_key")
358
+
359
+ # Delete a file
360
+ await client.store.delete_file(
361
+ project_id="your_project_id",
362
+ file_id="your_file_id"
363
+ )
364
+
365
+ asyncio.run(main())
366
+ ```
367
+ """
368
+ request_data = self._pre_delete_file(
369
+ project_id=project_id,
370
+ file_id=file_id,
371
+ correlation_id=correlation_id,
372
+ api_version=ApiVersion.V1.value,
373
+ )
374
+
375
+ await self._request_handler.make_request(
376
+ "DELETE", request_data, return_json=False
377
+ )
@@ -0,0 +1,243 @@
1
+ import os
2
+ from mimetypes import guess_type
3
+ from typing import Optional, Union
4
+ from urllib.parse import urljoin
5
+
6
+ from ...types._api_version import ApiVersion
7
+ from .._request_handler import AsyncRequestHandler, RequestHandler
8
+
9
+
10
+ class BaseStore:
11
+ def __init__(self, request_handler: Union[RequestHandler, AsyncRequestHandler]):
12
+ self._request_handler = request_handler
13
+
14
+ def _pre_upload_file(
15
+ self,
16
+ store_connector_id: str,
17
+ project_id: str,
18
+ file_path: str,
19
+ folder_id: Optional[str] = None,
20
+ pending_ingestion: bool = True,
21
+ correlation_id: Optional[str] = None,
22
+ api_version: str = ApiVersion.V1.value,
23
+ ):
24
+ """
25
+ Prepare request data for file upload endpoint.
26
+
27
+ This internal method constructs the URL for file upload requests
28
+ and prepares the multipart form data payload.
29
+
30
+ Args:
31
+ store_connector_id: ID of the store connector
32
+ project_id: ID of the project
33
+ file_path: Path to the file on disk
34
+ folder_id: Optional folder ID
35
+ pending_ingestion: Whether the file is pending ingestion
36
+ correlation_id: Optional correlation ID for tracing
37
+ api_version: API version to use for the request
38
+
39
+ Returns:
40
+ RequestData: Prepared request data for the file upload endpoint
41
+
42
+ Raises:
43
+ ValueError: If an invalid API version is provided
44
+ """
45
+ if api_version not in ApiVersion.as_list():
46
+ raise ValueError(
47
+ f"Invalid API version: {api_version}. Valid versions are: {', '.join(ApiVersion.as_list())}"
48
+ )
49
+ url = urljoin(self._request_handler.base_url, f"{api_version}/Store/UploadFile")
50
+
51
+ payload = {
52
+ "StoreConnectorId": store_connector_id,
53
+ "ProjectId": project_id,
54
+ "PendingIngestion": str(pending_ingestion).lower(),
55
+ "FolderId": folder_id or "",
56
+ }
57
+ files = {
58
+ "File": (
59
+ os.path.basename(file_path),
60
+ open(file_path, "rb"),
61
+ guess_type(file_path)[0],
62
+ )
63
+ }
64
+
65
+ request_data = self._request_handler.prepare_request(
66
+ url, payload=payload, files=files, correlation_id=correlation_id
67
+ )
68
+
69
+ return request_data
70
+
71
+ def _pre_update_file(
72
+ self,
73
+ store_connector_id: str,
74
+ store_file_id: str,
75
+ project_id: str,
76
+ file_path: str,
77
+ pending_ingestion: bool = True,
78
+ correlation_id: Optional[str] = None,
79
+ api_version: str = ApiVersion.V1.value,
80
+ ):
81
+ """
82
+ Prepare request data for file update endpoint.
83
+
84
+ This internal method constructs the URL for file update requests
85
+ and prepares the multipart form data payload.
86
+
87
+ Args:
88
+ store_connector_id: ID of the store connector
89
+ store_file_id: ID of the file to update
90
+ project_id: ID of the project
91
+ file_path: Path to the file on disk
92
+ pending_ingestion: Whether the file is pending ingestion
93
+ correlation_id: Optional correlation ID for tracing
94
+ api_version: API version to use for the request
95
+
96
+ Returns:
97
+ RequestData: Prepared request data for the file update endpoint
98
+
99
+ Raises:
100
+ ValueError: If an invalid API version is provided
101
+ """
102
+ if api_version not in ApiVersion.as_list():
103
+ raise ValueError(
104
+ f"Invalid API version: {api_version}. Valid versions are: {', '.join(ApiVersion.as_list())}"
105
+ )
106
+ url = urljoin(self._request_handler.base_url, f"{api_version}/Store/UpdateFile")
107
+
108
+ payload = {
109
+ "StoreConnectorId": store_connector_id,
110
+ "StoreFileId": store_file_id,
111
+ "ProjectId": project_id,
112
+ "PendingIngestion": str(pending_ingestion).lower(),
113
+ }
114
+ files = {
115
+ "File": (
116
+ os.path.basename(file_path),
117
+ open(file_path, "rb"),
118
+ guess_type(file_path)[0],
119
+ )
120
+ }
121
+
122
+ request_data = self._request_handler.prepare_request(
123
+ url, payload=payload, files=files, correlation_id=correlation_id
124
+ )
125
+
126
+ return request_data
127
+
128
+ def _pre_get_file(
129
+ self,
130
+ project_id: str,
131
+ file_id: str,
132
+ correlation_id: Optional[str] = None,
133
+ api_version: str = ApiVersion.V1.value,
134
+ ):
135
+ """
136
+ Prepare request data for get file endpoint.
137
+
138
+ This internal method constructs the URL for file retrieval requests.
139
+
140
+ Args:
141
+ project_id: ID of the project
142
+ file_id: ID of the file
143
+ correlation_id: Optional correlation ID for tracing
144
+ api_version: API version to use for the request
145
+
146
+ Returns:
147
+ RequestData: Prepared request data for the get file endpoint
148
+
149
+ Raises:
150
+ ValueError: If an invalid API version is provided
151
+ """
152
+ if api_version not in ApiVersion.as_list():
153
+ raise ValueError(
154
+ f"Invalid API version: {api_version}. Valid versions are: {', '.join(ApiVersion.as_list())}"
155
+ )
156
+ url = urljoin(
157
+ self._request_handler.base_url,
158
+ f"{api_version}/Store/GetFile/{project_id}/{file_id}",
159
+ )
160
+
161
+ request_data = self._request_handler.prepare_request(
162
+ url, payload=None, correlation_id=correlation_id
163
+ )
164
+
165
+ return request_data
166
+
167
+ def _pre_get_files(
168
+ self,
169
+ project_id: str,
170
+ store_connector_id: str,
171
+ correlation_id: Optional[str] = None,
172
+ api_version: str = ApiVersion.V1.value,
173
+ ):
174
+ """
175
+ Prepare request data for get files endpoint.
176
+
177
+ This internal method constructs the URL for files retrieval requests.
178
+
179
+ Args:
180
+ project_id: ID of the project
181
+ store_connector_id: ID of the store connector
182
+ correlation_id: Optional correlation ID for tracing
183
+ api_version: API version to use for the request
184
+
185
+ Returns:
186
+ RequestData: Prepared request data for the get files endpoint
187
+
188
+ Raises:
189
+ ValueError: If an invalid API version is provided
190
+ """
191
+ if api_version not in ApiVersion.as_list():
192
+ raise ValueError(
193
+ f"Invalid API version: {api_version}. Valid versions are: {', '.join(ApiVersion.as_list())}"
194
+ )
195
+ url = urljoin(
196
+ self._request_handler.base_url,
197
+ f"{api_version}/Store/GetAllFiles/{project_id}/{store_connector_id}",
198
+ )
199
+
200
+ request_data = self._request_handler.prepare_request(
201
+ url, payload=None, correlation_id=correlation_id
202
+ )
203
+
204
+ return request_data
205
+
206
+ def _pre_delete_file(
207
+ self,
208
+ project_id: str,
209
+ file_id: str,
210
+ correlation_id: Optional[str] = None,
211
+ api_version: str = ApiVersion.V1.value,
212
+ ):
213
+ """
214
+ Prepare request data for delete file endpoint.
215
+
216
+ This internal method constructs the URL for file deletion requests.
217
+
218
+ Args:
219
+ project_id: ID of the project
220
+ file_id: ID of the file to delete
221
+ correlation_id: Optional correlation ID for tracing
222
+ api_version: API version to use for the request
223
+
224
+ Returns:
225
+ RequestData: Prepared request data for the delete file endpoint
226
+
227
+ Raises:
228
+ ValueError: If an invalid API version is provided
229
+ """
230
+ if api_version not in ApiVersion.as_list():
231
+ raise ValueError(
232
+ f"Invalid API version: {api_version}. Valid versions are: {', '.join(ApiVersion.as_list())}"
233
+ )
234
+ url = urljoin(
235
+ self._request_handler.base_url,
236
+ f"{api_version}/Store/DeleteFile/{project_id}/{file_id}",
237
+ )
238
+
239
+ request_data = self._request_handler.prepare_request(
240
+ url, payload=None, correlation_id=correlation_id
241
+ )
242
+
243
+ return request_data