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
|
|
101
|
-
|
|
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 +=
|
|
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
|
|
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
|
|
251
|
+
returned_result += 'Text: ' + response.text
|
|
245
252
|
|
|
246
|
-
returned_result
|
|
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
|
|
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
|
-
|
|
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
|
|
387
|
-
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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,,
|
|
File without changes
|