dotstat_io 1.0.1__py3-none-any.whl → 1.0.3__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.

Potentially problematic release.


This version of dotstat_io might be problematic. Click here for more details.

dotstat_io/client.py CHANGED
@@ -97,10 +97,15 @@ class Client():
97
97
  self.__log.info(' ' + line)
98
98
  else:
99
99
  if response.status_code != 200:
100
- returned_result = self.__ERROR_OCCURRED + 'Error code: ' + \
101
- str(response.status_code) + ' Reason: ' + str(response.reason)
100
+ returned_result = self.__ERROR_OCCURRED
101
+ if len(str(response.status_code)) > 0:
102
+ returned_result += 'Error code: ' + str(response.status_code) + os.linesep
103
+ if len(str(response.reason)) > 0:
104
+ returned_result += 'Reason: ' + str(response.reason) + os.linesep
102
105
  if len(response.text) > 0:
103
- returned_result += os.linesep + 'Text: ' + response.text
106
+ returned_result += 'Text: ' + response.text
107
+
108
+ returned_result += os.linesep
104
109
  else:
105
110
  if os.path.isfile(file_path):
106
111
  os.remove(file_path)
@@ -237,31 +242,159 @@ class Client():
237
242
 
238
243
  returned_result = returned_result + result + os.linesep
239
244
  else:
240
- returned_result = self.__ERROR_OCCURRED + 'Error code: ' + str(response.status_code) + os.linesep
245
+ returned_result = self.__ERROR_OCCURRED
246
+ if len(str(response.status_code)) > 0:
247
+ returned_result += 'Error code: ' + str(response.status_code) + os.linesep
241
248
  if len(str(response.reason)) > 0:
242
249
  returned_result += 'Reason: ' + str(response.reason) + os.linesep
243
250
  if len(response.text) > 0:
244
- returned_result = returned_result + os.linesep + 'Text: ' + response.text
251
+ returned_result += 'Text: ' + response.text
245
252
 
246
- returned_result = returned_result + os.linesep
253
+ returned_result += os.linesep
247
254
  # Write the result to the log
248
255
  for line in returned_result.split(os.linesep):
249
256
  if len(line) > 0:
250
257
  self.__log.info(' ' + line)
251
258
  except ValueError as err:
252
- returned_result = self.__ERROR_OCCURRED + os.linesep
259
+ returned_result = self.__ERROR_OCCURRED
253
260
  if len(str(response.status_code)) > 0:
254
261
  returned_result += 'Error code: ' + str(response.status_code) + os.linesep
255
262
  if len(str(response.reason)) > 0:
256
263
  returned_result += 'Reason: ' + str(response.reason) + os.linesep
257
264
  if len(response.text) > 0:
258
- returned_result += str(response.text)
265
+ returned_result += 'Text: ' + str(response.text)
259
266
  else:
260
267
  returned_result += str(err)
268
+
269
+ returned_result += os.linesep
261
270
  finally:
262
271
  return returned_result
263
272
 
264
273
 
274
+ # Upload an Excel data file to .Stat Suite
275
+ def upload_excel_data_file(self,
276
+ transfer_url: str,
277
+ excelfile_path: Path,
278
+ eddfile_path: Path,
279
+ space: str,
280
+ validationType: int):
281
+ try:
282
+ returned_result = ""
283
+
284
+ #
285
+ if self.__authentication_obj is not None:
286
+ self.__access_token = self.__authentication_obj.get_token()
287
+
288
+ payload = {
289
+ 'dataspace': space,
290
+ 'validationType': validationType
291
+ }
292
+
293
+ headers = {
294
+ 'accept': 'application/json',
295
+ 'authorization': "Bearer "+self.__access_token
296
+ }
297
+
298
+ excel_file = open(os.path.realpath(excelfile_path), 'rb')
299
+ eddfile_file = open(os.path.realpath(eddfile_path), 'rb')
300
+ files = {
301
+ 'dataspace': (None, payload['dataspace']),
302
+ 'validationType': (None, payload['validationType']),
303
+ 'excelFile': (str(excelfile_path), excel_file, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', ''),
304
+ 'eddFile': (str(eddfile_path), eddfile_file, 'text/xml', '')
305
+ }
306
+
307
+ #
308
+ response = requests.post(transfer_url, verify=True, headers=headers, files=files)
309
+ except Exception as err:
310
+ returned_result = self.__ERROR_OCCURRED + str(err) + os.linesep
311
+
312
+ # Write the result to the log
313
+ for line in returned_result.split(os.linesep):
314
+ if len(line) > 0:
315
+ self.__log.info(' ' + line)
316
+ else:
317
+ # If the response object cannot be converted to json, return an error
318
+ results_json = None
319
+ try:
320
+ results_json = json.loads(response.text)
321
+ if response.status_code == 200:
322
+ result = results_json['message']
323
+ # Write the result to the log
324
+ for line in result.split(os.linesep):
325
+ if len(line) > 0:
326
+ self.__log.info(' ' + line)
327
+
328
+ returned_result = result + os.linesep
329
+
330
+ # Check the request status
331
+ if (result != "" and result.find(self.__ERROR_OCCURRED ) == -1):
332
+ # Extract the request ID the returned message
333
+ start = 'with ID'
334
+ end = 'was successfully'
335
+ requestId = result[result.find(
336
+ start)+len(start):result.rfind(end)]
337
+
338
+ # Sleep a little bit before checking the request status
339
+ sleep(3)
340
+
341
+ # To avoid this error: maximum recursion depth exceeded while calling a Python object
342
+ # replace the recursive calls with while loops.
343
+ result = self.__check_request_status(transfer_url, requestId, space)
344
+
345
+ # Write the result to the log
346
+ for line in result.split(os.linesep):
347
+ if len(line) > 0:
348
+ self.__log.info(' ' + line)
349
+ sleep(3)
350
+
351
+ previous_result = result
352
+ while (result in [self.__EXECUTION_IN_PROGRESS, self.__EXECUTION_IN_QUEUED]
353
+ or self.__CONNECTION_ABORTED in result):
354
+ result = self.__check_request_status(transfer_url, requestId, space)
355
+
356
+ # Prevent loging again the same information such as "Queued" or "InProgress"
357
+ if previous_result != result:
358
+ previous_result = result
359
+
360
+ # Write the result to the log
361
+ for line in previous_result.split(os.linesep):
362
+ if (len(line) > 0 and line not in [self.__EXECUTION_IN_PROGRESS, self.__EXECUTION_IN_QUEUED]
363
+ and self.__CONNECTION_ABORTED not in line):
364
+ self.__log.info(' ' + line)
365
+ sleep(3)
366
+
367
+ returned_result = returned_result + result + os.linesep
368
+ else:
369
+ returned_result = self.__ERROR_OCCURRED
370
+ if len(str(response.status_code)) > 0:
371
+ returned_result += 'Error code: ' + str(response.status_code) + os.linesep
372
+ if len(str(response.reason)) > 0:
373
+ returned_result += 'Reason: ' + str(response.reason) + os.linesep
374
+ if len(response.text) > 0:
375
+ returned_result += 'Text: ' + response.text
376
+
377
+ returned_result += os.linesep
378
+ # Write the result to the log
379
+ for line in returned_result.split(os.linesep):
380
+ if len(line) > 0:
381
+ self.__log.info(' ' + line)
382
+ except ValueError as err:
383
+ returned_result = self.__ERROR_OCCURRED
384
+ if len(str(response.status_code)) > 0:
385
+ returned_result += 'Error code: ' + str(response.status_code) + os.linesep
386
+ if len(str(response.reason)) > 0:
387
+ returned_result += 'Reason: ' + str(response.reason) + os.linesep
388
+ if len(response.text) > 0:
389
+ returned_result += 'Text: ' + str(response.text)
390
+ else:
391
+ returned_result += str(err)
392
+
393
+ returned_result += os.linesep
394
+ finally:
395
+ return returned_result
396
+
397
+
265
398
  # Upload a structure file to .Stat Suite
266
399
  def upload_structure(self, transfer_url: str, file_path: Path):
267
400
  try:
@@ -360,8 +493,11 @@ class Client():
360
493
  }
361
494
 
362
495
  transfer_url = transfer_url.replace("import", "status")
363
- transfer_url = transfer_url.replace("sdmxFile", "request")
364
-
496
+ if "sdmxFile" in transfer_url:
497
+ transfer_url = transfer_url.replace("sdmxFile", "request")
498
+ elif "excel" in transfer_url:
499
+ transfer_url = transfer_url.replace("excel", "request")
500
+
365
501
  #
366
502
  response = requests.post(transfer_url, verify=True, headers=headers, data=payload)
367
503
  except Exception as err:
@@ -383,20 +519,27 @@ class Client():
383
519
  returned_result = returned_result + 'Log' + str(index) + ': ' + results_json['logs'][index]['message'] + os.linesep
384
520
  index += 1
385
521
  else:
386
- returned_result = self.__ERROR_OCCURRED + 'Error code: ' + \
387
- str(response.status_code) + ' Reason: ' + str(response.reason)
522
+ returned_result = self.__ERROR_OCCURRED
523
+ if len(str(response.status_code)) > 0:
524
+ returned_result += 'Error code: ' + str(response.status_code) + os.linesep
525
+ if len(str(response.reason)) > 0:
526
+ returned_result += 'Reason: ' + str(response.reason) + os.linesep
388
527
  if len(response.text) > 0:
389
- returned_result = returned_result + os.linesep + 'Text: ' + response.text
528
+ returned_result += 'Text: ' + str(response.text)
529
+
530
+ returned_result += os.linesep
390
531
  except ValueError as err:
391
- returned_result = self.__ERROR_OCCURRED + os.linesep
532
+ returned_result = self.__ERROR_OCCURRED
392
533
  if len(str(response.status_code)) > 0:
393
534
  returned_result += 'Error code: ' + str(response.status_code) + os.linesep
394
535
  if len(str(response.reason)) > 0:
395
536
  returned_result += 'Reason: ' + str(response.reason) + os.linesep
396
537
  if len(response.text) > 0:
397
- returned_result += str(response.text)
538
+ returned_result += 'Text: ' + str(response.text)
398
539
  else:
399
540
  returned_result += str(err)
541
+
542
+ returned_result += os.linesep
400
543
  finally:
401
544
  return returned_result
402
545
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dotstat_io
3
- Version: 1.0.1
3
+ Version: 1.0.3
4
4
  Summary: Utility to download or upload data from/to .Stat Suite using ADFS authentication to connect to it
5
5
  License: MIT
6
6
  Author: Gyorgy Gyomai
@@ -147,12 +147,25 @@ returned_result = client_obj.upload_data_file(
147
147
  transfer_url, Path(file_path), space, validationType, use_filepath)
148
148
  ```
149
149
  * `transfer_url:` URL of the transfer service
150
- * `file_path:` The full path of the SDMX-CSV file, which will be uploaded to .Stat Suite
150
+ * `file_path:` The full path of the SDMX-CSV file to be imported
151
151
  * `space:` Data space where the file will be uploaded
152
152
  * `validationType:` The type of validation to use during upload. Possible values: Basic Validation (0), Advanced Validation (1)
153
153
  * `use_filepath:` Use a file path of a shared folder accessible by the .Stat Suite data upload engine (for unlimited file sizes)
154
154
 
155
- #### 6. To upload a structure to .Stat Suite:
155
+ #### 6. To upload an Excel data file to .Stat Suite:
156
+ ```python
157
+ from dotstat_io.client import Client
158
+ client_obj = Client.init_with_authentication_obj(Authentication_obj)
159
+ returned_result = client_obj.upload_excel_data_file(
160
+ transfer_url, Path(excelfile_path), Path(eddfile_path), space, validationType)
161
+ ```
162
+ * `transfer_url:` URL of the transfer service
163
+ * `excelfile_path:` The full path of the Excel file containing the data/referential metadata values to be imported
164
+ * `eddfile_path:` The full path of the XML edd file containing the description of the Excel file to be imported
165
+ * `space:` Data space where the file will be uploaded
166
+ * `validationType:` The type of validation to use during upload. Possible values: Basic Validation (0), Advanced Validation (1)
167
+
168
+ #### 7. To upload a structure to .Stat Suite:
156
169
  ```python
157
170
  from dotstat_io.client import Client
158
171
  client_obj = Client.init_with_authentication_obj(Authentication_obj)
@@ -160,7 +173,7 @@ returned_result = client_obj.upload_structure(
160
173
  transfer_url, Path(file_path))
161
174
  ```
162
175
  * `transfer_url:` URL of the transfer service
163
- * `file_path:` The full path of the SDMX-ML file, which will be uploaded to .Stat Suite
176
+ * `file_path:` The full path of the SDMX-ML file to be imported
164
177
 
165
178
  ### For more information about how to use this package, all test cases can be accessed from this [`link`](https://gitlab.algobank.oecd.org/SD_ENGINEERING/dotstat_io/dotstat_io-package/-/blob/main/tests/test_cases.py)
166
179
 
@@ -0,0 +1,6 @@
1
+ dotstat_io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ dotstat_io/authentication.py,sha256=6mxRXuDUgU7wBrUNMzoXU_PFCF1bLGAiGgVrwOePmZw,14057
3
+ dotstat_io/client.py,sha256=liX5qINwEVb3r0mUH9OsBvggSalXFn-GZvPTxONb_GY,23324
4
+ dotstat_io-1.0.3.dist-info/METADATA,sha256=ldQBfsHNmKSGi-bVhaPcMI_M3GIWwmEsCny0Y9SjJQc,8001
5
+ dotstat_io-1.0.3.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
6
+ dotstat_io-1.0.3.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- dotstat_io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- dotstat_io/authentication.py,sha256=6mxRXuDUgU7wBrUNMzoXU_PFCF1bLGAiGgVrwOePmZw,14057
3
- dotstat_io/client.py,sha256=_GuDXvOGpg8WxW6Qw5yvTbMRN70nRIaWUojS7FSJ2WA,16630
4
- dotstat_io-1.0.1.dist-info/METADATA,sha256=Llnfc4eItd4ivCc65plilOihe-2sj4xJfWnzBYTtqXQ,7280
5
- dotstat_io-1.0.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
6
- dotstat_io-1.0.1.dist-info/RECORD,,