Skip to content

Commit 69e74b7

Browse files
authored
Merge pull request #87 from keboola/feature/CFT-3500-new-workspaces
Refs/heads/feature/cft 3500 new workspaces
2 parents c67dd40 + 22080b5 commit 69e74b7

4 files changed

Lines changed: 71 additions & 19 deletions

File tree

.github/workflows/push.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ jobs:
4949
echo "is_semantic_tag=$IS_SEMANTIC_TAG" >> $GITHUB_OUTPUT
5050
5151
- name: Upload image
52-
uses: ishworkh/docker-image-artifact-upload@v1
52+
uses: ishworkh/container-image-artifact-upload@v2.0.0
5353
with:
54-
image: "sapi-python-client"
54+
image: ${{ env.APP_IMAGE }}
5555
retention_days: "1"
5656

5757
tests_aws:
@@ -63,9 +63,9 @@ jobs:
6363
uses: actions/checkout@v3
6464

6565
- name: Download image
66-
uses: ishworkh/docker-image-artifact-download@v1
66+
uses: ishworkh/container-image-artifact-download@v2.0.0
6767
with:
68-
image: "sapi-python-client"
68+
image: ${{ env.APP_IMAGE }}
6969

7070
- name: Run Tests
7171
run: |
@@ -80,9 +80,9 @@ jobs:
8080
uses: actions/checkout@v3
8181

8282
- name: Download image
83-
uses: ishworkh/docker-image-artifact-download@v1
83+
uses: ishworkh/container-image-artifact-download@v2.0.0
8484
with:
85-
image: "sapi-python-client"
85+
image: ${{ env.APP_IMAGE }}
8686

8787
- name: Run Tests
8888
run: |
@@ -97,9 +97,9 @@ jobs:
9797
uses: actions/checkout@v3
9898

9999
- name: Download image
100-
uses: ishworkh/docker-image-artifact-download@v1
100+
uses: ishworkh/container-image-artifact-download@v2.0.0
101101
with:
102-
image: "sapi-python-client"
102+
image: ${{ env.APP_IMAGE }}
103103

104104
- name: Run Tests
105105
run: |

kbcstorage/branches.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,14 @@ def metadata(self, branch_id="default"):
4141

4242
url = f"{self.base_url}branch/{branch_id}/metadata"
4343
return self._get(url)
44+
45+
def branch_detail(self, branch_id="default"):
46+
"""
47+
Get branch details
48+
"""
49+
50+
if not isinstance(branch_id, str) or branch_id == "":
51+
raise ValueError(f"Invalid branch_id '{branch_id}'")
52+
53+
url = f"{self.base_url}dev-branches/{branch_id}"
54+
return self._get(url)

kbcstorage/configurations.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ def list(self, component_id):
7979
url = '{}/{}/configs'.format(self.base_url, component_id)
8080
return self._get(url)
8181

82+
def list_config_workspaces(self, component_id, config_id):
83+
"""
84+
Lists workspaces for component configuration.
85+
86+
Args:
87+
component_id (str): The id of the component.
88+
config_id (str): The id of the configuration.
89+
90+
Raises:
91+
requests.HTTPError: If the API request fails.
92+
"""
93+
if not isinstance(component_id, str) or component_id == '':
94+
raise ValueError("Invalid component_id '{}'.".format(component_id))
95+
url = f'{self.base_url}/{component_id}/configs/{config_id}/workspaces'
96+
return self._get(url)
97+
8298
def create(self, component_id, name, description='', configuration=None, state=None, change_description='',
8399
is_disabled=False, configuration_id=None):
84100
"""

kbcstorage/workspaces.py

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
from kbcstorage.base import Endpoint
1010
from kbcstorage.files import Files
1111
from kbcstorage.jobs import Jobs
12+
from typing import List # the legacy Workspaces class below unfortunately defines its own method called list
1213

1314

14-
def _make_body(mapping, source_key='source'):
15+
def _make_body(mapping, source_key='source', preserve: bool = True):
1516
"""
1617
Given a dict mapping Keboola tables to aliases, construct the body of
1718
the HTTP request to load said tables.
@@ -21,7 +22,7 @@ def _make_body(mapping, source_key='source'):
2122
be loaded (ie. 'in.c-bucker.table_name') and values contain the
2223
aliases to which they will be loaded (ie. 'table_name').
2324
"""
24-
body = {}
25+
body = {'preserve': str(preserve).lower()}
2526
template = 'input[{0}][{1}]'
2627
for i, (k, v) in enumerate(mapping.items()):
2728
body[template.format(i, source_key)] = k
@@ -72,7 +73,7 @@ def detail(self, workspace_id):
7273
url = '{}/{}'.format(self.base_url, workspace_id)
7374
return self._get(url)
7475

75-
def create(self, backend=None, timeout=None):
76+
def create(self, backend=None, timeout=None, login_type=None, public_key=None, read_all_objects=False):
7677
"""
7778
Create a new Workspace and return the credentials.
7879
@@ -87,7 +88,10 @@ def create(self, backend=None, timeout=None):
8788
"""
8889
body = {
8990
'backend': backend,
90-
'statementTimeoutSeconds': timeout
91+
'statementTimeoutSeconds': timeout,
92+
'loginType': login_type,
93+
'publicKey': public_key,
94+
'readOnlyStorageAccess': str(read_all_objects).lower() # convert bool to lowercase true or false
9195
}
9296

9397
return self._post(self.base_url, data=body)
@@ -122,29 +126,50 @@ def reset_password(self, workspace_id):
122126
url = '{}/{}/password'.format(self.base_url, workspace_id)
123127
return self._post(url)
124128

125-
def load_tables(self, workspace_id, table_mapping, preserve=None):
129+
def set_public_key(self, workspace_id, public_key):
130+
"""
131+
Set the public key for the workspace.
132+
"""
133+
data = {
134+
'publicKey': public_key
135+
}
136+
url = '{}/{}/public-key'.format(self.base_url, workspace_id)
137+
return self._post(url, json=data)
138+
139+
def load_tables(self, workspace_id: int | str, table_mapping: dict | List[dict], preserve=True, load_type='load'):
126140
"""
127141
Load tabes from storage into a workspace.
128142
129143
Args:
130144
workspace_id (int or str): The id of the workspace to which to load
131145
the tables.
132-
table_mapping (:obj:`dict`): Source table names mapped to
133-
destination table names.
146+
table_mapping (:obj:`dict` or :obj:`list`): Source table names mapped to
147+
destination table names. or a list of dicts with detailed tables specification.
134148
preserve (bool): If False, drop tables, else keep tables in
135149
workspace.
150+
load_type (str): Type of load, either 'load' or 'load-clone'. Defaults to 'load'.
136151
137152
Raises:
138153
requests.HTTPError: If the API request fails.
139154
140155
Todo:
141156
* Column data types.
142157
"""
143-
body = _make_body(table_mapping)
144-
body['preserve'] = preserve
145-
url = '{}/{}/load'.format(self.base_url, workspace_id)
158+
load_type = load_type.lower()
159+
if load_type not in ['load', 'load-clone']:
160+
raise ValueError("Invalid load_type: {}, supports only load and load-clone".format(load_type))
161+
162+
url = "/".join([self.base_url, str(workspace_id), load_type])
163+
164+
req = None
165+
if isinstance(table_mapping, dict):
166+
body = _make_body(table_mapping, preserve=preserve)
167+
req = self._post(url, data=body)
168+
elif isinstance(table_mapping, list):
169+
body = {'input': table_mapping, 'preserve': str(preserve).lower()}
170+
req = self._post(url, json=body)
146171

147-
return self._post(url, data=body)
172+
return req
148173

149174
def load_files(self, workspace_id, file_mapping):
150175
"""

0 commit comments

Comments
 (0)