keboola.component 1.4.2__tar.gz → 1.4.4__tar.gz
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.
- {keboola.component-1.4.2/src/keboola.component.egg-info → keboola.component-1.4.4}/PKG-INFO +1 -1
- {keboola.component-1.4.2 → keboola.component-1.4.4}/setup.py +1 -1
- {keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola/component/dao.py +66 -15
- {keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola/component/interface.py +39 -23
- {keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola/component/sync_actions.py +2 -2
- {keboola.component-1.4.2 → keboola.component-1.4.4/src/keboola.component.egg-info}/PKG-INFO +1 -1
- {keboola.component-1.4.2 → keboola.component-1.4.4}/LICENSE +0 -0
- {keboola.component-1.4.2 → keboola.component-1.4.4}/README.md +0 -0
- {keboola.component-1.4.2 → keboola.component-1.4.4}/setup.cfg +0 -0
- {keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola/component/__init__.py +0 -0
- {keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola/component/base.py +0 -0
- {keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola/component/exceptions.py +0 -0
- {keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola/component/table_schema.py +0 -0
- {keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola.component.egg-info/SOURCES.txt +0 -0
- {keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola.component.egg-info/dependency_links.txt +0 -0
- {keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola.component.egg-info/not-zip-safe +0 -0
- {keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola.component.egg-info/requires.txt +0 -0
- {keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola.component.egg-info/top_level.txt +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import dataclasses
|
|
2
2
|
import json
|
|
3
|
+
import logging
|
|
3
4
|
from abc import ABC, abstractmethod
|
|
4
5
|
from dataclasses import dataclass
|
|
5
6
|
from datetime import datetime
|
|
@@ -7,6 +8,11 @@ from enum import Enum
|
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from typing import List, Union, Dict, Optional
|
|
9
10
|
|
|
11
|
+
try:
|
|
12
|
+
from typing import Literal
|
|
13
|
+
except ImportError:
|
|
14
|
+
from typing_extensions import Literal
|
|
15
|
+
|
|
10
16
|
KBC_DEFAULT_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S%z'
|
|
11
17
|
|
|
12
18
|
|
|
@@ -381,6 +387,30 @@ class TableMetadata:
|
|
|
381
387
|
raise ValueError(', '.join(errors) + f'\n Supported base types are: [{SupportedDataTypes.list()}]')
|
|
382
388
|
|
|
383
389
|
|
|
390
|
+
@dataclass
|
|
391
|
+
class SupportedManifestAttributes(SubscriptableDataclass):
|
|
392
|
+
out_attributes: List[str]
|
|
393
|
+
in_attributes: List[str]
|
|
394
|
+
out_legacy_exclude: List[str] = dataclasses.field(default_factory=lambda: [])
|
|
395
|
+
in_legacy_exclude: List[str] = dataclasses.field(default_factory=lambda: [])
|
|
396
|
+
|
|
397
|
+
def get_attributes_by_stage(self, stage: Literal["in", "out"], legacy_queue: bool = False) -> List[str]:
|
|
398
|
+
if stage == 'out':
|
|
399
|
+
attributes = self.out_attributes
|
|
400
|
+
exclude = self.out_legacy_exclude
|
|
401
|
+
elif stage == 'in':
|
|
402
|
+
attributes = self.in_attributes
|
|
403
|
+
exclude = self.in_legacy_exclude
|
|
404
|
+
else:
|
|
405
|
+
raise ValueError(f"Unsupported stage {stage}")
|
|
406
|
+
|
|
407
|
+
if legacy_queue:
|
|
408
|
+
logging.warning(f"Running on legacy queue some manifest properties will be ignored: {exclude}")
|
|
409
|
+
attributes = list(set(attributes).difference(exclude))
|
|
410
|
+
|
|
411
|
+
return attributes
|
|
412
|
+
|
|
413
|
+
|
|
384
414
|
class IODefinition(ABC):
|
|
385
415
|
|
|
386
416
|
def __init__(self, full_path):
|
|
@@ -396,7 +426,7 @@ class IODefinition(ABC):
|
|
|
396
426
|
):
|
|
397
427
|
raise NotImplementedError
|
|
398
428
|
|
|
399
|
-
def _filter_attributes_by_manifest_type(self, manifest_type):
|
|
429
|
+
def _filter_attributes_by_manifest_type(self, manifest_type: Literal["in", "out"], legacy_queue: bool = False):
|
|
400
430
|
"""
|
|
401
431
|
Filter manifest to contain only supported fields
|
|
402
432
|
Args:
|
|
@@ -405,7 +435,8 @@ class IODefinition(ABC):
|
|
|
405
435
|
Returns:
|
|
406
436
|
|
|
407
437
|
"""
|
|
408
|
-
supported_fields = self._manifest_attributes.
|
|
438
|
+
supported_fields = self._manifest_attributes.get_attributes_by_stage(manifest_type, legacy_queue)
|
|
439
|
+
|
|
409
440
|
new_dict = self._raw_manifest.copy()
|
|
410
441
|
if supported_fields:
|
|
411
442
|
for attr in self._raw_manifest:
|
|
@@ -413,10 +444,10 @@ class IODefinition(ABC):
|
|
|
413
444
|
new_dict.pop(attr, None)
|
|
414
445
|
return new_dict
|
|
415
446
|
|
|
416
|
-
def get_manifest_dictionary(self, manifest_type: Optional[str] = None) -> dict:
|
|
447
|
+
def get_manifest_dictionary(self, manifest_type: Optional[str] = None, legacy_queue=False) -> dict:
|
|
417
448
|
"""
|
|
418
449
|
Returns manifest dictionary in appropriate manifest_type: either 'in' or 'out'.
|
|
419
|
-
By default returns output manifest.
|
|
450
|
+
By default, returns output manifest.
|
|
420
451
|
The result keeps only values that are applicable for
|
|
421
452
|
the selected type of the Manifest file. Because although input and output manifests share most of
|
|
422
453
|
the attributes, some are not shared.
|
|
@@ -428,6 +459,7 @@ class IODefinition(ABC):
|
|
|
428
459
|
manifest_type (str): either 'in' or 'out'.
|
|
429
460
|
See [manifest files](https://developers.keboola.com/extend/common-interface/manifest-files)
|
|
430
461
|
for more information.
|
|
462
|
+
legacy_queue (bool): optional flag marking project on legacy queue.(some options are not allowed on queue2)
|
|
431
463
|
|
|
432
464
|
Returns:
|
|
433
465
|
dict representation of the manifest file in a format expected / produced by the Keboola Connection
|
|
@@ -436,7 +468,7 @@ class IODefinition(ABC):
|
|
|
436
468
|
if not manifest_type:
|
|
437
469
|
manifest_type = self.stage
|
|
438
470
|
|
|
439
|
-
return self._filter_attributes_by_manifest_type(manifest_type)
|
|
471
|
+
return self._filter_attributes_by_manifest_type(manifest_type, legacy_queue)
|
|
440
472
|
|
|
441
473
|
@property
|
|
442
474
|
def stage(self) -> str:
|
|
@@ -453,11 +485,11 @@ class IODefinition(ABC):
|
|
|
453
485
|
|
|
454
486
|
@property
|
|
455
487
|
@abstractmethod
|
|
456
|
-
def _manifest_attributes(self) ->
|
|
488
|
+
def _manifest_attributes(self) -> SupportedManifestAttributes:
|
|
457
489
|
"""
|
|
458
490
|
Manifest attributes
|
|
459
491
|
"""
|
|
460
|
-
return
|
|
492
|
+
return SupportedManifestAttributes([], [])
|
|
461
493
|
|
|
462
494
|
@property
|
|
463
495
|
@abstractmethod
|
|
@@ -587,6 +619,7 @@ class TableDefinition(IODefinition):
|
|
|
587
619
|
"columns",
|
|
588
620
|
"incremental",
|
|
589
621
|
"primary_key",
|
|
622
|
+
"write_always",
|
|
590
623
|
"delimiter",
|
|
591
624
|
"enclosure",
|
|
592
625
|
"metadata",
|
|
@@ -596,6 +629,10 @@ class TableDefinition(IODefinition):
|
|
|
596
629
|
"delete_where_operator"
|
|
597
630
|
]
|
|
598
631
|
|
|
632
|
+
OUTPUT_MANIFEST_LEGACY_EXCLUDES = [
|
|
633
|
+
"write_always"
|
|
634
|
+
]
|
|
635
|
+
|
|
599
636
|
MANIFEST_ATTRIBUTES = {'in': INPUT_MANIFEST_ATTRIBUTES,
|
|
600
637
|
'out': OUTPUT_MANIFEST_ATTRIBUTES}
|
|
601
638
|
|
|
@@ -608,7 +645,9 @@ class TableDefinition(IODefinition):
|
|
|
608
645
|
enclosure: str = '"',
|
|
609
646
|
delimiter: str = ',',
|
|
610
647
|
delete_where: dict = None,
|
|
611
|
-
stage: str = 'in'
|
|
648
|
+
stage: str = 'in',
|
|
649
|
+
write_always: bool = False
|
|
650
|
+
):
|
|
612
651
|
"""
|
|
613
652
|
|
|
614
653
|
Args:
|
|
@@ -630,6 +669,8 @@ class TableDefinition(IODefinition):
|
|
|
630
669
|
delimiter: str: CSV delimiter, by default ,
|
|
631
670
|
delete_where (dict): Dict with settings for deleting rows
|
|
632
671
|
stage: str: Storage Stage 'in' or 'out'
|
|
672
|
+
write_always: Bool: If true, the table will be saved to Storage even when the job execution
|
|
673
|
+
fails.
|
|
633
674
|
"""
|
|
634
675
|
super().__init__(full_path)
|
|
635
676
|
self._name = name
|
|
@@ -650,6 +691,7 @@ class TableDefinition(IODefinition):
|
|
|
650
691
|
self.table_metadata = table_metadata
|
|
651
692
|
self.set_delete_where_from_dict(delete_where)
|
|
652
693
|
self.stage = stage
|
|
694
|
+
self.write_always = write_always
|
|
653
695
|
|
|
654
696
|
@classmethod
|
|
655
697
|
def build_from_manifest(cls,
|
|
@@ -705,8 +747,9 @@ class TableDefinition(IODefinition):
|
|
|
705
747
|
return table_def
|
|
706
748
|
|
|
707
749
|
@property
|
|
708
|
-
def _manifest_attributes(self) ->
|
|
709
|
-
return self.MANIFEST_ATTRIBUTES
|
|
750
|
+
def _manifest_attributes(self) -> SupportedManifestAttributes:
|
|
751
|
+
return SupportedManifestAttributes(self.MANIFEST_ATTRIBUTES['out'], self.MANIFEST_ATTRIBUTES['in'],
|
|
752
|
+
self.OUTPUT_MANIFEST_LEGACY_EXCLUDES)
|
|
710
753
|
|
|
711
754
|
# #### Manifest properties
|
|
712
755
|
@property
|
|
@@ -797,6 +840,14 @@ class TableDefinition(IODefinition):
|
|
|
797
840
|
if incremental:
|
|
798
841
|
self._raw_manifest['incremental'] = True
|
|
799
842
|
|
|
843
|
+
@property
|
|
844
|
+
def write_always(self) -> bool:
|
|
845
|
+
return self._raw_manifest.get('write_always', False)
|
|
846
|
+
|
|
847
|
+
@write_always.setter
|
|
848
|
+
def write_always(self, write_always: bool):
|
|
849
|
+
self._raw_manifest['write_always'] = write_always
|
|
850
|
+
|
|
800
851
|
@property
|
|
801
852
|
def primary_key(self) -> List[str]:
|
|
802
853
|
return self._raw_manifest.get('primary_key', [])
|
|
@@ -864,7 +915,7 @@ class TableDefinition(IODefinition):
|
|
|
864
915
|
self._raw_manifest['metadata'] = table_metadata.get_table_metadata_for_manifest()
|
|
865
916
|
self._raw_manifest['column_metadata'] = table_metadata.get_column_metadata_for_manifest()
|
|
866
917
|
|
|
867
|
-
def get_manifest_dictionary(self, stage_type: Optional[str] = None) -> dict:
|
|
918
|
+
def get_manifest_dictionary(self, stage_type: Optional[str] = None, legacy_queue=False) -> dict:
|
|
868
919
|
"""
|
|
869
920
|
|
|
870
921
|
Args:
|
|
@@ -877,8 +928,8 @@ class TableDefinition(IODefinition):
|
|
|
877
928
|
"""
|
|
878
929
|
# in case the table_metadata is out of sync, e.g. the object was modified in-place
|
|
879
930
|
self._set_table_metadata_to_manifest(self._table_metadata)
|
|
880
|
-
|
|
881
|
-
return
|
|
931
|
+
raw_manifest = super(TableDefinition, self).get_manifest_dictionary(stage_type, legacy_queue)
|
|
932
|
+
return raw_manifest
|
|
882
933
|
|
|
883
934
|
|
|
884
935
|
class FileDefinition(IODefinition):
|
|
@@ -1020,8 +1071,8 @@ class FileDefinition(IODefinition):
|
|
|
1020
1071
|
return Path(self.full_path).name
|
|
1021
1072
|
|
|
1022
1073
|
@property
|
|
1023
|
-
def _manifest_attributes(self) ->
|
|
1024
|
-
return
|
|
1074
|
+
def _manifest_attributes(self) -> SupportedManifestAttributes:
|
|
1075
|
+
return SupportedManifestAttributes(self.OUTPUT_MANIFEST_KEYS, [])
|
|
1025
1076
|
|
|
1026
1077
|
# ########### Output manifest properties - R/W
|
|
1027
1078
|
|
|
@@ -4,11 +4,11 @@ import glob
|
|
|
4
4
|
import json
|
|
5
5
|
import logging
|
|
6
6
|
import os
|
|
7
|
+
import sys
|
|
7
8
|
from datetime import datetime
|
|
8
9
|
from pathlib import Path
|
|
9
10
|
from typing import List, Dict, Optional, Union
|
|
10
11
|
|
|
11
|
-
import sys
|
|
12
12
|
from deprecated import deprecated
|
|
13
13
|
from pygelf import GelfUdpHandler, GelfTcpHandler
|
|
14
14
|
from pytz import utc
|
|
@@ -327,7 +327,8 @@ class CommonInterface:
|
|
|
327
327
|
table_metadata: dao.TableMetadata = None,
|
|
328
328
|
enclosure: str = '"',
|
|
329
329
|
delimiter: str = ',',
|
|
330
|
-
delete_where: dict = None
|
|
330
|
+
delete_where: dict = None,
|
|
331
|
+
write_always: bool = False) -> dao.TableDefinition:
|
|
331
332
|
"""
|
|
332
333
|
Helper method for dao.TableDefinition creation along with the "manifest".
|
|
333
334
|
It initializes path according to the storage_stage type.
|
|
@@ -347,6 +348,8 @@ class CommonInterface:
|
|
|
347
348
|
enclosure: str: CSV enclosure, by default "
|
|
348
349
|
delimiter: str: CSV delimiter, by default ,
|
|
349
350
|
delete_where: Dict with settings for deleting rows
|
|
351
|
+
write_always: Bool: If true, the table will be saved to Storage even when the job execution
|
|
352
|
+
fails.
|
|
350
353
|
"""
|
|
351
354
|
if storage_stage == 'in':
|
|
352
355
|
full_path = os.path.join(self.tables_in_path, name)
|
|
@@ -366,7 +369,8 @@ class CommonInterface:
|
|
|
366
369
|
enclosure=enclosure,
|
|
367
370
|
delimiter=delimiter,
|
|
368
371
|
delete_where=delete_where,
|
|
369
|
-
stage=storage_stage
|
|
372
|
+
stage=storage_stage,
|
|
373
|
+
write_always=write_always)
|
|
370
374
|
|
|
371
375
|
def create_in_table_definition(self, name: str,
|
|
372
376
|
is_sliced: bool = False,
|
|
@@ -410,7 +414,8 @@ class CommonInterface:
|
|
|
410
414
|
table_metadata: dao.TableMetadata = None,
|
|
411
415
|
enclosure: str = '"',
|
|
412
416
|
delimiter: str = ',',
|
|
413
|
-
delete_where: dict = None
|
|
417
|
+
delete_where: dict = None,
|
|
418
|
+
write_always: bool = False) -> dao.TableDefinition:
|
|
414
419
|
"""
|
|
415
420
|
Helper method for output dao.TableDefinition creation along with the "manifest".
|
|
416
421
|
It initializes path in data/tables/out/ folder.
|
|
@@ -426,6 +431,8 @@ class CommonInterface:
|
|
|
426
431
|
enclosure: str: CSV enclosure, by default "
|
|
427
432
|
delimiter: str: CSV delimiter, by default ,
|
|
428
433
|
delete_where: Dict with settings for deleting rows
|
|
434
|
+
write_always: Bool: If true, the table will be saved to Storage even when the job execution
|
|
435
|
+
fails.
|
|
429
436
|
"""
|
|
430
437
|
|
|
431
438
|
return self._create_table_definition(name=name,
|
|
@@ -438,7 +445,8 @@ class CommonInterface:
|
|
|
438
445
|
table_metadata=table_metadata,
|
|
439
446
|
enclosure=enclosure,
|
|
440
447
|
delimiter=delimiter,
|
|
441
|
-
delete_where=delete_where
|
|
448
|
+
delete_where=delete_where,
|
|
449
|
+
write_always=write_always)
|
|
442
450
|
|
|
443
451
|
# # File processing
|
|
444
452
|
|
|
@@ -862,8 +870,20 @@ class CommonInterface:
|
|
|
862
870
|
def files_in_path(self):
|
|
863
871
|
return os.path.join(self.data_folder_path, 'in', 'files')
|
|
864
872
|
|
|
865
|
-
@
|
|
866
|
-
def
|
|
873
|
+
@property
|
|
874
|
+
def is_legacy_queue(self) -> bool:
|
|
875
|
+
"""
|
|
876
|
+
Check if the project is running on legacy queue (v1)
|
|
877
|
+
Returns:
|
|
878
|
+
|
|
879
|
+
"""
|
|
880
|
+
features = os.environ.get('KBC_PROJECT_FEATURE_GATES')
|
|
881
|
+
is_legacy_queue = True
|
|
882
|
+
if not features or 'queuev2' in features:
|
|
883
|
+
is_legacy_queue = False
|
|
884
|
+
return is_legacy_queue
|
|
885
|
+
|
|
886
|
+
def write_manifest(self, io_definition: Union[dao.FileDefinition, dao.TableDefinition]):
|
|
867
887
|
"""
|
|
868
888
|
Write a table manifest from dao.IODefinition. Creates the appropriate manifest file in the proper location.
|
|
869
889
|
|
|
@@ -895,14 +915,14 @@ class CommonInterface:
|
|
|
895
915
|
Returns:
|
|
896
916
|
|
|
897
917
|
"""
|
|
898
|
-
|
|
918
|
+
|
|
919
|
+
manifest = io_definition.get_manifest_dictionary(legacy_queue=self.is_legacy_queue)
|
|
899
920
|
# make dirs if not exist
|
|
900
921
|
os.makedirs(os.path.dirname(io_definition.full_path), exist_ok=True)
|
|
901
922
|
with open(io_definition.full_path + '.manifest', 'w') as manifest_file:
|
|
902
923
|
json.dump(manifest, manifest_file)
|
|
903
924
|
|
|
904
|
-
|
|
905
|
-
def write_manifests(io_definitions: List[Union[dao.FileDefinition, dao.TableDefinition]]):
|
|
925
|
+
def write_manifests(self, io_definitions: List[Union[dao.FileDefinition, dao.TableDefinition]]):
|
|
906
926
|
"""
|
|
907
927
|
Process all table definition objects and create appropriate manifest files.
|
|
908
928
|
Args:
|
|
@@ -912,13 +932,12 @@ class CommonInterface:
|
|
|
912
932
|
|
|
913
933
|
"""
|
|
914
934
|
for io_def in io_definitions:
|
|
915
|
-
|
|
935
|
+
self.write_manifest(io_def)
|
|
916
936
|
|
|
917
937
|
# ############# DEPRECATED METHODS, TODO: remove
|
|
918
938
|
|
|
919
|
-
@staticmethod
|
|
920
939
|
@deprecated(version='1.3.0', reason="You should use write_manifest function")
|
|
921
|
-
def write_filedef_manifest(file_definition: dao.FileDefinition):
|
|
940
|
+
def write_filedef_manifest(self, file_definition: dao.FileDefinition):
|
|
922
941
|
"""
|
|
923
942
|
Write a table manifest from dao.FileDefinition. Creates the appropriate manifest file in the proper location.
|
|
924
943
|
|
|
@@ -942,11 +961,10 @@ class CommonInterface:
|
|
|
942
961
|
Returns:
|
|
943
962
|
|
|
944
963
|
"""
|
|
945
|
-
|
|
964
|
+
self.write_manifest(file_definition)
|
|
946
965
|
|
|
947
|
-
@staticmethod
|
|
948
966
|
@deprecated(version='1.3.0', reason="You should use write_manifests function")
|
|
949
|
-
def write_filedef_manifests(file_definitions: List[dao.FileDefinition]):
|
|
967
|
+
def write_filedef_manifests(self, file_definitions: List[dao.FileDefinition]):
|
|
950
968
|
"""
|
|
951
969
|
Process all table definition objects and create appropriate manifest files.
|
|
952
970
|
Args:
|
|
@@ -955,11 +973,10 @@ class CommonInterface:
|
|
|
955
973
|
Returns:
|
|
956
974
|
|
|
957
975
|
"""
|
|
958
|
-
|
|
976
|
+
self.write_manifests(file_definitions)
|
|
959
977
|
|
|
960
|
-
@staticmethod
|
|
961
978
|
@deprecated(version='1.3.0', reason="You should use write_manifest function")
|
|
962
|
-
def write_tabledef_manifest(table_definition: dao.TableDefinition):
|
|
979
|
+
def write_tabledef_manifest(self, table_definition: dao.TableDefinition):
|
|
963
980
|
"""
|
|
964
981
|
Write a table manifest from dao.TableDefinition. Creates the appropriate manifest file in the proper location.
|
|
965
982
|
|
|
@@ -988,11 +1005,10 @@ class CommonInterface:
|
|
|
988
1005
|
Returns:
|
|
989
1006
|
|
|
990
1007
|
"""
|
|
991
|
-
|
|
1008
|
+
self.write_manifest(table_definition)
|
|
992
1009
|
|
|
993
|
-
@staticmethod
|
|
994
1010
|
@deprecated(version='1.3.0', reason="You should use write_manifests function")
|
|
995
|
-
def write_tabledef_manifests(table_definitions: List[dao.TableDefinition]):
|
|
1011
|
+
def write_tabledef_manifests(self, table_definitions: List[dao.TableDefinition]):
|
|
996
1012
|
"""
|
|
997
1013
|
Process all table definition objects and create appropriate manifest files.
|
|
998
1014
|
Args:
|
|
@@ -1001,7 +1017,7 @@ class CommonInterface:
|
|
|
1001
1017
|
Returns:
|
|
1002
1018
|
|
|
1003
1019
|
"""
|
|
1004
|
-
|
|
1020
|
+
self.write_manifests(table_definitions)
|
|
1005
1021
|
|
|
1006
1022
|
|
|
1007
1023
|
# ########## CONFIGURATION
|
|
@@ -63,7 +63,7 @@ class SelectElement(SyncActionResult):
|
|
|
63
63
|
self.status = None
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
def process_sync_action_result(result: Union[None, dict, SyncActionResult, List[SyncActionResult]]) -> str:
|
|
66
|
+
def process_sync_action_result(result: Union[None, List[dict], dict, SyncActionResult, List[SyncActionResult]]) -> str:
|
|
67
67
|
"""
|
|
68
68
|
Converts Sync Action result into valid string (expected by Sync Action).
|
|
69
69
|
Args:
|
|
@@ -75,7 +75,7 @@ def process_sync_action_result(result: Union[None, dict, SyncActionResult, List[
|
|
|
75
75
|
if isinstance(result, SyncActionResult):
|
|
76
76
|
result_str = str(result)
|
|
77
77
|
elif isinstance(result, list):
|
|
78
|
-
result_str = f'[{", ".join([str(r) for r in result])}]'
|
|
78
|
+
result_str = f'[{", ".join([json.dumps(r) if isinstance(r, dict) else str(r) for r in result])}]'
|
|
79
79
|
elif result is None:
|
|
80
80
|
result_str = json.dumps({'status': 'success'})
|
|
81
81
|
elif isinstance(result, dict):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola.component.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola.component.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola.component.egg-info/requires.txt
RENAMED
|
File without changes
|
{keboola.component-1.4.2 → keboola.component-1.4.4}/src/keboola.component.egg-info/top_level.txt
RENAMED
|
File without changes
|