collibra-connector 1.0.10b0__py3-none-any.whl → 1.0.11__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.
- collibra_connector/api/Asset.py +198 -20
- collibra_connector/api/Base.py +2 -1
- collibra_connector/api/Community.py +180 -0
- collibra_connector/api/Domain.py +196 -1
- collibra_connector/api/Metadata.py +2 -2
- collibra_connector/api/OutputModule.py +48 -0
- collibra_connector/api/Relation.py +206 -0
- collibra_connector/api/Responsibility.py +19 -0
- collibra_connector/api/Utils.py +103 -0
- collibra_connector/api/__init__.py +8 -5
- collibra_connector/connector.py +3 -1
- {collibra_connector-1.0.10b0.dist-info → collibra_connector-1.0.11.dist-info}/METADATA +1 -1
- collibra_connector-1.0.11.dist-info/RECORD +21 -0
- collibra_connector-1.0.10b0.dist-info/RECORD +0 -18
- {collibra_connector-1.0.10b0.dist-info → collibra_connector-1.0.11.dist-info}/WHEEL +0 -0
- {collibra_connector-1.0.10b0.dist-info → collibra_connector-1.0.11.dist-info}/licenses/LICENSE +0 -0
- {collibra_connector-1.0.10b0.dist-info → collibra_connector-1.0.11.dist-info}/top_level.txt +0 -0
collibra_connector/api/Asset.py
CHANGED
|
@@ -86,7 +86,7 @@ class Asset(BaseAPI):
|
|
|
86
86
|
response = self._post(url=self.__base_api, data=data)
|
|
87
87
|
return self._handle_response(response)
|
|
88
88
|
|
|
89
|
-
def
|
|
89
|
+
def change_asset(
|
|
90
90
|
self,
|
|
91
91
|
asset_id: str,
|
|
92
92
|
name: str = None,
|
|
@@ -146,16 +146,7 @@ class Asset(BaseAPI):
|
|
|
146
146
|
"typePublicId": type_public_id,
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
|
|
150
|
-
import requests
|
|
151
|
-
response = requests.patch(
|
|
152
|
-
f"{self.__base_api}/{asset_id}",
|
|
153
|
-
auth=self.__connector.auth,
|
|
154
|
-
json=data,
|
|
155
|
-
headers=self.__header,
|
|
156
|
-
timeout=30
|
|
157
|
-
)
|
|
158
|
-
|
|
149
|
+
response = self._patch(url=f"{self.__base_api}/{asset_id}", data=data)
|
|
159
150
|
return self._handle_response(response)
|
|
160
151
|
|
|
161
152
|
def update_asset_attribute(self, asset_id: str, attribute_id: str, value):
|
|
@@ -182,16 +173,203 @@ class Asset(BaseAPI):
|
|
|
182
173
|
"typeId": attribute_id
|
|
183
174
|
}
|
|
184
175
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
176
|
+
response = self._put(url=f"{self.__base_api}/{asset_id}/attributes", data=data)
|
|
177
|
+
return self._handle_response(response)
|
|
178
|
+
|
|
179
|
+
def set_asset_attributes(self, asset_id: str, type_id: str = None, type_public_id: str = None, values: list = None):
|
|
180
|
+
"""
|
|
181
|
+
Set asset attributes. Replaces all attributes of the asset with the given ID
|
|
182
|
+
(of given attribute type) with the attributes from the request.
|
|
183
|
+
:param asset_id: The ID of the asset.
|
|
184
|
+
:param type_id: The ID of the attribute type for the new attribute.
|
|
185
|
+
:param type_public_id: The public ID of the attribute type for the new attribute.
|
|
186
|
+
:param values: The values for the new attribute (list of objects).
|
|
187
|
+
:return: The response from setting the attributes.
|
|
188
|
+
"""
|
|
189
|
+
if not asset_id:
|
|
190
|
+
raise ValueError("asset_id is required")
|
|
191
|
+
if not isinstance(asset_id, str):
|
|
192
|
+
raise ValueError("asset_id must be a string")
|
|
193
|
+
|
|
194
|
+
try:
|
|
195
|
+
uuid.UUID(asset_id)
|
|
196
|
+
except ValueError as exc:
|
|
197
|
+
raise ValueError("asset_id must be a valid UUID") from exc
|
|
198
|
+
|
|
199
|
+
if not values:
|
|
200
|
+
raise ValueError("values is required")
|
|
201
|
+
if not isinstance(values, list):
|
|
202
|
+
raise ValueError("values must be a list")
|
|
203
|
+
|
|
204
|
+
# Validate that either type_id or type_public_id is provided
|
|
205
|
+
if not type_id and not type_public_id:
|
|
206
|
+
raise ValueError("Either type_id or type_public_id must be provided")
|
|
207
|
+
|
|
208
|
+
# Validate type_id if provided
|
|
209
|
+
if type_id:
|
|
210
|
+
if not isinstance(type_id, str):
|
|
211
|
+
raise ValueError("type_id must be a string")
|
|
212
|
+
try:
|
|
213
|
+
uuid.UUID(type_id)
|
|
214
|
+
except ValueError as exc:
|
|
215
|
+
raise ValueError("type_id must be a valid UUID") from exc
|
|
216
|
+
|
|
217
|
+
# Validate type_public_id if provided
|
|
218
|
+
if type_public_id and not isinstance(type_public_id, str):
|
|
219
|
+
raise ValueError("type_public_id must be a string")
|
|
220
|
+
|
|
221
|
+
data = {
|
|
222
|
+
"values": values
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
# Add type_id or type_public_id to the data
|
|
226
|
+
if type_id:
|
|
227
|
+
data["typeId"] = type_id
|
|
228
|
+
if type_public_id:
|
|
229
|
+
data["typePublicId"] = type_public_id
|
|
230
|
+
|
|
231
|
+
response = self._put(url=f"{self.__base_api}/{asset_id}/attributes", data=data)
|
|
232
|
+
return self._handle_response(response)
|
|
233
|
+
|
|
234
|
+
def remove_asset(self, asset_id: str):
|
|
235
|
+
"""
|
|
236
|
+
Remove an asset identified by given ID.
|
|
237
|
+
:param asset_id: The ID of the asset to remove.
|
|
238
|
+
:return: The response from removing the asset.
|
|
239
|
+
"""
|
|
240
|
+
if not asset_id:
|
|
241
|
+
raise ValueError("asset_id is required")
|
|
242
|
+
if not isinstance(asset_id, str):
|
|
243
|
+
raise ValueError("asset_id must be a string")
|
|
244
|
+
|
|
245
|
+
try:
|
|
246
|
+
uuid.UUID(asset_id)
|
|
247
|
+
except ValueError as exc:
|
|
248
|
+
raise ValueError("asset_id must be a valid UUID") from exc
|
|
249
|
+
|
|
250
|
+
response = self._delete(url=f"{self.__base_api}/{asset_id}")
|
|
251
|
+
return self._handle_response(response)
|
|
252
|
+
|
|
253
|
+
def set_asset_relations(self, asset_id: str, related_asset_ids: list, relation_direction: str,
|
|
254
|
+
type_id: str = None, type_public_id: str = None):
|
|
255
|
+
"""
|
|
256
|
+
Set relations for the asset with the given ID. All relations described by this request
|
|
257
|
+
will replace the existing ones (identified with asset as one end, relation type and direction).
|
|
258
|
+
:param asset_id: The ID of the asset.
|
|
259
|
+
:param related_asset_ids: The IDs of the related assets (list of UUIDs).
|
|
260
|
+
:param relation_direction: The relation direction ('TO_TARGET' or 'TO_SOURCE').
|
|
261
|
+
:param type_id: The ID of the relation type for the relations to be set.
|
|
262
|
+
:param type_public_id: The public ID of the relation type for the relations to be set.
|
|
263
|
+
:return: The response from setting the relations.
|
|
264
|
+
"""
|
|
265
|
+
if not asset_id:
|
|
266
|
+
raise ValueError("asset_id is required")
|
|
267
|
+
if not isinstance(asset_id, str):
|
|
268
|
+
raise ValueError("asset_id must be a string")
|
|
269
|
+
|
|
270
|
+
try:
|
|
271
|
+
uuid.UUID(asset_id)
|
|
272
|
+
except ValueError as exc:
|
|
273
|
+
raise ValueError("asset_id must be a valid UUID") from exc
|
|
274
|
+
|
|
275
|
+
if not related_asset_ids:
|
|
276
|
+
raise ValueError("related_asset_ids is required")
|
|
277
|
+
if not isinstance(related_asset_ids, list):
|
|
278
|
+
raise ValueError("related_asset_ids must be a list")
|
|
279
|
+
|
|
280
|
+
# Validate all related asset IDs are valid UUIDs
|
|
281
|
+
for i, related_id in enumerate(related_asset_ids):
|
|
282
|
+
if not isinstance(related_id, str):
|
|
283
|
+
raise ValueError(f"related_asset_ids[{i}] must be a string")
|
|
284
|
+
try:
|
|
285
|
+
uuid.UUID(related_id)
|
|
286
|
+
except ValueError as exc:
|
|
287
|
+
raise ValueError(f"related_asset_ids[{i}] must be a valid UUID") from exc
|
|
288
|
+
|
|
289
|
+
if not relation_direction:
|
|
290
|
+
raise ValueError("relation_direction is required")
|
|
291
|
+
if relation_direction not in ["TO_TARGET", "TO_SOURCE"]:
|
|
292
|
+
raise ValueError("relation_direction must be either 'TO_TARGET' or 'TO_SOURCE'")
|
|
293
|
+
|
|
294
|
+
# Validate that either type_id or type_public_id is provided
|
|
295
|
+
if not type_id and not type_public_id:
|
|
296
|
+
raise ValueError("Either type_id or type_public_id must be provided")
|
|
297
|
+
|
|
298
|
+
# Validate type_id if provided
|
|
299
|
+
if type_id:
|
|
300
|
+
if not isinstance(type_id, str):
|
|
301
|
+
raise ValueError("type_id must be a string")
|
|
302
|
+
try:
|
|
303
|
+
uuid.UUID(type_id)
|
|
304
|
+
except ValueError as exc:
|
|
305
|
+
raise ValueError("type_id must be a valid UUID") from exc
|
|
306
|
+
|
|
307
|
+
# Validate type_public_id if provided
|
|
308
|
+
if type_public_id and not isinstance(type_public_id, str):
|
|
309
|
+
raise ValueError("type_public_id must be a string")
|
|
310
|
+
|
|
311
|
+
data = {
|
|
312
|
+
"relatedAssetIds": related_asset_ids,
|
|
313
|
+
"relationDirection": relation_direction
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
# Add type_id or type_public_id to the data
|
|
317
|
+
if type_id:
|
|
318
|
+
data["typeId"] = type_id
|
|
319
|
+
if type_public_id:
|
|
320
|
+
data["typePublicId"] = type_public_id
|
|
321
|
+
|
|
322
|
+
response = self._put(url=f"{self.__base_api}/{asset_id}/relations", data=data)
|
|
323
|
+
return self._handle_response(response)
|
|
324
|
+
|
|
325
|
+
def set_asset_responsibilities(self, asset_id: str, role_id: str, owner_ids: list):
|
|
326
|
+
"""
|
|
327
|
+
Set responsibilities for the asset with the given ID.
|
|
328
|
+
:param asset_id: The ID of the asset.
|
|
329
|
+
:param role_id: The ID of the role for the responsibilities to be set.
|
|
330
|
+
:param owner_ids: The IDs of the owners (list of UUIDs). An owner is either user or group.
|
|
331
|
+
:return: The response from setting the responsibilities.
|
|
332
|
+
"""
|
|
333
|
+
if not asset_id:
|
|
334
|
+
raise ValueError("asset_id is required")
|
|
335
|
+
if not isinstance(asset_id, str):
|
|
336
|
+
raise ValueError("asset_id must be a string")
|
|
337
|
+
|
|
338
|
+
try:
|
|
339
|
+
uuid.UUID(asset_id)
|
|
340
|
+
except ValueError as exc:
|
|
341
|
+
raise ValueError("asset_id must be a valid UUID") from exc
|
|
342
|
+
|
|
343
|
+
if not role_id:
|
|
344
|
+
raise ValueError("role_id is required")
|
|
345
|
+
if not isinstance(role_id, str):
|
|
346
|
+
raise ValueError("role_id must be a string")
|
|
347
|
+
|
|
348
|
+
try:
|
|
349
|
+
uuid.UUID(role_id)
|
|
350
|
+
except ValueError as exc:
|
|
351
|
+
raise ValueError("role_id must be a valid UUID") from exc
|
|
352
|
+
|
|
353
|
+
if not owner_ids:
|
|
354
|
+
raise ValueError("owner_ids is required")
|
|
355
|
+
if not isinstance(owner_ids, list):
|
|
356
|
+
raise ValueError("owner_ids must be a list")
|
|
357
|
+
|
|
358
|
+
# Validate all owner IDs are valid UUIDs
|
|
359
|
+
for i, owner_id in enumerate(owner_ids):
|
|
360
|
+
if not isinstance(owner_id, str):
|
|
361
|
+
raise ValueError(f"owner_ids[{i}] must be a string")
|
|
362
|
+
try:
|
|
363
|
+
uuid.UUID(owner_id)
|
|
364
|
+
except ValueError as exc:
|
|
365
|
+
raise ValueError(f"owner_ids[{i}] must be a valid UUID") from exc
|
|
366
|
+
|
|
367
|
+
data = {
|
|
368
|
+
"roleId": role_id,
|
|
369
|
+
"ownerIds": owner_ids
|
|
370
|
+
}
|
|
194
371
|
|
|
372
|
+
response = self._put(url=f"{self.__base_api}/{asset_id}/responsibilities", data=data)
|
|
195
373
|
return self._handle_response(response)
|
|
196
374
|
|
|
197
375
|
def find_assets(
|
collibra_connector/api/Base.py
CHANGED
|
@@ -38,7 +38,7 @@ class BaseAPI:
|
|
|
38
38
|
timeout=self.__connector.timeout
|
|
39
39
|
)
|
|
40
40
|
|
|
41
|
-
def _post(self, url: str, data: dict, headers: dict = None):
|
|
41
|
+
def _post(self, url: str, data: dict, headers: dict = None, params: dict = None):
|
|
42
42
|
"""
|
|
43
43
|
Makes a POST request to the specified URL with the given data.
|
|
44
44
|
:param url: The URL to send the POST request to.
|
|
@@ -56,6 +56,7 @@ class BaseAPI:
|
|
|
56
56
|
auth=self.__connector.auth,
|
|
57
57
|
json=data,
|
|
58
58
|
headers=headers,
|
|
59
|
+
params=params,
|
|
59
60
|
timeout=self.__connector.timeout
|
|
60
61
|
)
|
|
61
62
|
|
|
@@ -110,3 +110,183 @@ class Community(BaseAPI):
|
|
|
110
110
|
|
|
111
111
|
response = self._get(params=params)
|
|
112
112
|
return self._handle_response(response)
|
|
113
|
+
|
|
114
|
+
def add_community(
|
|
115
|
+
self,
|
|
116
|
+
name: str,
|
|
117
|
+
parent_id: str = None,
|
|
118
|
+
description: str = None,
|
|
119
|
+
community_id: str = None
|
|
120
|
+
):
|
|
121
|
+
"""
|
|
122
|
+
Adds a new community with the given parameters.
|
|
123
|
+
:param name: The name of the new community. Should be unique across all communities
|
|
124
|
+
(required, 1-255 characters).
|
|
125
|
+
:param parent_id: The ID of the parent for the new community (optional UUID).
|
|
126
|
+
:param description: The description of the new community (optional).
|
|
127
|
+
:param community_id: The ID of the new community. Should be unique within all communities
|
|
128
|
+
(optional UUID).
|
|
129
|
+
:return: Details of the created community.
|
|
130
|
+
"""
|
|
131
|
+
# Validate required parameters
|
|
132
|
+
if not name:
|
|
133
|
+
raise ValueError("name is required")
|
|
134
|
+
if not isinstance(name, str):
|
|
135
|
+
raise ValueError("name must be a string")
|
|
136
|
+
if len(name.strip()) < 1 or len(name) > 255:
|
|
137
|
+
raise ValueError("name must be between 1 and 255 characters")
|
|
138
|
+
|
|
139
|
+
# Validate parent_id if provided
|
|
140
|
+
if parent_id is not None:
|
|
141
|
+
if not isinstance(parent_id, str):
|
|
142
|
+
raise ValueError("parent_id must be a string")
|
|
143
|
+
try:
|
|
144
|
+
uuid.UUID(parent_id)
|
|
145
|
+
except ValueError as exc:
|
|
146
|
+
raise ValueError("parent_id must be a valid UUID") from exc
|
|
147
|
+
|
|
148
|
+
# Validate description if provided
|
|
149
|
+
if description is not None and not isinstance(description, str):
|
|
150
|
+
raise ValueError("description must be a string")
|
|
151
|
+
|
|
152
|
+
# Validate community_id if provided
|
|
153
|
+
if community_id is not None:
|
|
154
|
+
if not isinstance(community_id, str):
|
|
155
|
+
raise ValueError("community_id must be a string")
|
|
156
|
+
try:
|
|
157
|
+
parsed_uuid = uuid.UUID(community_id)
|
|
158
|
+
# Check if UUID starts with reserved prefix
|
|
159
|
+
if str(parsed_uuid).startswith("00000000-0000-0000-"):
|
|
160
|
+
raise ValueError("community_id cannot start with reserved prefix '00000000-0000-0000-'")
|
|
161
|
+
except ValueError as exc:
|
|
162
|
+
if "reserved prefix" in str(exc):
|
|
163
|
+
raise exc
|
|
164
|
+
raise ValueError("community_id must be a valid UUID") from exc
|
|
165
|
+
|
|
166
|
+
# Build request body - only include provided values
|
|
167
|
+
data = {"name": name.strip()}
|
|
168
|
+
|
|
169
|
+
if parent_id is not None:
|
|
170
|
+
data["parentId"] = parent_id
|
|
171
|
+
if description is not None:
|
|
172
|
+
data["description"] = description
|
|
173
|
+
if community_id is not None:
|
|
174
|
+
data["id"] = community_id
|
|
175
|
+
|
|
176
|
+
response = self._post(url=self.__base_api, data=data)
|
|
177
|
+
return self._handle_response(response)
|
|
178
|
+
|
|
179
|
+
def change_community(
|
|
180
|
+
self,
|
|
181
|
+
community_id: str,
|
|
182
|
+
name: str = None,
|
|
183
|
+
parent_id: str = None,
|
|
184
|
+
description: str = None,
|
|
185
|
+
remove_scope_overlap_on_move: bool = None
|
|
186
|
+
):
|
|
187
|
+
"""
|
|
188
|
+
Changes the community with the information that is present in the request.
|
|
189
|
+
Only properties that are specified in this request and have non-null values are updated.
|
|
190
|
+
:param community_id: The ID of the community to be changed (required UUID).
|
|
191
|
+
:param name: The new name for the community (optional, 1-255 characters).
|
|
192
|
+
:param parent_id: The ID of the new parent community (optional UUID).
|
|
193
|
+
:param description: The new description for the community (optional).
|
|
194
|
+
:param remove_scope_overlap_on_move: Whether scopes assigned to domain community
|
|
195
|
+
and its children should be removed on move if there
|
|
196
|
+
are any inherited scopes in new parent community.
|
|
197
|
+
:return: Details of the updated community.
|
|
198
|
+
"""
|
|
199
|
+
# Validate required parameters
|
|
200
|
+
if not community_id:
|
|
201
|
+
raise ValueError("community_id is required")
|
|
202
|
+
if not isinstance(community_id, str):
|
|
203
|
+
raise ValueError("community_id must be a string")
|
|
204
|
+
|
|
205
|
+
try:
|
|
206
|
+
uuid.UUID(community_id)
|
|
207
|
+
except ValueError as exc:
|
|
208
|
+
raise ValueError("community_id must be a valid UUID") from exc
|
|
209
|
+
|
|
210
|
+
# Validate name if provided
|
|
211
|
+
if name is not None:
|
|
212
|
+
if not isinstance(name, str):
|
|
213
|
+
raise ValueError("name must be a string")
|
|
214
|
+
if len(name.strip()) < 1 or len(name) > 255:
|
|
215
|
+
raise ValueError("name must be between 1 and 255 characters")
|
|
216
|
+
|
|
217
|
+
# Validate parent_id if provided
|
|
218
|
+
if parent_id is not None:
|
|
219
|
+
if not isinstance(parent_id, str):
|
|
220
|
+
raise ValueError("parent_id must be a string")
|
|
221
|
+
try:
|
|
222
|
+
uuid.UUID(parent_id)
|
|
223
|
+
except ValueError as exc:
|
|
224
|
+
raise ValueError("parent_id must be a valid UUID") from exc
|
|
225
|
+
|
|
226
|
+
# Validate description if provided
|
|
227
|
+
if description is not None and not isinstance(description, str):
|
|
228
|
+
raise ValueError("description must be a string")
|
|
229
|
+
|
|
230
|
+
# Validate remove_scope_overlap_on_move if provided
|
|
231
|
+
if remove_scope_overlap_on_move is not None and not isinstance(remove_scope_overlap_on_move, bool):
|
|
232
|
+
raise ValueError("remove_scope_overlap_on_move must be a boolean")
|
|
233
|
+
|
|
234
|
+
# Build request body - only include provided values
|
|
235
|
+
# Include the community_id in the body as required by the API
|
|
236
|
+
data = {"id": community_id}
|
|
237
|
+
|
|
238
|
+
if name is not None:
|
|
239
|
+
data["name"] = name.strip()
|
|
240
|
+
if parent_id is not None:
|
|
241
|
+
data["parentId"] = parent_id
|
|
242
|
+
if description is not None:
|
|
243
|
+
data["description"] = description
|
|
244
|
+
if remove_scope_overlap_on_move is not None:
|
|
245
|
+
data["removeScopeOverlapOnMove"] = remove_scope_overlap_on_move
|
|
246
|
+
|
|
247
|
+
response = self._patch(url=f"{self.__base_api}/{community_id}", data=data)
|
|
248
|
+
return self._handle_response(response)
|
|
249
|
+
|
|
250
|
+
def remove_community(self, community_id: str):
|
|
251
|
+
"""
|
|
252
|
+
Remove a community by its ID.
|
|
253
|
+
|
|
254
|
+
**DEPRECATED**: This endpoint will be removed in the future.
|
|
255
|
+
Please use POST /communities/removalJobs instead.
|
|
256
|
+
|
|
257
|
+
:param community_id: The ID of the community to remove (required UUID).
|
|
258
|
+
:return: Response from the removal operation.
|
|
259
|
+
"""
|
|
260
|
+
# Validate required parameters
|
|
261
|
+
if not community_id:
|
|
262
|
+
raise ValueError("community_id is required")
|
|
263
|
+
if not isinstance(community_id, str):
|
|
264
|
+
raise ValueError("community_id must be a string")
|
|
265
|
+
|
|
266
|
+
try:
|
|
267
|
+
uuid.UUID(community_id)
|
|
268
|
+
except ValueError as exc:
|
|
269
|
+
raise ValueError("community_id must be a valid UUID") from exc
|
|
270
|
+
|
|
271
|
+
response = self._delete(url=f"{self.__base_api}/{community_id}")
|
|
272
|
+
return self._handle_response(response)
|
|
273
|
+
|
|
274
|
+
def change_to_root_community(self, community_id: str):
|
|
275
|
+
"""
|
|
276
|
+
Changes the community with given ID to a root community.
|
|
277
|
+
:param community_id: The ID of the community that will be changed to a root community (required UUID).
|
|
278
|
+
:return: Details of the updated community.
|
|
279
|
+
"""
|
|
280
|
+
# Validate required parameters
|
|
281
|
+
if not community_id:
|
|
282
|
+
raise ValueError("community_id is required")
|
|
283
|
+
if not isinstance(community_id, str):
|
|
284
|
+
raise ValueError("community_id must be a string")
|
|
285
|
+
|
|
286
|
+
try:
|
|
287
|
+
uuid.UUID(community_id)
|
|
288
|
+
except ValueError as exc:
|
|
289
|
+
raise ValueError("community_id must be a valid UUID") from exc
|
|
290
|
+
|
|
291
|
+
response = self._post(url=f"{self.__base_api}/{community_id}/root", data={})
|
|
292
|
+
return self._handle_response(response)
|
collibra_connector/api/Domain.py
CHANGED
|
@@ -112,5 +112,200 @@ class Domain(BaseAPI):
|
|
|
112
112
|
if type_public_id is not None:
|
|
113
113
|
params["typePublicId"] = type_public_id
|
|
114
114
|
|
|
115
|
-
response = self._get(params=params)
|
|
115
|
+
response = self._get(url=self.__base_api, params=params)
|
|
116
|
+
return self._handle_response(response)
|
|
117
|
+
|
|
118
|
+
def add_domain(
|
|
119
|
+
self,
|
|
120
|
+
name: str,
|
|
121
|
+
community_id: str,
|
|
122
|
+
type_id: str = None,
|
|
123
|
+
description: str = None,
|
|
124
|
+
domain_id: str = None,
|
|
125
|
+
excluded_from_auto_hyperlinking: bool = None,
|
|
126
|
+
type_public_id: str = None
|
|
127
|
+
):
|
|
128
|
+
"""
|
|
129
|
+
Adds a new domain with given data into a community.
|
|
130
|
+
:param name: The name of the new domain. Should be unique within the community
|
|
131
|
+
(required, 1-255 characters).
|
|
132
|
+
:param community_id: The ID of the community that the new domain should be added to (required UUID).
|
|
133
|
+
:param type_id: The ID of the domain type of the new domain (optional UUID).
|
|
134
|
+
:param description: The description of the new domain (optional).
|
|
135
|
+
:param domain_id: The ID of the new domain. Should be unique within all domains (optional UUID).
|
|
136
|
+
:param excluded_from_auto_hyperlinking: Whether to exclude from auto hyperlinking (optional boolean).
|
|
137
|
+
:param type_public_id: The public ID of the domain type of the new domain (optional).
|
|
138
|
+
:return: Details of the created domain.
|
|
139
|
+
"""
|
|
140
|
+
# Validate required parameters
|
|
141
|
+
if not name:
|
|
142
|
+
raise ValueError("name is required")
|
|
143
|
+
if not isinstance(name, str):
|
|
144
|
+
raise ValueError("name must be a string")
|
|
145
|
+
if len(name.strip()) < 1 or len(name) > 255:
|
|
146
|
+
raise ValueError("name must be between 1 and 255 characters")
|
|
147
|
+
|
|
148
|
+
if not community_id:
|
|
149
|
+
raise ValueError("community_id is required")
|
|
150
|
+
if not isinstance(community_id, str):
|
|
151
|
+
raise ValueError("community_id must be a string")
|
|
152
|
+
try:
|
|
153
|
+
uuid.UUID(community_id)
|
|
154
|
+
except ValueError as exc:
|
|
155
|
+
raise ValueError("community_id must be a valid UUID") from exc
|
|
156
|
+
|
|
157
|
+
# Validate type_id if provided
|
|
158
|
+
if type_id is not None:
|
|
159
|
+
if not isinstance(type_id, str):
|
|
160
|
+
raise ValueError("type_id must be a string")
|
|
161
|
+
try:
|
|
162
|
+
uuid.UUID(type_id)
|
|
163
|
+
except ValueError as exc:
|
|
164
|
+
raise ValueError("type_id must be a valid UUID") from exc
|
|
165
|
+
|
|
166
|
+
# Validate description if provided
|
|
167
|
+
if description is not None and not isinstance(description, str):
|
|
168
|
+
raise ValueError("description must be a string")
|
|
169
|
+
|
|
170
|
+
# Validate domain_id if provided
|
|
171
|
+
if domain_id is not None:
|
|
172
|
+
if not isinstance(domain_id, str):
|
|
173
|
+
raise ValueError("domain_id must be a string")
|
|
174
|
+
try:
|
|
175
|
+
parsed_uuid = uuid.UUID(domain_id)
|
|
176
|
+
# Check if UUID starts with reserved prefix
|
|
177
|
+
if str(parsed_uuid).startswith("00000000-0000-0000-"):
|
|
178
|
+
raise ValueError("domain_id cannot start with reserved prefix '00000000-0000-0000-'")
|
|
179
|
+
except ValueError as exc:
|
|
180
|
+
if "reserved prefix" in str(exc):
|
|
181
|
+
raise exc
|
|
182
|
+
raise ValueError("domain_id must be a valid UUID") from exc
|
|
183
|
+
|
|
184
|
+
# Validate excluded_from_auto_hyperlinking if provided
|
|
185
|
+
if excluded_from_auto_hyperlinking is not None and not isinstance(excluded_from_auto_hyperlinking, bool):
|
|
186
|
+
raise ValueError("excluded_from_auto_hyperlinking must be a boolean")
|
|
187
|
+
|
|
188
|
+
# Validate type_public_id if provided
|
|
189
|
+
if type_public_id is not None and not isinstance(type_public_id, str):
|
|
190
|
+
raise ValueError("type_public_id must be a string")
|
|
191
|
+
|
|
192
|
+
# Build request body - only include provided values
|
|
193
|
+
data = {
|
|
194
|
+
"name": name.strip(),
|
|
195
|
+
"communityId": community_id
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if type_id is not None:
|
|
199
|
+
data["typeId"] = type_id
|
|
200
|
+
if description is not None:
|
|
201
|
+
data["description"] = description
|
|
202
|
+
if domain_id is not None:
|
|
203
|
+
data["id"] = domain_id
|
|
204
|
+
if excluded_from_auto_hyperlinking is not None:
|
|
205
|
+
data["excludedFromAutoHyperlinking"] = excluded_from_auto_hyperlinking
|
|
206
|
+
if type_public_id is not None:
|
|
207
|
+
data["typePublicId"] = type_public_id
|
|
208
|
+
|
|
209
|
+
response = self._post(url=self.__base_api, data=data)
|
|
210
|
+
return self._handle_response(response)
|
|
211
|
+
|
|
212
|
+
def remove_domain(self, domain_id: str):
|
|
213
|
+
"""
|
|
214
|
+
Remove a domain by its ID.
|
|
215
|
+
|
|
216
|
+
**DEPRECATED**: This endpoint will be removed in the future.
|
|
217
|
+
Please use POST /domains/removalJobs instead.
|
|
218
|
+
|
|
219
|
+
:param domain_id: The ID of the domain to remove (required UUID).
|
|
220
|
+
:return: Response from the removal operation.
|
|
221
|
+
"""
|
|
222
|
+
# Validate required parameters
|
|
223
|
+
if not domain_id:
|
|
224
|
+
raise ValueError("domain_id is required")
|
|
225
|
+
if not isinstance(domain_id, str):
|
|
226
|
+
raise ValueError("domain_id must be a string")
|
|
227
|
+
|
|
228
|
+
try:
|
|
229
|
+
uuid.UUID(domain_id)
|
|
230
|
+
except ValueError as exc:
|
|
231
|
+
raise ValueError("domain_id must be a valid UUID") from exc
|
|
232
|
+
|
|
233
|
+
response = self._delete(url=f"{self.__base_api}/{domain_id}")
|
|
234
|
+
return self._handle_response(response)
|
|
235
|
+
|
|
236
|
+
def change_domain(
|
|
237
|
+
self,
|
|
238
|
+
domain_id: str,
|
|
239
|
+
name: str = None,
|
|
240
|
+
description: str = None,
|
|
241
|
+
type_id: str = None,
|
|
242
|
+
type_public_id: str = None,
|
|
243
|
+
excluded_from_auto_hyperlinking: bool = None
|
|
244
|
+
):
|
|
245
|
+
"""
|
|
246
|
+
Changes the domain with the information that is present in the request.
|
|
247
|
+
Only properties that are specified in this request and have non-null values are updated.
|
|
248
|
+
:param domain_id: The ID of the domain to be changed (required UUID).
|
|
249
|
+
:param name: The new name for the domain (optional, 1-255 characters).
|
|
250
|
+
:param description: The new description for the domain (optional).
|
|
251
|
+
:param type_id: The ID of the domain type (optional UUID).
|
|
252
|
+
:param type_public_id: The public ID of the domain type (optional).
|
|
253
|
+
:param excluded_from_auto_hyperlinking: Whether to exclude from auto hyperlinking (optional boolean).
|
|
254
|
+
:return: Details of the updated domain.
|
|
255
|
+
"""
|
|
256
|
+
# Validate required parameters
|
|
257
|
+
if not domain_id:
|
|
258
|
+
raise ValueError("domain_id is required")
|
|
259
|
+
if not isinstance(domain_id, str):
|
|
260
|
+
raise ValueError("domain_id must be a string")
|
|
261
|
+
|
|
262
|
+
try:
|
|
263
|
+
uuid.UUID(domain_id)
|
|
264
|
+
except ValueError as exc:
|
|
265
|
+
raise ValueError("domain_id must be a valid UUID") from exc
|
|
266
|
+
|
|
267
|
+
# Validate name if provided
|
|
268
|
+
if name is not None:
|
|
269
|
+
if not isinstance(name, str):
|
|
270
|
+
raise ValueError("name must be a string")
|
|
271
|
+
if len(name.strip()) < 1 or len(name) > 255:
|
|
272
|
+
raise ValueError("name must be between 1 and 255 characters")
|
|
273
|
+
|
|
274
|
+
# Validate description if provided
|
|
275
|
+
if description is not None and not isinstance(description, str):
|
|
276
|
+
raise ValueError("description must be a string")
|
|
277
|
+
|
|
278
|
+
# Validate type_id if provided
|
|
279
|
+
if type_id is not None:
|
|
280
|
+
if not isinstance(type_id, str):
|
|
281
|
+
raise ValueError("type_id must be a string")
|
|
282
|
+
try:
|
|
283
|
+
uuid.UUID(type_id)
|
|
284
|
+
except ValueError as exc:
|
|
285
|
+
raise ValueError("type_id must be a valid UUID") from exc
|
|
286
|
+
|
|
287
|
+
# Validate type_public_id if provided
|
|
288
|
+
if type_public_id is not None and not isinstance(type_public_id, str):
|
|
289
|
+
raise ValueError("type_public_id must be a string")
|
|
290
|
+
|
|
291
|
+
# Validate excluded_from_auto_hyperlinking if provided
|
|
292
|
+
if excluded_from_auto_hyperlinking is not None and not isinstance(excluded_from_auto_hyperlinking, bool):
|
|
293
|
+
raise ValueError("excluded_from_auto_hyperlinking must be a boolean")
|
|
294
|
+
|
|
295
|
+
# Build request body - only include provided values
|
|
296
|
+
# Include the domain_id in the body as required by the API
|
|
297
|
+
data = {"id": domain_id}
|
|
298
|
+
|
|
299
|
+
if name is not None:
|
|
300
|
+
data["name"] = name.strip()
|
|
301
|
+
if description is not None:
|
|
302
|
+
data["description"] = description
|
|
303
|
+
if type_id is not None:
|
|
304
|
+
data["typeId"] = type_id
|
|
305
|
+
if type_public_id is not None:
|
|
306
|
+
data["typePublicId"] = type_public_id
|
|
307
|
+
if excluded_from_auto_hyperlinking is not None:
|
|
308
|
+
data["excludedFromAutoHyperlinking"] = excluded_from_auto_hyperlinking
|
|
309
|
+
|
|
310
|
+
response = self._patch(url=f"{self.__base_api}/{domain_id}", data=data)
|
|
116
311
|
return self._handle_response(response)
|
|
@@ -72,8 +72,8 @@ class Metadata(BaseAPI):
|
|
|
72
72
|
for domain in domains_data.get("results", []):
|
|
73
73
|
metadata["Domain"][domain["name"]] = domain["id"]
|
|
74
74
|
if (
|
|
75
|
-
domains_data.get("offset", 0) + domains_data.get("limit", 0)
|
|
76
|
-
domains_data.get("total", 0)
|
|
75
|
+
domains_data.get("offset", 0) + domains_data.get("limit", 0)
|
|
76
|
+
>= domains_data.get("total", 0)
|
|
77
77
|
):
|
|
78
78
|
break
|
|
79
79
|
domains_params["offset"] += domains_params["limit"]
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from typing import Optional, Dict, Any
|
|
3
|
+
from .Base import BaseAPI
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class OutputModule(BaseAPI):
|
|
7
|
+
"""
|
|
8
|
+
Output Module API endpoints for Collibra DGC.
|
|
9
|
+
"""
|
|
10
|
+
def __init__(self, connector):
|
|
11
|
+
super().__init__(connector)
|
|
12
|
+
self.__base_api = connector.api + "/outputModule"
|
|
13
|
+
|
|
14
|
+
def export_json(
|
|
15
|
+
self,
|
|
16
|
+
body: str,
|
|
17
|
+
validation_enabled: bool = False
|
|
18
|
+
) -> Dict[Any, Any]:
|
|
19
|
+
"""
|
|
20
|
+
Exports results in JSON format, returns the results immediately.
|
|
21
|
+
|
|
22
|
+
Performs an Output Module query and exports the returns results immediately in JSON format.
|
|
23
|
+
|
|
24
|
+
Please note that the ViewConfig/TableViewConfig's syntax validation is not executed by default.
|
|
25
|
+
DGC admin console settings may impact the execution of the query (especially in terms of timeout
|
|
26
|
+
and a limit on the number of results).
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
view_config (str): The JSON/YAML representation of ViewConfig/TableViewConfig
|
|
30
|
+
that describes the query to be performed.
|
|
31
|
+
validation_enabled (bool): Determines if the ViewConfig's syntax should be validated
|
|
32
|
+
(True) or not (False). Default value is False for backward
|
|
33
|
+
compatibility reasons but it is strongly advised to always
|
|
34
|
+
enable this validation.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Dict[Any, Any]: The exported results in JSON format.
|
|
38
|
+
|
|
39
|
+
Raises:
|
|
40
|
+
requests.exceptions.RequestException: If the API request fails.
|
|
41
|
+
"""
|
|
42
|
+
endpoint = f"{self.__base_api}/export/json"
|
|
43
|
+
|
|
44
|
+
headers = {
|
|
45
|
+
'Content-Type': 'application/json'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return self._post(url=endpoint, data=body, headers=headers).json()
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from .Base import BaseAPI
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Relation(BaseAPI):
|
|
6
|
+
def __init__(self, connector):
|
|
7
|
+
super().__init__(connector)
|
|
8
|
+
self.__base_api = connector.api + "/relations"
|
|
9
|
+
|
|
10
|
+
def add_relation(
|
|
11
|
+
self,
|
|
12
|
+
source_id: str,
|
|
13
|
+
target_id: str,
|
|
14
|
+
type_id: str = None,
|
|
15
|
+
starting_date: int = None,
|
|
16
|
+
ending_date: int = None,
|
|
17
|
+
type_public_id: str = None
|
|
18
|
+
):
|
|
19
|
+
"""
|
|
20
|
+
Adds a new relation.
|
|
21
|
+
:param source_id: The ID of the source of the relation (required UUID).
|
|
22
|
+
:param target_id: The ID of the target of the relation (required UUID).
|
|
23
|
+
:param type_id: The ID of the type of the relation (optional UUID).
|
|
24
|
+
:param starting_date: The starting date of the relation (deprecated, int64).
|
|
25
|
+
:param ending_date: The ending date of the relation (deprecated, int64).
|
|
26
|
+
:param type_public_id: The public ID of the type of the relation (optional).
|
|
27
|
+
:return: Details of the created relation.
|
|
28
|
+
"""
|
|
29
|
+
# Validate required parameters
|
|
30
|
+
if not source_id:
|
|
31
|
+
raise ValueError("source_id is required")
|
|
32
|
+
if not isinstance(source_id, str):
|
|
33
|
+
raise ValueError("source_id must be a string")
|
|
34
|
+
try:
|
|
35
|
+
uuid.UUID(source_id)
|
|
36
|
+
except ValueError as exc:
|
|
37
|
+
raise ValueError("source_id must be a valid UUID") from exc
|
|
38
|
+
|
|
39
|
+
if not target_id:
|
|
40
|
+
raise ValueError("target_id is required")
|
|
41
|
+
if not isinstance(target_id, str):
|
|
42
|
+
raise ValueError("target_id must be a string")
|
|
43
|
+
try:
|
|
44
|
+
uuid.UUID(target_id)
|
|
45
|
+
except ValueError as exc:
|
|
46
|
+
raise ValueError("target_id must be a valid UUID") from exc
|
|
47
|
+
|
|
48
|
+
# Validate type_id if provided
|
|
49
|
+
if type_id is not None:
|
|
50
|
+
if not isinstance(type_id, str):
|
|
51
|
+
raise ValueError("type_id must be a string")
|
|
52
|
+
try:
|
|
53
|
+
uuid.UUID(type_id)
|
|
54
|
+
except ValueError as exc:
|
|
55
|
+
raise ValueError("type_id must be a valid UUID") from exc
|
|
56
|
+
|
|
57
|
+
# Validate starting_date if provided
|
|
58
|
+
if starting_date is not None:
|
|
59
|
+
if not isinstance(starting_date, int):
|
|
60
|
+
raise ValueError("starting_date must be an integer")
|
|
61
|
+
if starting_date < 0:
|
|
62
|
+
raise ValueError("starting_date must be a positive integer")
|
|
63
|
+
|
|
64
|
+
# Validate ending_date if provided
|
|
65
|
+
if ending_date is not None:
|
|
66
|
+
if not isinstance(ending_date, int):
|
|
67
|
+
raise ValueError("ending_date must be an integer")
|
|
68
|
+
if ending_date < 0:
|
|
69
|
+
raise ValueError("ending_date must be a positive integer")
|
|
70
|
+
|
|
71
|
+
# Validate type_public_id if provided
|
|
72
|
+
if type_public_id is not None and not isinstance(type_public_id, str):
|
|
73
|
+
raise ValueError("type_public_id must be a string")
|
|
74
|
+
|
|
75
|
+
# Build request data - only include provided values
|
|
76
|
+
data = {
|
|
77
|
+
"sourceId": source_id,
|
|
78
|
+
"targetId": target_id
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if type_id is not None:
|
|
82
|
+
data["typeId"] = type_id
|
|
83
|
+
if starting_date is not None:
|
|
84
|
+
data["startingDate"] = starting_date
|
|
85
|
+
if ending_date is not None:
|
|
86
|
+
data["endingDate"] = ending_date
|
|
87
|
+
if type_public_id is not None:
|
|
88
|
+
data["typePublicId"] = type_public_id
|
|
89
|
+
|
|
90
|
+
response = self._post(url=self.__base_api, data=data)
|
|
91
|
+
return self._handle_response(response)
|
|
92
|
+
|
|
93
|
+
def get_relation(self, relation_id: str):
|
|
94
|
+
"""
|
|
95
|
+
Returns a relation identified by given id.
|
|
96
|
+
:param relation_id: The ID of the relation (required UUID).
|
|
97
|
+
:return: Relation details.
|
|
98
|
+
"""
|
|
99
|
+
if not relation_id:
|
|
100
|
+
raise ValueError("relation_id is required")
|
|
101
|
+
if not isinstance(relation_id, str):
|
|
102
|
+
raise ValueError("relation_id must be a string")
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
uuid.UUID(relation_id)
|
|
106
|
+
except ValueError as exc:
|
|
107
|
+
raise ValueError("relation_id must be a valid UUID") from exc
|
|
108
|
+
|
|
109
|
+
response = self._get(url=f"{self.__base_api}/{relation_id}")
|
|
110
|
+
return self._handle_response(response)
|
|
111
|
+
|
|
112
|
+
def remove_relation(self, relation_id: str):
|
|
113
|
+
"""
|
|
114
|
+
Removes a relation identified by given id.
|
|
115
|
+
:param relation_id: The ID of the relation to remove (required UUID).
|
|
116
|
+
:return: Response from the removal operation.
|
|
117
|
+
"""
|
|
118
|
+
if not relation_id:
|
|
119
|
+
raise ValueError("relation_id is required")
|
|
120
|
+
if not isinstance(relation_id, str):
|
|
121
|
+
raise ValueError("relation_id must be a string")
|
|
122
|
+
|
|
123
|
+
try:
|
|
124
|
+
uuid.UUID(relation_id)
|
|
125
|
+
except ValueError as exc:
|
|
126
|
+
raise ValueError("relation_id must be a valid UUID") from exc
|
|
127
|
+
|
|
128
|
+
response = self._delete(url=f"{self.__base_api}/{relation_id}")
|
|
129
|
+
return self._handle_response(response)
|
|
130
|
+
|
|
131
|
+
def change_relation(
|
|
132
|
+
self,
|
|
133
|
+
relation_id: str,
|
|
134
|
+
source_id: str = None,
|
|
135
|
+
target_id: str = None,
|
|
136
|
+
starting_date: int = None,
|
|
137
|
+
ending_date: int = None
|
|
138
|
+
):
|
|
139
|
+
"""
|
|
140
|
+
Changes the relation with the information that is present in the request.
|
|
141
|
+
Only properties that are specified in this request and have non-null values are updated.
|
|
142
|
+
:param relation_id: The ID of the relation to be changed (required UUID).
|
|
143
|
+
:param source_id: The ID of the new source for the relation (optional UUID).
|
|
144
|
+
:param target_id: The ID of the new target for the relation (optional UUID).
|
|
145
|
+
:param starting_date: The new starting date for the relation (deprecated, int64).
|
|
146
|
+
:param ending_date: The new ending date for the relation (deprecated, int64).
|
|
147
|
+
:return: Details of the updated relation.
|
|
148
|
+
"""
|
|
149
|
+
# Validate required parameters
|
|
150
|
+
if not relation_id:
|
|
151
|
+
raise ValueError("relation_id is required")
|
|
152
|
+
if not isinstance(relation_id, str):
|
|
153
|
+
raise ValueError("relation_id must be a string")
|
|
154
|
+
|
|
155
|
+
try:
|
|
156
|
+
uuid.UUID(relation_id)
|
|
157
|
+
except ValueError as exc:
|
|
158
|
+
raise ValueError("relation_id must be a valid UUID") from exc
|
|
159
|
+
|
|
160
|
+
# Validate source_id if provided
|
|
161
|
+
if source_id is not None:
|
|
162
|
+
if not isinstance(source_id, str):
|
|
163
|
+
raise ValueError("source_id must be a string")
|
|
164
|
+
try:
|
|
165
|
+
uuid.UUID(source_id)
|
|
166
|
+
except ValueError as exc:
|
|
167
|
+
raise ValueError("source_id must be a valid UUID") from exc
|
|
168
|
+
|
|
169
|
+
# Validate target_id if provided
|
|
170
|
+
if target_id is not None:
|
|
171
|
+
if not isinstance(target_id, str):
|
|
172
|
+
raise ValueError("target_id must be a string")
|
|
173
|
+
try:
|
|
174
|
+
uuid.UUID(target_id)
|
|
175
|
+
except ValueError as exc:
|
|
176
|
+
raise ValueError("target_id must be a valid UUID") from exc
|
|
177
|
+
|
|
178
|
+
# Validate starting_date if provided
|
|
179
|
+
if starting_date is not None:
|
|
180
|
+
if not isinstance(starting_date, int):
|
|
181
|
+
raise ValueError("starting_date must be an integer")
|
|
182
|
+
if starting_date < 0:
|
|
183
|
+
raise ValueError("starting_date must be a positive integer")
|
|
184
|
+
|
|
185
|
+
# Validate ending_date if provided
|
|
186
|
+
if ending_date is not None:
|
|
187
|
+
if not isinstance(ending_date, int):
|
|
188
|
+
raise ValueError("ending_date must be an integer")
|
|
189
|
+
if ending_date < 0:
|
|
190
|
+
raise ValueError("ending_date must be a positive integer")
|
|
191
|
+
|
|
192
|
+
# Build request body - only include provided values
|
|
193
|
+
# Include the relation_id in the body as required by the API
|
|
194
|
+
data = {"id": relation_id}
|
|
195
|
+
|
|
196
|
+
if source_id is not None:
|
|
197
|
+
data["sourceId"] = source_id
|
|
198
|
+
if target_id is not None:
|
|
199
|
+
data["targetId"] = target_id
|
|
200
|
+
if starting_date is not None:
|
|
201
|
+
data["startingDate"] = starting_date
|
|
202
|
+
if ending_date is not None:
|
|
203
|
+
data["endingDate"] = ending_date
|
|
204
|
+
|
|
205
|
+
response = self._patch(url=f"{self.__base_api}/{relation_id}", data=data)
|
|
206
|
+
return self._handle_response(response)
|
|
@@ -113,6 +113,25 @@ class Responsibility(BaseAPI):
|
|
|
113
113
|
response = self._get(url=f"{self.__base_api}/{responsibility_id}")
|
|
114
114
|
return self._handle_response(response)
|
|
115
115
|
|
|
116
|
+
def delete_responsibility(self, responsibility_id: str):
|
|
117
|
+
"""
|
|
118
|
+
Remove the responsibility identified by the given id.
|
|
119
|
+
:param responsibility_id: The unique identifier of the responsibility.
|
|
120
|
+
:return: None
|
|
121
|
+
"""
|
|
122
|
+
if not responsibility_id:
|
|
123
|
+
raise ValueError("responsibility_id is required")
|
|
124
|
+
if not isinstance(responsibility_id, str):
|
|
125
|
+
raise ValueError("responsibility_id must be a string")
|
|
126
|
+
|
|
127
|
+
try:
|
|
128
|
+
uuid.UUID(responsibility_id)
|
|
129
|
+
except ValueError as exc:
|
|
130
|
+
raise ValueError("responsibility_id must be a valid UUID") from exc
|
|
131
|
+
|
|
132
|
+
response = self._delete(url=f"{self.__base_api}/{responsibility_id}")
|
|
133
|
+
self._handle_response(response)
|
|
134
|
+
|
|
116
135
|
def find_responsibilities(
|
|
117
136
|
self,
|
|
118
137
|
count_limit: int = -1,
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import logging
|
|
3
|
+
from .Base import BaseAPI
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Utils(BaseAPI):
|
|
9
|
+
def __init__(self, connector):
|
|
10
|
+
super().__init__(connector)
|
|
11
|
+
self.__base_api = connector.api
|
|
12
|
+
|
|
13
|
+
def get_uuids(self):
|
|
14
|
+
"""
|
|
15
|
+
Retrieves UUIDs of asset types, relation types, responsibilities, statuses, and attributes from Collibra,
|
|
16
|
+
returning a dictionary with names as keys and UUIDs as values. Relation type names are used.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
A dictionary containing dictionaries of named UUIDs for asset types, relation types,
|
|
20
|
+
responsibilities, statuses, and attributes.
|
|
21
|
+
"""
|
|
22
|
+
metadata = {
|
|
23
|
+
"AssetType": {},
|
|
24
|
+
"Relation": {},
|
|
25
|
+
"Responsability": {},
|
|
26
|
+
"Status": {},
|
|
27
|
+
"Attribute": {},
|
|
28
|
+
"Community": {},
|
|
29
|
+
"Domain": {},
|
|
30
|
+
"DomainType": {},
|
|
31
|
+
}
|
|
32
|
+
try:
|
|
33
|
+
# Get Asset Type UUIDs
|
|
34
|
+
asset_types_url = f"{self.__base_api}/assetTypes"
|
|
35
|
+
asset_types_response = self._get(url=asset_types_url)
|
|
36
|
+
asset_types_data = self._handle_response(asset_types_response)
|
|
37
|
+
for asset_type in asset_types_data["results"]:
|
|
38
|
+
metadata["AssetType"][asset_type["name"]] = asset_type["id"]
|
|
39
|
+
|
|
40
|
+
# Get Relation Type UUIDs
|
|
41
|
+
relation_types_url = f"{self.__base_api}/relationTypes"
|
|
42
|
+
relation_types_response = self._get(url=relation_types_url)
|
|
43
|
+
relation_types_data = self._handle_response(relation_types_response)
|
|
44
|
+
for relation_type in relation_types_data["results"]:
|
|
45
|
+
source_name = re.sub(" ", "", relation_type["sourceType"]["name"])
|
|
46
|
+
target_name = re.sub(" ", "", relation_type["targetType"]["name"])
|
|
47
|
+
metadata["Relation"][f"{source_name}_{target_name}"] = relation_type["id"]
|
|
48
|
+
|
|
49
|
+
# Get Roles
|
|
50
|
+
resource_roles_url = f"{self.__base_api}/roles"
|
|
51
|
+
resource_roles_response = self._get(url=resource_roles_url)
|
|
52
|
+
resource_roles_data = self._handle_response(resource_roles_response)
|
|
53
|
+
for resource_role in resource_roles_data["results"]:
|
|
54
|
+
metadata["Responsability"][resource_role["name"]] = resource_role["id"]
|
|
55
|
+
|
|
56
|
+
# Get Status UUIDs
|
|
57
|
+
statuses_url = f"{self.__base_api}/statuses"
|
|
58
|
+
statuses_response = self._get(url=statuses_url)
|
|
59
|
+
statuses_data = self._handle_response(statuses_response)
|
|
60
|
+
for status in statuses_data["results"]:
|
|
61
|
+
metadata["Status"][status["name"]] = status["id"]
|
|
62
|
+
|
|
63
|
+
# Get Attribute UUIDs
|
|
64
|
+
attributes_url = f"{self.__base_api}/attributeTypes"
|
|
65
|
+
attributes_response = self._get(url=attributes_url)
|
|
66
|
+
attributes_data = self._handle_response(attributes_response)
|
|
67
|
+
for attribute in attributes_data["results"]:
|
|
68
|
+
metadata["Attribute"][attribute["name"]] = attribute["id"]
|
|
69
|
+
|
|
70
|
+
# Get Community UUIDs
|
|
71
|
+
communities_url = f"{self.__base_api}/communities"
|
|
72
|
+
communities_response = self._get(url=communities_url)
|
|
73
|
+
communities_data = self._handle_response(communities_response)
|
|
74
|
+
for community in communities_data["results"]:
|
|
75
|
+
metadata["Community"][community["name"]] = community["id"]
|
|
76
|
+
|
|
77
|
+
# Get Domain UUIDs
|
|
78
|
+
domains_url = f"{self.__base_api}/domains"
|
|
79
|
+
domains_params = {"limit": 1000, "offset": 0}
|
|
80
|
+
while True:
|
|
81
|
+
domains_response = self._get(url=domains_url, params=domains_params)
|
|
82
|
+
domains_data = self._handle_response(domains_response)
|
|
83
|
+
for domain in domains_data["results"]:
|
|
84
|
+
metadata["Domain"][domain["name"]] = domain["id"]
|
|
85
|
+
if domains_data.get("offset") + domains_data.get(
|
|
86
|
+
"limit"
|
|
87
|
+
) >= domains_data.get("total"):
|
|
88
|
+
break
|
|
89
|
+
domains_params["offset"] += domains_params["limit"]
|
|
90
|
+
|
|
91
|
+
# Get Domain Type UUIDs
|
|
92
|
+
domain_types_url = f"{self.__base_api}/domainTypes"
|
|
93
|
+
domain_types_response = self._get(url=domain_types_url)
|
|
94
|
+
domain_types_data = self._handle_response(domain_types_response)
|
|
95
|
+
for domain_type in domain_types_data["results"]:
|
|
96
|
+
metadata["DomainType"][domain_type["name"]] = domain_type["id"]
|
|
97
|
+
|
|
98
|
+
logger.info("Collibra UUIDS fetched successfully")
|
|
99
|
+
return metadata
|
|
100
|
+
|
|
101
|
+
except (KeyError, ValueError, AttributeError) as e:
|
|
102
|
+
logger.error("Error fetching Collibra UUIDs: %s", e)
|
|
103
|
+
return None
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
from .Asset import Asset
|
|
2
2
|
from .Base import BaseAPI
|
|
3
3
|
from .Community import Community
|
|
4
|
-
from .Domain import Domain
|
|
5
|
-
from .User import User
|
|
6
|
-
from .Responsibility import Responsibility
|
|
7
|
-
from .Workflow import Workflow
|
|
8
|
-
from .Metadata import Metadata
|
|
9
4
|
from .Comment import Comment
|
|
5
|
+
from .Domain import Domain
|
|
10
6
|
from .Exceptions import (
|
|
11
7
|
CollibraAPIError,
|
|
12
8
|
UnauthorizedError,
|
|
@@ -14,3 +10,10 @@ from .Exceptions import (
|
|
|
14
10
|
NotFoundError,
|
|
15
11
|
ServerError
|
|
16
12
|
)
|
|
13
|
+
from .Metadata import Metadata
|
|
14
|
+
from .OutputModule import OutputModule
|
|
15
|
+
from .Relation import Relation
|
|
16
|
+
from .Responsibility import Responsibility
|
|
17
|
+
from .User import User
|
|
18
|
+
from .Utils import Utils
|
|
19
|
+
from .Workflow import Workflow
|
collibra_connector/connector.py
CHANGED
|
@@ -10,7 +10,8 @@ from .api import (
|
|
|
10
10
|
Responsibility,
|
|
11
11
|
Workflow,
|
|
12
12
|
Metadata,
|
|
13
|
-
Comment
|
|
13
|
+
Comment,
|
|
14
|
+
Relation
|
|
14
15
|
)
|
|
15
16
|
|
|
16
17
|
|
|
@@ -42,6 +43,7 @@ class CollibraConnector():
|
|
|
42
43
|
self.workflow = Workflow(self)
|
|
43
44
|
self.metadata = Metadata(self)
|
|
44
45
|
self.comment = Comment(self)
|
|
46
|
+
self.relation = Relation(self)
|
|
45
47
|
|
|
46
48
|
logging.basicConfig(level=logging.INFO)
|
|
47
49
|
self.logger = logging.getLogger(__name__)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: collibra-connector
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.11
|
|
4
4
|
Summary: An UNOFFICIAL standard Python connector for the Collibra Data Governance Center API.
|
|
5
5
|
Author-email: Raül Dalgamonni <rauldalgamonnialonso@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/rauldaal/collibra-python-connector
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
collibra_connector/__init__.py,sha256=vzF9epFfmdnFjOcr_qZhvfiN9Z0cIBB48xldnvIiKjo,1694
|
|
2
|
+
collibra_connector/connector.py,sha256=oNN8WCI1TI6ffSEfl6_SX7SdrznwA5UeN7U13m-O_hU,2224
|
|
3
|
+
collibra_connector/api/Asset.py,sha256=aPhnsRxzdGGFtaytpLueDgMrELMpIs4cuOJoc2DR-p4,17927
|
|
4
|
+
collibra_connector/api/Base.py,sha256=2gHpieP8N_PK-R63zUv38Wpdfqdw9tHcH59hlXUZOWM,5929
|
|
5
|
+
collibra_connector/api/Comment.py,sha256=4ZzXiKj3pDOw_JRhfrUj-gcF8nZVdW_z7X2jJnq7LcU,4994
|
|
6
|
+
collibra_connector/api/Community.py,sha256=kM4j0LGYCXQygOZ4zHuu10JzJzvXtbUDz9litzKeKUI,12132
|
|
7
|
+
collibra_connector/api/Domain.py,sha256=U0i103g1WceCn9qAFUWDLgeXrtOvfBqX3vMCn4sQqRE,13012
|
|
8
|
+
collibra_connector/api/Exceptions.py,sha256=lX8yU3BnlOiWWifIBKlZdXVZaTI5pvtbrffyDtEUtoc,429
|
|
9
|
+
collibra_connector/api/Metadata.py,sha256=4uzb4vnZuMOg_ISCEnCfmAEVbsIcuD4FvupDlcxrfT4,5213
|
|
10
|
+
collibra_connector/api/OutputModule.py,sha256=97TzIbeoC5V63x5fi5fEcGfviUydwKwJC3NobLuNF5w,1791
|
|
11
|
+
collibra_connector/api/Relation.py,sha256=Hw0PlAQrU2Zv-RAbvHZhZpZb2_m6uDWngx2ySwo_mv0,8079
|
|
12
|
+
collibra_connector/api/Responsibility.py,sha256=PJu1Pe1u8mKzgpGGjzHtZNfRTfpgWWbaQn5bSifZOMo,14123
|
|
13
|
+
collibra_connector/api/User.py,sha256=nPl8q6l-H8hq2sR7gLelXq09jl3QRWFzI_WU3OUIHhQ,7755
|
|
14
|
+
collibra_connector/api/Utils.py,sha256=F8ZWrW8urzDX8QfiL16kWRnBYGRiLqeKUbYXlQpXNiM,4674
|
|
15
|
+
collibra_connector/api/Workflow.py,sha256=rsD9mPut69eEy35TNGf2mUKTrgWUmoakgnsXa85XzNY,10417
|
|
16
|
+
collibra_connector/api/__init__.py,sha256=yBJcKzcRraE-UYbBviisbdvQ1asFBnud5Vo1oJcCv_w,491
|
|
17
|
+
collibra_connector-1.0.11.dist-info/licenses/LICENSE,sha256=6KmWWtAu_q58gerPlrnkgsmGM2l8j6Wc_VL0y4S_ip4,1079
|
|
18
|
+
collibra_connector-1.0.11.dist-info/METADATA,sha256=HXkSXZVVmm1z57evuwsuWoOzFI6lSjrVuhd2hZKSHEU,4081
|
|
19
|
+
collibra_connector-1.0.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
20
|
+
collibra_connector-1.0.11.dist-info/top_level.txt,sha256=Vs-kR64zf__ebL2j3_AEx7rhO6xkwgmHUFRzxlQPgTQ,19
|
|
21
|
+
collibra_connector-1.0.11.dist-info/RECORD,,
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
collibra_connector/__init__.py,sha256=vzF9epFfmdnFjOcr_qZhvfiN9Z0cIBB48xldnvIiKjo,1694
|
|
2
|
-
collibra_connector/connector.py,sha256=VjoFk0Jouz6vEhP74_9MJv6f8EQxKg_durmkbDLKxbI,2171
|
|
3
|
-
collibra_connector/api/Asset.py,sha256=JJkImmgxYN3zGacSlnXegVnO2xHZqUhTiOyjhQFnvEU,10359
|
|
4
|
-
collibra_connector/api/Base.py,sha256=8sYTPrIlHZP8smfYKl2rWSL63aKqHrtFca_M6gEOVns,5881
|
|
5
|
-
collibra_connector/api/Comment.py,sha256=4ZzXiKj3pDOw_JRhfrUj-gcF8nZVdW_z7X2jJnq7LcU,4994
|
|
6
|
-
collibra_connector/api/Community.py,sha256=yEDbYEmEi7ZhVsodTtCTi2DpEa-NOojgsOK3ihn7wfY,4463
|
|
7
|
-
collibra_connector/api/Domain.py,sha256=CXDVheIcJ_7cU_h_gOozAg2nliFoAEMoeprZRIba_i8,4605
|
|
8
|
-
collibra_connector/api/Exceptions.py,sha256=lX8yU3BnlOiWWifIBKlZdXVZaTI5pvtbrffyDtEUtoc,429
|
|
9
|
-
collibra_connector/api/Metadata.py,sha256=lOVXu0pcHSZNhInb4nR4q7lBB1MwtRuoL4Qb-2sr8aI,5213
|
|
10
|
-
collibra_connector/api/Responsibility.py,sha256=s9W2oa11CS2_CEDYrgdjpHOjX83ysXnQ9CNDUFlzGTQ,13372
|
|
11
|
-
collibra_connector/api/User.py,sha256=nPl8q6l-H8hq2sR7gLelXq09jl3QRWFzI_WU3OUIHhQ,7755
|
|
12
|
-
collibra_connector/api/Workflow.py,sha256=rsD9mPut69eEy35TNGf2mUKTrgWUmoakgnsXa85XzNY,10417
|
|
13
|
-
collibra_connector/api/__init__.py,sha256=61ZNTfMTMRMPCy8WABptw152RriLZ_B1HV455vipFDk,396
|
|
14
|
-
collibra_connector-1.0.10b0.dist-info/licenses/LICENSE,sha256=6KmWWtAu_q58gerPlrnkgsmGM2l8j6Wc_VL0y4S_ip4,1079
|
|
15
|
-
collibra_connector-1.0.10b0.dist-info/METADATA,sha256=jIfBXEZlypct5cyb9E1H878_-MhF9gbxesqoOQTEPUQ,4083
|
|
16
|
-
collibra_connector-1.0.10b0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
17
|
-
collibra_connector-1.0.10b0.dist-info/top_level.txt,sha256=Vs-kR64zf__ebL2j3_AEx7rhO6xkwgmHUFRzxlQPgTQ,19
|
|
18
|
-
collibra_connector-1.0.10b0.dist-info/RECORD,,
|
|
File without changes
|
{collibra_connector-1.0.10b0.dist-info → collibra_connector-1.0.11.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|