gooddata-pipelines 1.49.1.dev1__py3-none-any.whl → 1.50.0__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 gooddata-pipelines might be problematic. Click here for more details.

Files changed (22) hide show
  1. gooddata_pipelines/__init__.py +7 -1
  2. gooddata_pipelines/api/gooddata_api.py +0 -54
  3. gooddata_pipelines/backup_and_restore/backup_manager.py +50 -44
  4. gooddata_pipelines/backup_and_restore/constants.py +2 -1
  5. gooddata_pipelines/backup_and_restore/models/storage.py +40 -2
  6. gooddata_pipelines/backup_and_restore/storage/s3_storage.py +22 -11
  7. gooddata_pipelines/provisioning/entities/users/models/permissions.py +23 -79
  8. gooddata_pipelines/provisioning/entities/users/models/user_groups.py +23 -50
  9. gooddata_pipelines/provisioning/entities/users/models/users.py +9 -49
  10. gooddata_pipelines/provisioning/entities/users/permissions.py +14 -6
  11. gooddata_pipelines/provisioning/entities/users/user_groups.py +7 -1
  12. gooddata_pipelines/provisioning/entities/users/users.py +3 -0
  13. gooddata_pipelines/provisioning/entities/workspaces/models.py +16 -15
  14. gooddata_pipelines/provisioning/entities/workspaces/workspace.py +52 -5
  15. gooddata_pipelines/provisioning/entities/workspaces/workspace_data_parser.py +9 -6
  16. gooddata_pipelines/provisioning/provisioning.py +24 -6
  17. gooddata_pipelines/provisioning/utils/context_objects.py +6 -6
  18. gooddata_pipelines/provisioning/utils/utils.py +3 -15
  19. {gooddata_pipelines-1.49.1.dev1.dist-info → gooddata_pipelines-1.50.0.dist-info}/METADATA +2 -2
  20. {gooddata_pipelines-1.49.1.dev1.dist-info → gooddata_pipelines-1.50.0.dist-info}/RECORD +22 -22
  21. {gooddata_pipelines-1.49.1.dev1.dist-info → gooddata_pipelines-1.50.0.dist-info}/WHEEL +0 -0
  22. {gooddata_pipelines-1.49.1.dev1.dist-info → gooddata_pipelines-1.50.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -24,6 +24,9 @@ class Provisioning(Generic[TFullLoadSourceData, TIncrementalSourceData]):
24
24
  source_group_full: list[TFullLoadSourceData]
25
25
  source_group_incremental: list[TIncrementalSourceData]
26
26
 
27
+ FULL_LOAD_TYPE: type[TFullLoadSourceData]
28
+ INCREMENTAL_LOAD_TYPE: type[TIncrementalSourceData]
29
+
27
30
  def __init__(self, host: str, token: str) -> None:
28
31
  self.source_id: set[str] = set()
29
32
  self.upstream_id: set[str] = set()
@@ -80,6 +83,17 @@ class Provisioning(Generic[TFullLoadSourceData, TIncrementalSourceData]):
80
83
  ids_to_create=ids_to_create,
81
84
  )
82
85
 
86
+ def _validate_source_data_type(
87
+ self,
88
+ source_data: list[TFullLoadSourceData] | list[TIncrementalSourceData],
89
+ model: type[TFullLoadSourceData] | type[TIncrementalSourceData],
90
+ ) -> None:
91
+ """Validates data type of the source data."""
92
+ if not all(isinstance(record, model) for record in source_data):
93
+ raise TypeError(
94
+ f"Not all elements in source data are instances of {model.__name__}"
95
+ )
96
+
83
97
  def _provision_incremental_load(self) -> None:
84
98
  raise NotImplementedError(
85
99
  "Provisioning method to be implemented in the subclass."
@@ -100,11 +114,13 @@ class Provisioning(Generic[TFullLoadSourceData, TIncrementalSourceData]):
100
114
  That means:
101
115
  - All workspaces declared in the source data are created if missing, or
102
116
  updated to match the source data
103
- - All workspaces not declared in the source data are deleted
117
+ - All child workspaces not declared under the parent workspace in the
118
+ source data are deleted
104
119
  """
105
- self.source_group_full = source_data
106
120
 
107
121
  try:
122
+ self._validate_source_data_type(source_data, self.FULL_LOAD_TYPE)
123
+ self.source_group_full = source_data
108
124
  self._provision_full_load()
109
125
  self.logger.info("Provisioning completed.")
110
126
  except Exception as e:
@@ -116,12 +132,14 @@ class Provisioning(Generic[TFullLoadSourceData, TIncrementalSourceData]):
116
132
  """Runs incremental provisioning workflow with the provided source data.
117
133
 
118
134
  Incremental provisioning is used to modify a subset of the upstream workspaces
119
- based on the source data provided.
135
+ based on the source data provided. Only changes requested in the source
136
+ data will be applied.
120
137
  """
121
- # TODO: validate the data type of source group at runtime
122
- self.source_group_incremental = source_data
123
-
124
138
  try:
139
+ self._validate_source_data_type(
140
+ source_data, self.INCREMENTAL_LOAD_TYPE
141
+ )
142
+ self.source_group_incremental = source_data
125
143
  self._provision_incremental_load()
126
144
  self.logger.info("Provisioning completed.")
127
145
  except Exception as e:
@@ -16,10 +16,10 @@ class WorkspaceContext:
16
16
  wdf_id: str | None = None,
17
17
  wdf_values: list[str] | None = None,
18
18
  ):
19
- self.workspace_id: str = workspace_id if workspace_id else "NA"
20
- self.workspace_name: str | None = workspace_name
21
- self.wdf_id: str | None = wdf_id
22
- self.wdf_values: list[str] | None = wdf_values
19
+ self.workspace_id = workspace_id if workspace_id else "NA"
20
+ self.workspace_name = workspace_name
21
+ self.wdf_id = wdf_id
22
+ self.wdf_values = wdf_values
23
23
 
24
24
 
25
25
  class UserContext:
@@ -28,5 +28,5 @@ class UserContext:
28
28
 
29
29
  def __init__(self, user_id: str, user_groups: list[str]):
30
30
  """User context object, stringifies list of user groups"""
31
- self.user_id: str = user_id
32
- self.user_groups: str = ",".join(user_groups)
31
+ self.user_id = user_id
32
+ self.user_groups = ",".join(user_groups)
@@ -2,7 +2,7 @@
2
2
 
3
3
  """Module for utilities used in GoodData Pipelines provisioning."""
4
4
 
5
- from pydantic import BaseModel
5
+ import attrs
6
6
  from requests import Response
7
7
 
8
8
 
@@ -61,20 +61,8 @@ class AttributesMixin:
61
61
  return attrs
62
62
 
63
63
 
64
- class SplitMixin:
65
- @staticmethod
66
- def split(string_value: str, delimiter: str = ",") -> list[str]:
67
- """
68
- Splits a string by the given delimiter and returns a list of stripped values.
69
- If the input is empty, returns an empty list.
70
- """
71
- if not string_value:
72
- return []
73
-
74
- return [value.strip() for value in string_value.split(delimiter)]
75
-
76
-
77
- class EntityGroupIds(BaseModel):
64
+ @attrs.define
65
+ class EntityGroupIds:
78
66
  ids_in_both_systems: set[str]
79
67
  ids_to_delete: set[str]
80
68
  ids_to_create: set[str]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gooddata-pipelines
3
- Version: 1.49.1.dev1
3
+ Version: 1.50.0
4
4
  Summary: GoodData Cloud lifecycle automation pipelines
5
5
  Author-email: GoodData <support@gooddata.com>
6
6
  License: MIT
@@ -8,7 +8,7 @@ License-File: LICENSE.txt
8
8
  Requires-Python: >=3.10
9
9
  Requires-Dist: boto3-stubs<2.0.0,>=1.39.3
10
10
  Requires-Dist: boto3<2.0.0,>=1.39.3
11
- Requires-Dist: gooddata-sdk~=1.49.1.dev1
11
+ Requires-Dist: gooddata-sdk~=1.50.0
12
12
  Requires-Dist: pydantic<3.0.0,>=2.11.3
13
13
  Requires-Dist: requests<3.0.0,>=2.32.3
14
14
  Requires-Dist: types-pyyaml<7.0.0,>=6.0.12.20250326
@@ -1,29 +1,29 @@
1
- gooddata_pipelines/__init__.py,sha256=H1W1_ZuQyoFiM305bALurYv2S3dKc_9I8sFCjcH9XLo,1826
1
+ gooddata_pipelines/__init__.py,sha256=AEKIRuGBPMA_RkL14RF-recw9hS4dGV8cVqgDM3XmrA,1931
2
2
  gooddata_pipelines/_version.py,sha256=Zi8Ht5ofjFeSYGG5USixQtJNB1po6okh0Rez8VyAsFM,200
3
3
  gooddata_pipelines/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  gooddata_pipelines/api/__init__.py,sha256=0WaBI2XMdkkZgnUsQ9kqipNzh2l2zamZvUt_qjp8xCk,106
5
5
  gooddata_pipelines/api/exceptions.py,sha256=rddQXfv8Ktckz7RONKBnKfm53M7dzPCh50Dl1k-8hqs,1545
6
- gooddata_pipelines/api/gooddata_api.py,sha256=QFTwn5o7xMEvXAg85qqr9VhkpA1UDQElfUAUbvMYS8o,10881
6
+ gooddata_pipelines/api/gooddata_api.py,sha256=ALuxTgu3KOK5S2b0C5HpDyvmT_UNfGeF-eqbvxXhDQM,8667
7
7
  gooddata_pipelines/api/gooddata_api_wrapper.py,sha256=t7dFrXJ6X4yXS9XDthOmvd2CyzdnDDNPeIngTEW72YU,1152
8
8
  gooddata_pipelines/api/gooddata_sdk.py,sha256=wd5O4e9BQLWUawt6odrs5a51nqFGthBkvqh9WOiW36Q,13734
9
9
  gooddata_pipelines/api/utils.py,sha256=3QY_aYH17I9THoCINE3l-n5oj52k-gNeT1wv6Z_VxN8,1433
10
10
  gooddata_pipelines/backup_and_restore/__init__.py,sha256=-BG28PGDbalLyZGQjpFG0pjdIvtf25ut0r8ZwZVbi4s,32
11
11
  gooddata_pipelines/backup_and_restore/backup_input_processor.py,sha256=ex1tGwETdHDDBRJ_DGKZsZbH6uoRuOrbGbKOC976H5s,7940
12
- gooddata_pipelines/backup_and_restore/backup_manager.py,sha256=MZJIdaWp3KlhUFv0V0lh495X-LHGUsNSEsrxKfvuHgE,15898
13
- gooddata_pipelines/backup_and_restore/constants.py,sha256=AO4H6ngsLMs4bCV-RcT7xIi-VZu3smgZWA_3P7lVsQc,907
12
+ gooddata_pipelines/backup_and_restore/backup_manager.py,sha256=rfNMn6VLul2OjnLmMyy7AL3qaOVuGapyelORvoTOjGA,16012
13
+ gooddata_pipelines/backup_and_restore/constants.py,sha256=TYw4hU5hhzDVTLJa0gWseaiSs_VboWsYwW7QsqtJ1hA,939
14
14
  gooddata_pipelines/backup_and_restore/csv_reader.py,sha256=0Kw7mJT7REj3Gjqfsc6YT9MbhcqfCGNB_SKBwzTI1rk,1268
15
15
  gooddata_pipelines/backup_and_restore/models/__init__.py,sha256=-BG28PGDbalLyZGQjpFG0pjdIvtf25ut0r8ZwZVbi4s,32
16
16
  gooddata_pipelines/backup_and_restore/models/input_type.py,sha256=CBKJigKdmZ-NJD9MSfNhq89bo86W0AqCMMoyonbd1QA,239
17
- gooddata_pipelines/backup_and_restore/models/storage.py,sha256=DcFH8iWz7LtZZIXoiScZ9ztG6uZHeI9-vLsD07FFnFY,1537
17
+ gooddata_pipelines/backup_and_restore/models/storage.py,sha256=GToCc1M2OlqZJd9NcrIZKsZH_FCD_P_XjdHB4QPtAvo,2791
18
18
  gooddata_pipelines/backup_and_restore/models/workspace_response.py,sha256=eQbYLgRQc17IRG0yPTAJVrD-Xs05SzuwtzoNrPT2DoY,833
19
19
  gooddata_pipelines/backup_and_restore/storage/__init__.py,sha256=-BG28PGDbalLyZGQjpFG0pjdIvtf25ut0r8ZwZVbi4s,32
20
20
  gooddata_pipelines/backup_and_restore/storage/base_storage.py,sha256=67wdItlG3neExeb_eCUDQhswdUB62X5Nyj9sOImB_Hg,487
21
21
  gooddata_pipelines/backup_and_restore/storage/local_storage.py,sha256=NvhPRzRAvuSpc5qCDyPqZaMB0i1jeZOZczaSwjUSGEg,1155
22
- gooddata_pipelines/backup_and_restore/storage/s3_storage.py,sha256=iRtMtDq_C1b_JBL92P9DP4t-BtIdIlmf7hMDE7a02Ps,3284
22
+ gooddata_pipelines/backup_and_restore/storage/s3_storage.py,sha256=ZAysu4sPMAvdWs3RUroHHp2XZLHeU_LhJ5qBHlBQ7n4,3732
23
23
  gooddata_pipelines/logger/__init__.py,sha256=W-fJvMStnsDUY52AYFhx_LnS2cSCFNf3bB47Iew2j04,129
24
24
  gooddata_pipelines/logger/logger.py,sha256=yIMdvqsmOSGQLI4U_tQwxX5E2q_FXUu0Ko7Hv39slFM,3549
25
25
  gooddata_pipelines/provisioning/__init__.py,sha256=RZDEiv8nla4Jwa2TZXUdp1NSxg2_-lLqz4h7k2c4v5Y,854
26
- gooddata_pipelines/provisioning/provisioning.py,sha256=RSxp3bZgdJx3WfbkwQrV1W7dRlyngqfppCtCfVG7BbA,5357
26
+ gooddata_pipelines/provisioning/provisioning.py,sha256=Mibf1-ZwPfHzmoAjgIRuYvtakY7LqerDTF36FgPg990,6175
27
27
  gooddata_pipelines/provisioning/assets/wdf_setting.json,sha256=nxOLGZkEQiMdARcUDER5ygqr3Zu-MQlLlUyXVhPUq64,280
28
28
  gooddata_pipelines/provisioning/entities/__init__.py,sha256=-BG28PGDbalLyZGQjpFG0pjdIvtf25ut0r8ZwZVbi4s,32
29
29
  gooddata_pipelines/provisioning/entities/user_data_filters/__init__.py,sha256=-BG28PGDbalLyZGQjpFG0pjdIvtf25ut0r8ZwZVbi4s,32
@@ -31,24 +31,24 @@ gooddata_pipelines/provisioning/entities/user_data_filters/user_data_filters.py,
31
31
  gooddata_pipelines/provisioning/entities/user_data_filters/models/__init__.py,sha256=-BG28PGDbalLyZGQjpFG0pjdIvtf25ut0r8ZwZVbi4s,32
32
32
  gooddata_pipelines/provisioning/entities/user_data_filters/models/udf_models.py,sha256=y0q5E91AhxIkf_EHW0swCjNUkiiAOFXarAhvjUKVVKw,740
33
33
  gooddata_pipelines/provisioning/entities/users/__init__.py,sha256=-BG28PGDbalLyZGQjpFG0pjdIvtf25ut0r8ZwZVbi4s,32
34
- gooddata_pipelines/provisioning/entities/users/permissions.py,sha256=dZUxzTscIpWPRvANUVocjAfpUSvJ7ImBiABBTIeguyE,6850
35
- gooddata_pipelines/provisioning/entities/users/user_groups.py,sha256=Up36pwwlOFS_IdYetViZ7gUHfV2hIgXL4th_k9D31Eo,8266
36
- gooddata_pipelines/provisioning/entities/users/users.py,sha256=1B1bMk8ysughCoCJs1aX0bI9iUIeAc1hIUyJ0hWyC5M,6503
34
+ gooddata_pipelines/provisioning/entities/users/permissions.py,sha256=2k3oPI7WyABcD2TMmLPsMUDrAjnKM7Vw56kz_RWhcmI,7135
35
+ gooddata_pipelines/provisioning/entities/users/user_groups.py,sha256=-2Nca01ZMjXmnAGDUuKP5G7mqFyn4MnsgZsnS2oy7vg,8511
36
+ gooddata_pipelines/provisioning/entities/users/users.py,sha256=TVfOp3fqQYmzA4K03IBGNYJrqGQAzWH_oay0qsvR8Xo,6633
37
37
  gooddata_pipelines/provisioning/entities/users/models/__init__.py,sha256=-BG28PGDbalLyZGQjpFG0pjdIvtf25ut0r8ZwZVbi4s,32
38
- gooddata_pipelines/provisioning/entities/users/models/permissions.py,sha256=JCyItTqDdyDqB72O5f32IOh1sAiVK-DwFyXyllNU-v4,9279
39
- gooddata_pipelines/provisioning/entities/users/models/user_groups.py,sha256=TjlP6oABK6UP7nMKNMlLk3M62eNf9e-3LdKI9-VFwi8,2007
40
- gooddata_pipelines/provisioning/entities/users/models/users.py,sha256=rKtiRxtelLphw-_BbD-AM_-hPrpp0xqEr1jmuU_oJVg,3767
38
+ gooddata_pipelines/provisioning/entities/users/models/permissions.py,sha256=buyNtDShvAJL4mFZSV-UqK_9JAL_2-AaIlGYCHibhHo,7244
39
+ gooddata_pipelines/provisioning/entities/users/models/user_groups.py,sha256=Odp4yZoK2vC40jgh7FBKmaIINpwffl62uoaT8Xxr-14,1160
40
+ gooddata_pipelines/provisioning/entities/users/models/users.py,sha256=lwb8Q-slBELs_0882KOumkMgKiFKCL3ZABONsoT5Nw0,2234
41
41
  gooddata_pipelines/provisioning/entities/workspaces/__init__.py,sha256=-BG28PGDbalLyZGQjpFG0pjdIvtf25ut0r8ZwZVbi4s,32
42
- gooddata_pipelines/provisioning/entities/workspaces/models.py,sha256=4SR4XLd-qJ4pgpb-diHbm5yqZRmXQ_PgvF4iFfSV740,2155
43
- gooddata_pipelines/provisioning/entities/workspaces/workspace.py,sha256=qlBwzP9nWTucoB9tLMY35na1fIhifvnZoN5D-PJhudY,9770
42
+ gooddata_pipelines/provisioning/entities/workspaces/models.py,sha256=-ehte9HLNos3l6yLip4mZU6wBcmY_Yzwq0t0m0fhwPI,2031
43
+ gooddata_pipelines/provisioning/entities/workspaces/workspace.py,sha256=jngaEKNlMfhjRr4rQ2ECQDoh0gk7KaZTMuTazPLECnM,11505
44
44
  gooddata_pipelines/provisioning/entities/workspaces/workspace_data_filters.py,sha256=0dNcK7tkp40XulCj7EPoB4zVeyQbRx2Tt4yAfgLrm50,10736
45
- gooddata_pipelines/provisioning/entities/workspaces/workspace_data_parser.py,sha256=hjrLZQKdN8vSFjtX9VPiDYUO0RHj06bqzgNzEQqnfR8,4316
45
+ gooddata_pipelines/provisioning/entities/workspaces/workspace_data_parser.py,sha256=akiN8F9x-6xo7KXLJ40iOlmBImEKqWlGYlN3lpF4jQs,4562
46
46
  gooddata_pipelines/provisioning/entities/workspaces/workspace_data_validator.py,sha256=t6RWNsrDpebyOgB4c_ctqrkio72jBHqsXqk-ntBTkA4,7225
47
47
  gooddata_pipelines/provisioning/utils/__init__.py,sha256=-BG28PGDbalLyZGQjpFG0pjdIvtf25ut0r8ZwZVbi4s,32
48
- gooddata_pipelines/provisioning/utils/context_objects.py,sha256=sM22hMsxE0XLI1TU0Vs-2kK0vf4YrB1musoAg__4bjc,936
48
+ gooddata_pipelines/provisioning/utils/context_objects.py,sha256=HJoeumH_gXwM6X-GO3HkC4w-6RYozz6-aqQOhDnu7no,879
49
49
  gooddata_pipelines/provisioning/utils/exceptions.py,sha256=1WnAOlPhqOf0xRcvn70lxAlLb8Oo6m6WCYS4hj9uzDU,3630
50
- gooddata_pipelines/provisioning/utils/utils.py,sha256=_Tk-mFgbIGpCixDCF9e-3ZYd-g5Jb3SJiLSH465k4jY,2846
51
- gooddata_pipelines-1.49.1.dev1.dist-info/METADATA,sha256=_FSW5vT-giekFNSkPNpNZ5X5YEaPHOJql7kejY-50ew,3522
52
- gooddata_pipelines-1.49.1.dev1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
53
- gooddata_pipelines-1.49.1.dev1.dist-info/licenses/LICENSE.txt,sha256=PNC7WXGIo6OKkNoPLRxlVrw6jaLcjSTUsSxy9Xcu9Jo,560365
54
- gooddata_pipelines-1.49.1.dev1.dist-info/RECORD,,
50
+ gooddata_pipelines/provisioning/utils/utils.py,sha256=uF3k5hmoM5d6UoWWfPGCQgT_861zcU-ACyaQHHOOncY,2434
51
+ gooddata_pipelines-1.50.0.dist-info/METADATA,sha256=CeJDooBpPypFs18Un0bz0MjSUYhsFJWGddlkwaOpD98,3512
52
+ gooddata_pipelines-1.50.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
53
+ gooddata_pipelines-1.50.0.dist-info/licenses/LICENSE.txt,sha256=PNC7WXGIo6OKkNoPLRxlVrw6jaLcjSTUsSxy9Xcu9Jo,560365
54
+ gooddata_pipelines-1.50.0.dist-info/RECORD,,