brynq-sdk-brynq 4.2.6.dev0__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 brynq-sdk-brynq might be problematic. Click here for more details.
- brynq_sdk_brynq/__init__.py +1 -0
- brynq_sdk_brynq/brynq.py +289 -0
- brynq_sdk_brynq/credentials.py +157 -0
- brynq_sdk_brynq/customers.py +88 -0
- brynq_sdk_brynq/interfaces.py +234 -0
- brynq_sdk_brynq/mappings.py +107 -0
- brynq_sdk_brynq/organization_chart.py +251 -0
- brynq_sdk_brynq/roles.py +272 -0
- brynq_sdk_brynq/scenarios.py +3495 -0
- brynq_sdk_brynq/schemas/__init__.py +52 -0
- brynq_sdk_brynq/schemas/credentials.py +37 -0
- brynq_sdk_brynq/schemas/customers.py +108 -0
- brynq_sdk_brynq/schemas/interfaces.py +237 -0
- brynq_sdk_brynq/schemas/organization_chart.py +70 -0
- brynq_sdk_brynq/schemas/roles.py +95 -0
- brynq_sdk_brynq/schemas/scenarios.py +419 -0
- brynq_sdk_brynq/schemas/users.py +126 -0
- brynq_sdk_brynq/source_systems.py +175 -0
- brynq_sdk_brynq/users.py +405 -0
- brynq_sdk_brynq-4.2.6.dev0.dist-info/METADATA +17 -0
- brynq_sdk_brynq-4.2.6.dev0.dist-info/RECORD +23 -0
- brynq_sdk_brynq-4.2.6.dev0.dist-info/WHEEL +5 -0
- brynq_sdk_brynq-4.2.6.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
from typing import Dict, List, Any, Optional
|
|
2
|
+
from .credentials import Credentials
|
|
3
|
+
from .mappings import Mappings
|
|
4
|
+
from .scenarios import Scenarios
|
|
5
|
+
from .schemas.interfaces import Interface, InterfaceDetail, InterfaceConfig, Schedule, Scope, DevSettings
|
|
6
|
+
from brynq_sdk_functions import Functions
|
|
7
|
+
|
|
8
|
+
class Interfaces:
|
|
9
|
+
"""
|
|
10
|
+
Handles all interface-related operations for BrynQ SDK.
|
|
11
|
+
"""
|
|
12
|
+
def __init__(self, brynq_instance):
|
|
13
|
+
"""
|
|
14
|
+
Initialize Interfaces manager.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
brynq_instance: The parent BrynQ instance
|
|
18
|
+
"""
|
|
19
|
+
self._brynq = brynq_instance
|
|
20
|
+
self.credentials = Credentials(brynq_instance)
|
|
21
|
+
self.mappings = Mappings(brynq_instance)
|
|
22
|
+
self.scenarios = Scenarios(brynq_instance)
|
|
23
|
+
|
|
24
|
+
def get_all(self) -> List[Dict[str, Any]]:
|
|
25
|
+
"""Get all interfaces this token has access to.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
List[Dict[str, Any]]: List of interfaces with their details including:
|
|
29
|
+
- id (int): Interface ID
|
|
30
|
+
- name (str): Interface name
|
|
31
|
+
- description (str): Interface description
|
|
32
|
+
- sourceSystems (List[int]): List of source system IDs
|
|
33
|
+
- targetSystems (List[int]): List of target system IDs
|
|
34
|
+
- taskSchedule (Dict): Task schedule details including status, timing, etc.
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
ValueError: If the response data is invalid
|
|
38
|
+
requests.exceptions.RequestException: If the API request fails
|
|
39
|
+
"""
|
|
40
|
+
response = self._brynq.brynq_session.get(
|
|
41
|
+
f"{self._brynq.url}interfaces",
|
|
42
|
+
timeout=self._brynq.timeout
|
|
43
|
+
)
|
|
44
|
+
response.raise_for_status()
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
interfaces_data = response.json()
|
|
48
|
+
valid_data, _ = Functions.validate_pydantic_data(interfaces_data, schema=Interface)
|
|
49
|
+
return valid_data
|
|
50
|
+
except ValueError as e:
|
|
51
|
+
raise ValueError(f"Invalid interface data received from API: {str(e)}")
|
|
52
|
+
|
|
53
|
+
def get(self) -> Dict[str, Any]:
|
|
54
|
+
"""Get a specific interface by its ID.
|
|
55
|
+
Returns:
|
|
56
|
+
Dict[str, Any]: Interface details including:
|
|
57
|
+
- name (str): Interface name
|
|
58
|
+
- type (str): Interface type (e.g., 'ADVANCED')
|
|
59
|
+
- apps (Dict): Application configuration with:
|
|
60
|
+
- source (str): Source application name
|
|
61
|
+
- target (str): Target application name
|
|
62
|
+
|
|
63
|
+
Raises:
|
|
64
|
+
ValueError: If interface_id is not a positive integer or if the response data is invalid
|
|
65
|
+
requests.exceptions.RequestException: If the API request fails
|
|
66
|
+
"""
|
|
67
|
+
# Basic validation
|
|
68
|
+
|
|
69
|
+
response = self._brynq.brynq_session.get(
|
|
70
|
+
f"{self._brynq.url}interfaces/{self._brynq.data_interface_id}",
|
|
71
|
+
timeout=self._brynq.timeout
|
|
72
|
+
)
|
|
73
|
+
response.raise_for_status()
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
interface_data = response.json()
|
|
77
|
+
valid_data, _ = Functions.validate_pydantic_data(interface_data, schema=InterfaceDetail)
|
|
78
|
+
return valid_data[0]
|
|
79
|
+
except ValueError as e:
|
|
80
|
+
raise ValueError(f"Invalid interface data received from API: {str(e)}")
|
|
81
|
+
|
|
82
|
+
def get_config(self) -> Dict[str, Any]:
|
|
83
|
+
"""Get the base configuration of an interface.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
interface_id (int): The ID of the interface
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Dict[str, Any]: Interface configuration including:
|
|
90
|
+
- mapping (List): List of mapping configurations
|
|
91
|
+
- variables (Dict): Configuration variables
|
|
92
|
+
|
|
93
|
+
Raises:
|
|
94
|
+
ValueError: If interface_id is not a positive integer or if the response data is invalid
|
|
95
|
+
requests.exceptions.RequestException: If the API request fails
|
|
96
|
+
"""
|
|
97
|
+
# Basic validation
|
|
98
|
+
|
|
99
|
+
response = self._brynq.brynq_session.get(
|
|
100
|
+
f"{self._brynq.url}interfaces/{self._brynq.data_interface_id}/config",
|
|
101
|
+
timeout=self._brynq.timeout
|
|
102
|
+
)
|
|
103
|
+
response.raise_for_status()
|
|
104
|
+
|
|
105
|
+
try:
|
|
106
|
+
config_data = response.json()
|
|
107
|
+
valid_data, _ = Functions.validate_pydantic_data(config_data, schema=InterfaceConfig)
|
|
108
|
+
return valid_data[0]
|
|
109
|
+
except ValueError as e:
|
|
110
|
+
raise ValueError(f"Invalid interface configuration data: {str(e)}")
|
|
111
|
+
|
|
112
|
+
def flush_config(self) -> Dict[str, Any]:
|
|
113
|
+
"""
|
|
114
|
+
Flushes the interface config to revert to a fresh state.
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
Dict[str, Any]: Response from the flush operation
|
|
118
|
+
|
|
119
|
+
Raises:
|
|
120
|
+
requests.exceptions.RequestException: If the API request fails
|
|
121
|
+
"""
|
|
122
|
+
response = self._brynq.brynq_session.get(
|
|
123
|
+
url=f'{self._brynq.url}interfaces/{self._brynq.data_interface_id}/config/flush',
|
|
124
|
+
timeout=self._brynq.timeout
|
|
125
|
+
)
|
|
126
|
+
response.raise_for_status()
|
|
127
|
+
return response
|
|
128
|
+
|
|
129
|
+
def get_schedule(self) -> Dict[str, Any]:
|
|
130
|
+
"""Get the schedule configuration of an interface.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
Dict[str, Any]: Schedule configuration including:
|
|
134
|
+
- id (int): The schedule ID
|
|
135
|
+
- triggerType (str): Type of trigger (e.g., 'MANUAL')
|
|
136
|
+
- triggerPattern (str): Pattern for the trigger
|
|
137
|
+
- timezone (str): Timezone setting
|
|
138
|
+
- nextReload (str, optional): Next scheduled reload time
|
|
139
|
+
- frequency (Dict): Object containing day, hour, month, minute
|
|
140
|
+
- startAfterPrecedingTask (bool, optional): Whether to start after preceding task
|
|
141
|
+
- lastReload (str): Last reload time
|
|
142
|
+
- lastErrorMessage (str): Last error message
|
|
143
|
+
|
|
144
|
+
Raises:
|
|
145
|
+
ValueError: If interface_id is not a positive integer or if the response data is invalid
|
|
146
|
+
requests.exceptions.RequestException: If the API request fails
|
|
147
|
+
"""
|
|
148
|
+
response = self._brynq.brynq_session.get(
|
|
149
|
+
f"{self._brynq.url}interfaces/{self._brynq.data_interface_id}/config/schedule",
|
|
150
|
+
timeout=self._brynq.timeout
|
|
151
|
+
)
|
|
152
|
+
response.raise_for_status()
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
schedule_data = response.json()
|
|
156
|
+
valid_data, _ = Functions.validate_pydantic_data(schedule_data, schema=Schedule)
|
|
157
|
+
return valid_data[0]
|
|
158
|
+
except ValueError as e:
|
|
159
|
+
raise ValueError(f"Invalid schedule configuration data: {str(e)}")
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def get_scope(self) -> Dict[str, Any]:
|
|
163
|
+
"""Get live and draft scopes from interface by id.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
Dict[str, Any]: Scope configuration including:
|
|
167
|
+
- live (Dict, optional): Live scope configuration
|
|
168
|
+
- draft (Dict, optional): Draft scope configuration
|
|
169
|
+
|
|
170
|
+
Raises:
|
|
171
|
+
ValueError: If interface_id is not a positive integer or if the response data is invalid
|
|
172
|
+
requests.exceptions.RequestException: If the API request fails
|
|
173
|
+
"""
|
|
174
|
+
response = self._brynq.brynq_session.get(
|
|
175
|
+
f"{self._brynq.url}interfaces/{self._brynq.data_interface_id}/scope",
|
|
176
|
+
timeout=self._brynq.timeout
|
|
177
|
+
)
|
|
178
|
+
response.raise_for_status()
|
|
179
|
+
|
|
180
|
+
try:
|
|
181
|
+
scope_data = response.json()
|
|
182
|
+
valid_data, _ = Functions.validate_pydantic_data(scope_data, schema=Scope)
|
|
183
|
+
return valid_data[0]
|
|
184
|
+
except ValueError as e:
|
|
185
|
+
raise ValueError(f"Invalid scope data: {str(e)}")
|
|
186
|
+
|
|
187
|
+
def get_dev_settings(self) -> List[dict[str,Any]]:
|
|
188
|
+
"""Get the dev-settings of an interface
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
Dict[str, Any]: A dictionary containing the dev settings:
|
|
192
|
+
- dockerImage (str): Docker image name
|
|
193
|
+
- sftpMapping (List[dict]): SFTP mapping configuration
|
|
194
|
+
- runfilePath (str): Path to the runfile
|
|
195
|
+
- stopIsAllowed (bool): Whether stopping is allowed
|
|
196
|
+
|
|
197
|
+
Raises:
|
|
198
|
+
requests.exceptions.RequestException: If the API request fails
|
|
199
|
+
requests.exceptions.HTTPError: If dev settings not found (404)
|
|
200
|
+
ValueError: If interface_id is not a positive integer
|
|
201
|
+
"""
|
|
202
|
+
|
|
203
|
+
response = self._brynq.brynq_session.get(
|
|
204
|
+
url=f"{self._brynq.url}interfaces/{self._brynq.data_interface_id}/config/dev-settings",
|
|
205
|
+
timeout=self._brynq.timeout
|
|
206
|
+
)
|
|
207
|
+
response.raise_for_status()
|
|
208
|
+
|
|
209
|
+
valid_data, _ = Functions.validate_pydantic_data(response.json(), schema=DevSettings)
|
|
210
|
+
return valid_data
|
|
211
|
+
|
|
212
|
+
def get_variables(self, variable_name: str = None):
|
|
213
|
+
"""
|
|
214
|
+
Get a value from the task_variables table corresponding with the given name. If temp value is filled, it will
|
|
215
|
+
(run_instant = 1), then the temp_value will be returned. This is to give the possibility for users in the frontend to run
|
|
216
|
+
a task once manual with other values then normal without overwriting the normal values.
|
|
217
|
+
:param variable_name: the name of the variable
|
|
218
|
+
:return: the value of the given variable.
|
|
219
|
+
"""
|
|
220
|
+
|
|
221
|
+
variables = self.get_config().get("variables")
|
|
222
|
+
|
|
223
|
+
if not variables:
|
|
224
|
+
raise Exception(f"There are no valid variables in interface '{self._brynq.data_interface_id}'")
|
|
225
|
+
|
|
226
|
+
if variable_name:
|
|
227
|
+
variable = variables.get(variable_name)
|
|
228
|
+
if not variable:
|
|
229
|
+
raise Exception(f"The variable '{variable_name}' does not exist in interface '{self._brynq.data_interface_id}'")
|
|
230
|
+
self.flush_config()
|
|
231
|
+
return variable
|
|
232
|
+
else:
|
|
233
|
+
self.flush_config()
|
|
234
|
+
return variables
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from typing import Optional, Union, Literal, Any, Tuple, List, Dict
|
|
4
|
+
import warnings
|
|
5
|
+
from .schemas.interfaces import MappingItem
|
|
6
|
+
from brynq_sdk_functions import Functions
|
|
7
|
+
|
|
8
|
+
class MappingNotFoundError(Exception):
|
|
9
|
+
"""Raised when a requested mapping is not found"""
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
class Mappings:
|
|
13
|
+
"""
|
|
14
|
+
Handles all mapping-related operations for BrynQ SDK.
|
|
15
|
+
"""
|
|
16
|
+
def __init__(self, brynq_instance):
|
|
17
|
+
"""
|
|
18
|
+
Initialize Mappings manager.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
brynq_instance: The parent BrynQ instance
|
|
22
|
+
"""
|
|
23
|
+
self._brynq = brynq_instance
|
|
24
|
+
|
|
25
|
+
def _get_mappings(self) -> List[Dict[str, Any]]:
|
|
26
|
+
"""Get all mappings for an interface.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
interface_id (int): The ID of the interface
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
List[Dict[str, Any]]: List of mapping configurations
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
ValueError: If interface_id is not a positive integer or if the response data is invalid
|
|
36
|
+
requests.exceptions.RequestException: If the API request fails
|
|
37
|
+
"""
|
|
38
|
+
response = self._brynq.brynq_session.get(
|
|
39
|
+
f"{self._brynq.url}interfaces/{self._brynq.data_interface_id}/config/mapping",
|
|
40
|
+
timeout=self._brynq.timeout
|
|
41
|
+
)
|
|
42
|
+
response.raise_for_status()
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
mappings_data = response.json()
|
|
46
|
+
valid_data, _ = Functions.validate_pydantic_data(mappings_data, schema=MappingItem)
|
|
47
|
+
return valid_data
|
|
48
|
+
except ValueError as e:
|
|
49
|
+
raise ValueError(f"Invalid mappings data: {str(e)}")
|
|
50
|
+
|
|
51
|
+
def _to_dataframe(self, mapping_data: dict, prefix: bool = False) -> pd.DataFrame:
|
|
52
|
+
"""Convert mapping values to DataFrame format"""
|
|
53
|
+
rows = []
|
|
54
|
+
for value in mapping_data['values']:
|
|
55
|
+
row = {}
|
|
56
|
+
for key, val in value['input'].items():
|
|
57
|
+
row[f'input.{key}' if prefix else key] = val
|
|
58
|
+
for key, val in value['output'].items():
|
|
59
|
+
row[f'output.{key}' if prefix else key] = val
|
|
60
|
+
rows.append(row)
|
|
61
|
+
return pd.DataFrame(rows)
|
|
62
|
+
|
|
63
|
+
def _to_dict(self, mapping_data: dict) -> dict:
|
|
64
|
+
"""Convert mapping values to dictionary format"""
|
|
65
|
+
mappings = {}
|
|
66
|
+
for value in mapping_data['values']:
|
|
67
|
+
input_key = ','.join(value['input'].values())
|
|
68
|
+
output_value = ','.join(value['output'].values()) if len(value['output']) > 1 else next(iter(value['output'].values()))
|
|
69
|
+
mappings[input_key] = output_value
|
|
70
|
+
return mappings
|
|
71
|
+
|
|
72
|
+
def get(self, mapping: Optional[str] = None, as_df: bool = False, prefix: bool = False) -> dict:
|
|
73
|
+
"""Get the mapping from BrynQ.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
interface_id (int): The id of the task in BrynQ
|
|
77
|
+
mapping (str): The name of the mapping
|
|
78
|
+
as_df (bool, optional): If True, returns mappings as pandas DataFrame. If False, returns mappings as dictionary. Defaults to False.
|
|
79
|
+
prefix (bool, optional): Only used when as_df is True. If True, prefixes column names with 'input.' and 'output.'. Defaults to False.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
dict: Dictionary with keys:
|
|
83
|
+
- 'default_value': The default value for the mapping
|
|
84
|
+
- 'mappings': Either a DataFrame (if as_df=True) or a dictionary (if as_df=False)
|
|
85
|
+
|
|
86
|
+
Raises:
|
|
87
|
+
MappingNotFoundError: If mapping is not found
|
|
88
|
+
ValueError: If mapping data is invalid
|
|
89
|
+
"""
|
|
90
|
+
mappings = self._get_mappings()
|
|
91
|
+
if mapping is None:
|
|
92
|
+
if as_df:
|
|
93
|
+
mapping_data = [{'default_value': item['default_value'], 'mappings': self._to_dataframe(item, prefix)} for item in mappings]
|
|
94
|
+
else:
|
|
95
|
+
mapping_data = [{'default_value': item['default_value'], 'mappings': self._to_dict(item)} for item in mappings]
|
|
96
|
+
|
|
97
|
+
return mapping_data
|
|
98
|
+
else:
|
|
99
|
+
mapping_data = next((item for item in mappings if item['name'] == mapping), None)
|
|
100
|
+
|
|
101
|
+
if not mapping_data:
|
|
102
|
+
raise MappingNotFoundError(f"Mapping named '{mapping}' not found")
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
'default_value': mapping_data['default_value'],
|
|
106
|
+
'mappings': self._to_dataframe(mapping_data, prefix) if as_df else self._to_dict(mapping_data)
|
|
107
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from typing import Dict, List, Any, Literal, Union, Optional
|
|
3
|
+
from .schemas.organization_chart import (
|
|
4
|
+
OrganizationChartNode,
|
|
5
|
+
OrganizationLayerCreate,
|
|
6
|
+
OrganizationLayerGet,
|
|
7
|
+
OrganizationLayerUpdate,
|
|
8
|
+
OrganizationNode,
|
|
9
|
+
OrganizationNodeCreate, OrganizationNodeUpdate
|
|
10
|
+
)
|
|
11
|
+
from brynq_sdk_functions import Functions
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class OrganizationChart:
|
|
15
|
+
"""
|
|
16
|
+
Handles all organization chart related operations for BrynQ SDK.
|
|
17
|
+
"""
|
|
18
|
+
def __init__(self, brynq_instance):
|
|
19
|
+
"""
|
|
20
|
+
Initialize OrganizationChart manager.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
brynq_instance: The parent BrynQ instance
|
|
24
|
+
"""
|
|
25
|
+
self._brynq = brynq_instance
|
|
26
|
+
|
|
27
|
+
def get(self, layout: Literal["nested", "flat"] = "nested") -> List[Dict[str, Any]]:
|
|
28
|
+
"""Get all organization charts.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
layout (str): Layout format, either "nested" or "flat"
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
Dict[str, Any]: Organization charts data including:
|
|
35
|
+
- id (int): Node ID
|
|
36
|
+
- name (str): Node name
|
|
37
|
+
- dropIndex (int): Drop index for ordering
|
|
38
|
+
- parent_id (int, optional): Parent node ID, null for root nodes
|
|
39
|
+
- source_system_entities (List[str]): List of source system entities
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
requests.exceptions.RequestException: If the API request fails
|
|
43
|
+
ValueError: If layout is not "nested" or "flat" or if the response data is invalid
|
|
44
|
+
"""
|
|
45
|
+
if layout not in ["nested", "flat"]:
|
|
46
|
+
raise ValueError('layout must be either "nested" or "flat"')
|
|
47
|
+
|
|
48
|
+
response = self._brynq.brynq_session.get(
|
|
49
|
+
f"{self._brynq.url}organization-chart",
|
|
50
|
+
params={"layout": layout},
|
|
51
|
+
timeout=self._brynq.timeout
|
|
52
|
+
)
|
|
53
|
+
response.raise_for_status()
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
chart_data = response.json()
|
|
57
|
+
valid_data, _ = Functions.validate_pydantic_data(chart_data, schema=OrganizationChartNode)
|
|
58
|
+
return valid_data
|
|
59
|
+
except ValueError as e:
|
|
60
|
+
raise ValueError(f"Invalid organization chart data: {str(e)}")
|
|
61
|
+
|
|
62
|
+
def get_layers(self) -> List[Dict[str, Any]]:
|
|
63
|
+
"""Get all organization layers.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Dict[str, Any]: Organization chart layers data including:
|
|
67
|
+
- id (int): Layer ID
|
|
68
|
+
- name (str): Layer name
|
|
69
|
+
- level (int): Layer level in hierarchy
|
|
70
|
+
|
|
71
|
+
Raises:
|
|
72
|
+
requests.exceptions.RequestException: If the API request fails
|
|
73
|
+
ValueError: If the response data is invalid
|
|
74
|
+
"""
|
|
75
|
+
response = self._brynq.brynq_session.get(
|
|
76
|
+
f"{self._brynq.url}organization-chart/layers",
|
|
77
|
+
timeout=self._brynq.timeout
|
|
78
|
+
)
|
|
79
|
+
response.raise_for_status()
|
|
80
|
+
|
|
81
|
+
try:
|
|
82
|
+
layers_data = response.json()
|
|
83
|
+
valid_data, _ = Functions.validate_pydantic_data(layers_data, schema=OrganizationLayerGet)
|
|
84
|
+
return valid_data
|
|
85
|
+
except ValueError as e:
|
|
86
|
+
raise ValueError(f"Invalid organization layer data: {str(e)}")
|
|
87
|
+
|
|
88
|
+
def create_layer(self, data:Dict[str,Any]) -> Dict[str, Any]:
|
|
89
|
+
"""Create a new organization layer.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
data (Dict[str,Any]): Data to create a new layer for
|
|
93
|
+
{
|
|
94
|
+
name (str): Layer name
|
|
95
|
+
level (int): Layer level in hierarchy
|
|
96
|
+
}
|
|
97
|
+
Returns:
|
|
98
|
+
Dict[str, Any]: Response from the API
|
|
99
|
+
|
|
100
|
+
Raises:
|
|
101
|
+
requests.exceptions.RequestException: If the API request fails
|
|
102
|
+
ValueError: If the input data is invalid
|
|
103
|
+
"""
|
|
104
|
+
valid_data, _ = Functions.validate_pydantic_data(data, schema=OrganizationLayerCreate)
|
|
105
|
+
|
|
106
|
+
response = self._brynq.brynq_session.post(
|
|
107
|
+
f"{self._brynq.url}organization-chart/layers",
|
|
108
|
+
json=valid_data[0],
|
|
109
|
+
timeout=self._brynq.timeout
|
|
110
|
+
)
|
|
111
|
+
response.raise_for_status()
|
|
112
|
+
return response
|
|
113
|
+
|
|
114
|
+
def update_layer(self, data:dict[str, Any]) -> Dict[str, Any]:
|
|
115
|
+
"""Update an existing organization layer.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
data(dict[]): Organization layer data
|
|
119
|
+
{
|
|
120
|
+
layer_id (int): ID of the layer to update
|
|
121
|
+
name (str): New layer name
|
|
122
|
+
level (int): New layer level in hierarchy
|
|
123
|
+
}
|
|
124
|
+
Returns:
|
|
125
|
+
Dict[str, Any]: Response from the API
|
|
126
|
+
|
|
127
|
+
Raises:
|
|
128
|
+
requests.exceptions.RequestException: If the API request fails
|
|
129
|
+
ValueError: If the input data is invalid
|
|
130
|
+
"""
|
|
131
|
+
valid_data, _ = Functions.validate_pydantic_data(data, schema=OrganizationLayerUpdate)
|
|
132
|
+
|
|
133
|
+
response = self._brynq.brynq_session.put(
|
|
134
|
+
f"{self._brynq.url}organization-chart/layers/{data['id']}",
|
|
135
|
+
json=valid_data[0],
|
|
136
|
+
timeout=self._brynq.timeout
|
|
137
|
+
)
|
|
138
|
+
response.raise_for_status()
|
|
139
|
+
return response
|
|
140
|
+
|
|
141
|
+
def delete_layer(self, layer_id: int) -> None:
|
|
142
|
+
"""Delete a layer and its underlying layers.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
layer_id (int): ID of the layer to delete
|
|
146
|
+
|
|
147
|
+
Raises:
|
|
148
|
+
requests.exceptions.RequestException: If the API request fails
|
|
149
|
+
ValueError: If layer_id is not an integer
|
|
150
|
+
"""
|
|
151
|
+
if not isinstance(layer_id, int):
|
|
152
|
+
raise ValueError("layer_id must be an integer")
|
|
153
|
+
|
|
154
|
+
response = self._brynq.brynq_session.delete(
|
|
155
|
+
f"{self._brynq.url}organization-chart/layers/{layer_id}",
|
|
156
|
+
timeout=self._brynq.timeout
|
|
157
|
+
)
|
|
158
|
+
response.raise_for_status()
|
|
159
|
+
return response
|
|
160
|
+
|
|
161
|
+
def get_nodes(self) -> List[Dict[str, Any]]:
|
|
162
|
+
"""Get all organization chart nodes.
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
Dict[str, Any]: Organization chart nodes data including:
|
|
166
|
+
- id (int): Node ID
|
|
167
|
+
- name (str): Node name
|
|
168
|
+
- parentId (int, optional): Parent node ID
|
|
169
|
+
|
|
170
|
+
Raises:
|
|
171
|
+
requests.exceptions.RequestException: If the API request fails
|
|
172
|
+
ValueError: If the response data is invalid
|
|
173
|
+
"""
|
|
174
|
+
response = self._brynq.brynq_session.get(
|
|
175
|
+
url=f'{self._brynq.url}organization-chart/nodes',
|
|
176
|
+
timeout=self._brynq.timeout
|
|
177
|
+
)
|
|
178
|
+
response.raise_for_status()
|
|
179
|
+
valid_data, _ = Functions.validate_pydantic_data(response.json(), schema=OrganizationNode)
|
|
180
|
+
return valid_data
|
|
181
|
+
|
|
182
|
+
def create_nodes(self, data:dict) -> Dict[str, Any]:
|
|
183
|
+
"""Create an organization chart node.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
data (dict): Node data
|
|
187
|
+
{
|
|
188
|
+
name (str): Name of the node
|
|
189
|
+
position (int, optional): Position among siblings
|
|
190
|
+
parent_id (int, optional): ID of the parent node
|
|
191
|
+
}
|
|
192
|
+
Returns:
|
|
193
|
+
Dict[str, Any]: Response from the API
|
|
194
|
+
|
|
195
|
+
Raises:
|
|
196
|
+
requests.exceptions.RequestException: If the API request fails
|
|
197
|
+
ValueError: If the input data is invalid
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
valid_data, _ = Functions.validate_pydantic_data(data, schema=OrganizationNodeCreate)
|
|
201
|
+
|
|
202
|
+
response = self._brynq.brynq_session.post(
|
|
203
|
+
f"{self._brynq.url}organization-chart/nodes",
|
|
204
|
+
json=valid_data[0],
|
|
205
|
+
timeout=self._brynq.timeout
|
|
206
|
+
)
|
|
207
|
+
response.raise_for_status()
|
|
208
|
+
return response
|
|
209
|
+
|
|
210
|
+
def update_node(self, data: dict) -> dict:
|
|
211
|
+
"""Update an organization chart node.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
data (dict): Dictionary containing fields to update (e.g. name, position, parentId)
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
dict: Updated node details returned from API
|
|
218
|
+
|
|
219
|
+
Raises:
|
|
220
|
+
ValueError: If node_id is not a positive integer
|
|
221
|
+
requests.exceptions.RequestException: If the API request fails
|
|
222
|
+
"""
|
|
223
|
+
valid_data, _ = Functions.validate_pydantic_data(data, schema=OrganizationNodeUpdate)
|
|
224
|
+
|
|
225
|
+
response = self._brynq.brynq_session.put(
|
|
226
|
+
f"{self._brynq.url}organization-chart/nodes/{data['id']}",
|
|
227
|
+
json=valid_data[0],
|
|
228
|
+
timeout=self._brynq.timeout
|
|
229
|
+
)
|
|
230
|
+
response.raise_for_status()
|
|
231
|
+
return response
|
|
232
|
+
|
|
233
|
+
def delete_node(self, node_id: int) -> None:
|
|
234
|
+
"""Delete a node and its underlying nodes.
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
node_id (int): ID of the layer to delete
|
|
238
|
+
|
|
239
|
+
Raises:
|
|
240
|
+
requests.exceptions.RequestException: If the API request fails
|
|
241
|
+
ValueError: If layer_id is not an integer
|
|
242
|
+
"""
|
|
243
|
+
if not isinstance(node_id, int):
|
|
244
|
+
raise ValueError("node_id must be an integer")
|
|
245
|
+
|
|
246
|
+
response = self._brynq.brynq_session.delete(
|
|
247
|
+
f"{self._brynq.url}organization-chart/nodes/{node_id}",
|
|
248
|
+
timeout=self._brynq.timeout
|
|
249
|
+
)
|
|
250
|
+
response.raise_for_status()
|
|
251
|
+
return response
|