anatools 6.0.0__py3-none-any.whl → 6.0.1__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.
- anatools/__init__.py +1 -1
- anatools/anaclient/api/api.py +5 -1
- anatools/anaclient/api/datasets.py +21 -3
- anatools/anaclient/datasets.py +61 -1
- anatools/annotations/annotations.py +39 -18
- anatools/annotations/draw.py +34 -18
- {anatools-6.0.0.data → anatools-6.0.1.data}/scripts/anadeploy +2 -0
- {anatools-6.0.0.data → anatools-6.0.1.data}/scripts/renderedai +1174 -9
- {anatools-6.0.0.dist-info → anatools-6.0.1.dist-info}/METADATA +1 -1
- {anatools-6.0.0.dist-info → anatools-6.0.1.dist-info}/RECORD +21 -21
- {anatools-6.0.0.dist-info → anatools-6.0.1.dist-info}/WHEEL +1 -1
- {anatools-6.0.0.data → anatools-6.0.1.data}/scripts/ana +0 -0
- {anatools-6.0.0.data → anatools-6.0.1.data}/scripts/anamount +0 -0
- {anatools-6.0.0.data → anatools-6.0.1.data}/scripts/anaprofile +0 -0
- {anatools-6.0.0.data → anatools-6.0.1.data}/scripts/anarules +0 -0
- {anatools-6.0.0.data → anatools-6.0.1.data}/scripts/anaserver +0 -0
- {anatools-6.0.0.data → anatools-6.0.1.data}/scripts/anatransfer +0 -0
- {anatools-6.0.0.data → anatools-6.0.1.data}/scripts/anautils +0 -0
- {anatools-6.0.0.dist-info → anatools-6.0.1.dist-info}/entry_points.txt +0 -0
- {anatools-6.0.0.dist-info → anatools-6.0.1.dist-info}/licenses/LICENSE +0 -0
- {anatools-6.0.0.dist-info → anatools-6.0.1.dist-info}/top_level.txt +0 -0
anatools/__init__.py
CHANGED
anatools/anaclient/api/api.py
CHANGED
|
@@ -117,8 +117,12 @@ class api:
|
|
|
117
117
|
responsedata = response.json()
|
|
118
118
|
if self.verbose == 'debug': print(responsedata)
|
|
119
119
|
try:
|
|
120
|
+
# Check for errors FIRST, even if data exists (partial response scenario in GraphQL)
|
|
121
|
+
# This ensures errors like "The Datasets limit has been reached by this workspace"
|
|
122
|
+
# are properly raised instead of being silently ignored when data is also present
|
|
123
|
+
if 'errors' in responsedata and responsedata['errors']:
|
|
124
|
+
raise Exception(responsedata['errors'][-1]['message'])
|
|
120
125
|
if 'data' in responsedata and responsedata['data'] is not None and call in responsedata['data']: return responsedata['data'][call]
|
|
121
|
-
elif 'errors' in responsedata: raise Exception(responsedata['errors'][-1]['message'])
|
|
122
126
|
else: raise Exception()
|
|
123
127
|
except Exception as e:
|
|
124
128
|
raise Exception(f'There was an issue with the {call} API call: {e}')
|
|
@@ -118,21 +118,39 @@ def editDataset(self, workspaceId, datasetId, name=None, description=None, pause
|
|
|
118
118
|
|
|
119
119
|
def downloadDataset(self, workspaceId, datasetId):
|
|
120
120
|
response = self.session.post(
|
|
121
|
-
url = self.url,
|
|
122
|
-
headers = self.headers,
|
|
121
|
+
url = self.url,
|
|
122
|
+
headers = self.headers,
|
|
123
123
|
json = {
|
|
124
124
|
"operationName": "downloadDataset",
|
|
125
125
|
"variables": {
|
|
126
126
|
"workspaceId": workspaceId,
|
|
127
127
|
"datasetId": datasetId
|
|
128
128
|
},
|
|
129
|
-
"query": """mutation
|
|
129
|
+
"query": """mutation
|
|
130
130
|
downloadDataset($workspaceId: String!, $datasetId: String!) {
|
|
131
131
|
downloadDataset(workspaceId: $workspaceId, datasetId: $datasetId)
|
|
132
132
|
}"""})
|
|
133
133
|
return self.errorhandler(response, "downloadDataset")
|
|
134
134
|
|
|
135
135
|
|
|
136
|
+
def downloadDatasetFile(self, workspaceId, datasetId, filepath):
|
|
137
|
+
response = self.session.post(
|
|
138
|
+
url = self.url,
|
|
139
|
+
headers = self.headers,
|
|
140
|
+
json = {
|
|
141
|
+
"operationName": "downloadDatasetFile",
|
|
142
|
+
"variables": {
|
|
143
|
+
"workspaceId": workspaceId,
|
|
144
|
+
"datasetId": datasetId,
|
|
145
|
+
"filepath": filepath
|
|
146
|
+
},
|
|
147
|
+
"query": """mutation
|
|
148
|
+
downloadDatasetFile($workspaceId: String!, $datasetId: String!, $filepath: String!) {
|
|
149
|
+
downloadDatasetFile(workspaceId: $workspaceId, datasetId: $datasetId, filepath: $filepath)
|
|
150
|
+
}"""})
|
|
151
|
+
return self.errorhandler(response, "downloadDatasetFile")
|
|
152
|
+
|
|
153
|
+
|
|
136
154
|
def cancelDataset(self, workspaceId, datasetId):
|
|
137
155
|
response = self.session.post(
|
|
138
156
|
url = self.url,
|
anatools/anaclient/datasets.py
CHANGED
|
@@ -219,7 +219,67 @@ def download_dataset(self, datasetId, workspaceId=None, localDir=None):
|
|
|
219
219
|
raise Exception(f"Dataset '{dataset_name}' is not available for download (status: {dataset_status}). The dataset may still be processing or may have failed.")
|
|
220
220
|
|
|
221
221
|
fname = dataset_name + '.zip'
|
|
222
|
-
return download_file(url=url, fname=fname, localDir=localDir)
|
|
222
|
+
return download_file(url=url, fname=fname, localDir=localDir)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def download_dataset_file(self, datasetId, filepath, workspaceId=None, localDir=None):
|
|
226
|
+
"""Download a single file from a dataset.
|
|
227
|
+
|
|
228
|
+
This allows downloading individual files from a dataset rather than
|
|
229
|
+
downloading the entire dataset archive. Use get_dataset_files() to
|
|
230
|
+
list available files in a dataset.
|
|
231
|
+
|
|
232
|
+
Parameters
|
|
233
|
+
----------
|
|
234
|
+
datasetId : str
|
|
235
|
+
Dataset ID of the dataset containing the file.
|
|
236
|
+
filepath : str
|
|
237
|
+
Relative path to the file within the dataset (e.g., "images/000000-1-image.png").
|
|
238
|
+
workspaceId : str
|
|
239
|
+
Workspace ID that the dataset is in. If none is provided, the default workspace will get used.
|
|
240
|
+
localDir : str
|
|
241
|
+
Path for where to download the file. If none is provided, current working directory will be used.
|
|
242
|
+
|
|
243
|
+
Returns
|
|
244
|
+
-------
|
|
245
|
+
str
|
|
246
|
+
Returns the path the file was downloaded to.
|
|
247
|
+
|
|
248
|
+
Raises
|
|
249
|
+
------
|
|
250
|
+
ValueError
|
|
251
|
+
If datasetId or filepath is not provided.
|
|
252
|
+
Exception
|
|
253
|
+
If the file cannot be downloaded (e.g., not found).
|
|
254
|
+
|
|
255
|
+
Examples
|
|
256
|
+
--------
|
|
257
|
+
>>> # First, list available files
|
|
258
|
+
>>> files = ana.get_dataset_files(datasetId='abc123', path='images')
|
|
259
|
+
>>> print(files)
|
|
260
|
+
['000000-1-image.png', '000001-1-image.png', ...]
|
|
261
|
+
>>>
|
|
262
|
+
>>> # Then download a specific file
|
|
263
|
+
>>> path = ana.download_dataset_file(datasetId='abc123', filepath='images/000000-1-image.png')
|
|
264
|
+
>>> print(path)
|
|
265
|
+
'/home/user/000000-1-image.png'
|
|
266
|
+
"""
|
|
267
|
+
import os
|
|
268
|
+
from anatools.lib.download import download_file
|
|
269
|
+
|
|
270
|
+
self.check_logout()
|
|
271
|
+
if datasetId is None: raise ValueError("The datasetId parameter is required!")
|
|
272
|
+
if filepath is None or filepath.strip() == '': raise ValueError("The filepath parameter is required!")
|
|
273
|
+
if workspaceId is None: workspaceId = self.workspace
|
|
274
|
+
|
|
275
|
+
url = self.ana_api.downloadDatasetFile(workspaceId=workspaceId, datasetId=datasetId, filepath=filepath)
|
|
276
|
+
|
|
277
|
+
if url is None:
|
|
278
|
+
raise Exception(f"File '{filepath}' not found in dataset '{datasetId}'.")
|
|
279
|
+
|
|
280
|
+
# Extract the filename from the filepath
|
|
281
|
+
fname = os.path.basename(filepath)
|
|
282
|
+
return download_file(url=url, fname=fname, localDir=localDir)
|
|
223
283
|
|
|
224
284
|
|
|
225
285
|
def cancel_dataset(self, datasetId, workspaceId=None):
|
|
@@ -14,15 +14,15 @@ class annotations:
|
|
|
14
14
|
Examples of mapfiles are in the example channel at /ana/channels/example/mapfiles/.
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
|
-
def bounding_box_2d(self, image_path, out_dir, object_ids=None, object_types=None, line_thickness=1, colors=None):
|
|
17
|
+
def bounding_box_2d(self, image_path, out_dir, object_ids=None, object_types=None, line_thickness=1, colors=None, quiet=False):
|
|
18
18
|
"""
|
|
19
|
-
Generates images annotated with 2d bounding boxes for datasets downloaded from the Platform. Optional filter on
|
|
19
|
+
Generates images annotated with 2d bounding boxes for datasets downloaded from the Platform. Optional filter on
|
|
20
20
|
object_ids or object_types (must choose a single filter).
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
Parameters
|
|
23
23
|
----------
|
|
24
24
|
image_path : str
|
|
25
|
-
Path to of specific image file to draw the boxes for.
|
|
25
|
+
Path to of specific image file to draw the boxes for.
|
|
26
26
|
out_dir : str
|
|
27
27
|
File path to directory where the image should be saved to.
|
|
28
28
|
object_ids : list[int]
|
|
@@ -30,22 +30,29 @@ class annotations:
|
|
|
30
30
|
object_types: list[str]
|
|
31
31
|
Filter for the object types to annotate. If not provided, all object types will get annotated. Choose either id or type filter.
|
|
32
32
|
line_thickness: int
|
|
33
|
-
Desired line thickness for box outline.
|
|
34
|
-
|
|
33
|
+
Desired line thickness for box outline.
|
|
34
|
+
colors: dict
|
|
35
35
|
Dictionary of colors to use for each object type where each color is a tuple of 3 integers (R, G, B). For example: colors={'Car': (255, 0, 0)}
|
|
36
|
+
quiet: bool
|
|
37
|
+
If True, suppress print output. Useful for CLI/automation.
|
|
38
|
+
|
|
39
|
+
Returns
|
|
40
|
+
-------
|
|
41
|
+
str or None
|
|
42
|
+
Path to the saved annotated image, or None if an error occurred.
|
|
36
43
|
"""
|
|
37
|
-
draw(image_path, out_dir, draw_type='box_2d', object_ids=object_ids, object_types=object_types, line_thickness=line_thickness, colors=colors)
|
|
44
|
+
return draw(image_path, out_dir, draw_type='box_2d', object_ids=object_ids, object_types=object_types, line_thickness=line_thickness, colors=colors, quiet=quiet)
|
|
38
45
|
|
|
39
46
|
|
|
40
|
-
def bounding_box_3d(self, image_path, out_dir, object_ids=None, object_types=None, line_thickness=1, colors=None):
|
|
47
|
+
def bounding_box_3d(self, image_path, out_dir, object_ids=None, object_types=None, line_thickness=1, colors=None, quiet=False):
|
|
41
48
|
"""
|
|
42
|
-
Generates images annotated with 3d bounding boxes for datasets downloaded from the Platform. Optional filter on
|
|
49
|
+
Generates images annotated with 3d bounding boxes for datasets downloaded from the Platform. Optional filter on
|
|
43
50
|
object_ids or object_types (must choose a single filter).
|
|
44
|
-
|
|
51
|
+
|
|
45
52
|
Parameters
|
|
46
53
|
----------
|
|
47
54
|
image_path : str
|
|
48
|
-
Path to of specific image file to draw the boxes for.
|
|
55
|
+
Path to of specific image file to draw the boxes for.
|
|
49
56
|
out_dir : str
|
|
50
57
|
File path to directory where the image should be saved to.
|
|
51
58
|
object_ids : list[int]
|
|
@@ -53,22 +60,29 @@ class annotations:
|
|
|
53
60
|
object_types: list[str]
|
|
54
61
|
Filter for the object types to annotate. If not provided, all object types will get annotated. Choose either id or type filter.
|
|
55
62
|
line_thickness: int
|
|
56
|
-
Desired line thickness for box outline.
|
|
63
|
+
Desired line thickness for box outline.
|
|
57
64
|
colors: dict
|
|
58
65
|
Dictionary of colors to use for each object type where each color is a tuple of 3 integers (R, G, B). For example: colors={'Car': (255, 0, 0)}
|
|
66
|
+
quiet: bool
|
|
67
|
+
If True, suppress print output. Useful for CLI/automation.
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
str or None
|
|
72
|
+
Path to the saved annotated image, or None if an error occurred.
|
|
59
73
|
"""
|
|
60
|
-
draw(image_path, out_dir, draw_type='box_3d', object_ids=object_ids, object_types=object_types, line_thickness=line_thickness, colors=colors)
|
|
74
|
+
return draw(image_path, out_dir, draw_type='box_3d', object_ids=object_ids, object_types=object_types, line_thickness=line_thickness, colors=colors, quiet=quiet)
|
|
61
75
|
|
|
62
76
|
|
|
63
|
-
def segmentation(self, image_path, out_dir, object_ids=None, object_types=None, line_thickness=1, colors=None):
|
|
77
|
+
def segmentation(self, image_path, out_dir, object_ids=None, object_types=None, line_thickness=1, colors=None, quiet=False):
|
|
64
78
|
"""
|
|
65
|
-
Generates images annotated with outlines around objects for datasets downloaded from the Platform. Optional filter on
|
|
79
|
+
Generates images annotated with outlines around objects for datasets downloaded from the Platform. Optional filter on
|
|
66
80
|
object_ids or object_types (must choose a single filter).
|
|
67
|
-
|
|
81
|
+
|
|
68
82
|
Parameters
|
|
69
83
|
----------
|
|
70
84
|
image_path : str
|
|
71
|
-
Path to of specific image file to draw the boxes for.
|
|
85
|
+
Path to of specific image file to draw the boxes for.
|
|
72
86
|
out_dir : str
|
|
73
87
|
File path to directory where the image should be saved to.
|
|
74
88
|
object_ids : list[int]
|
|
@@ -79,8 +93,15 @@ class annotations:
|
|
|
79
93
|
Desired line thickness for object segmentation outline.
|
|
80
94
|
colors: dict
|
|
81
95
|
Dictionary of colors to use for each object type where each color is a tuple of 3 integers (R, G, B). For example: colors={'Car': (255, 0, 0)}
|
|
96
|
+
quiet: bool
|
|
97
|
+
If True, suppress print output. Useful for CLI/automation.
|
|
98
|
+
|
|
99
|
+
Returns
|
|
100
|
+
-------
|
|
101
|
+
str or None
|
|
102
|
+
Path to the saved annotated image, or None if an error occurred.
|
|
82
103
|
"""
|
|
83
|
-
draw(image_path, out_dir, draw_type='segmentation', object_ids=object_ids, object_types=object_types, line_thickness=line_thickness, colors=colors)
|
|
104
|
+
return draw(image_path, out_dir, draw_type='segmentation', object_ids=object_ids, object_types=object_types, line_thickness=line_thickness, colors=colors, quiet=quiet)
|
|
84
105
|
|
|
85
106
|
|
|
86
107
|
def dump_classification(self, datadir, outdir, mapfile=None):
|
anatools/annotations/draw.py
CHANGED
|
@@ -4,14 +4,14 @@ import json
|
|
|
4
4
|
import os
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def draw(image_path, out_dir, draw_type='box_2d', object_ids=None, object_types=None, line_thickness=1, colors=None):
|
|
7
|
+
def draw(image_path, out_dir, draw_type='box_2d', object_ids=None, object_types=None, line_thickness=1, colors=None, quiet=False):
|
|
8
8
|
"""
|
|
9
9
|
This function handles the io and draws the right type of annotation on the image.
|
|
10
10
|
|
|
11
11
|
Parameters
|
|
12
12
|
----------
|
|
13
13
|
image_path : str
|
|
14
|
-
Path to of specific image file to draw the boxes for.
|
|
14
|
+
Path to of specific image file to draw the boxes for.
|
|
15
15
|
out_dir : str
|
|
16
16
|
File path to directory where the image should be saved to.
|
|
17
17
|
draw_type : str
|
|
@@ -24,15 +24,24 @@ def draw(image_path, out_dir, draw_type='box_2d', object_ids=None, object_types=
|
|
|
24
24
|
Desired line thickness for box outline.
|
|
25
25
|
colors: dict
|
|
26
26
|
Dictionary of colors to use for each object type. Must provide a color for each object type specified in the filter.
|
|
27
|
+
quiet: bool
|
|
28
|
+
If True, suppress print output. Useful for CLI/automation.
|
|
29
|
+
|
|
30
|
+
Returns
|
|
31
|
+
-------
|
|
32
|
+
str or None
|
|
33
|
+
Path to the saved annotated image, or None if an error occurred.
|
|
27
34
|
"""
|
|
28
35
|
|
|
29
36
|
if not os.path.exists(image_path):
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
if not quiet:
|
|
38
|
+
print('Incorrect path to images: ' + image_path)
|
|
39
|
+
return None
|
|
32
40
|
|
|
33
41
|
if object_types and object_ids:
|
|
34
|
-
|
|
35
|
-
|
|
42
|
+
if not quiet:
|
|
43
|
+
print('Provide either object_types OR object_ids. ')
|
|
44
|
+
return None
|
|
36
45
|
|
|
37
46
|
if not os.path.exists(out_dir):
|
|
38
47
|
os.makedirs(out_dir)
|
|
@@ -47,8 +56,8 @@ def draw(image_path, out_dir, draw_type='box_2d', object_ids=None, object_types=
|
|
|
47
56
|
file.close()
|
|
48
57
|
|
|
49
58
|
annotation_ids = [data['id'] for data in annotations['annotations']]
|
|
50
|
-
if object_ids is not None and not check_lists(annotation_ids, object_ids, 'object_ids'):
|
|
51
|
-
return
|
|
59
|
+
if object_ids is not None and not check_lists(annotation_ids, object_ids, 'object_ids', quiet=quiet):
|
|
60
|
+
return None
|
|
52
61
|
|
|
53
62
|
|
|
54
63
|
metadata_file = root_dir+'/metadata/'+image_name+'-metadata.json'
|
|
@@ -62,8 +71,8 @@ def draw(image_path, out_dir, draw_type='box_2d', object_ids=None, object_types=
|
|
|
62
71
|
if object_ids:
|
|
63
72
|
object_data = [data for data in metadata['objects'] if data['id'] in object_ids]
|
|
64
73
|
elif object_types is not None:
|
|
65
|
-
if not check_lists(metadata_types, object_types, 'object_types'):
|
|
66
|
-
return
|
|
74
|
+
if not check_lists(metadata_types, object_types, 'object_types', quiet=quiet):
|
|
75
|
+
return None
|
|
67
76
|
object_data = [data for data in metadata['objects'] if data['type'] in object_types]
|
|
68
77
|
else:
|
|
69
78
|
object_data = [data for data in metadata['objects']]
|
|
@@ -74,14 +83,15 @@ def draw(image_path, out_dir, draw_type='box_2d', object_ids=None, object_types=
|
|
|
74
83
|
generate_color = [int(val) for val in np.random.randint(0, 255, 3)]
|
|
75
84
|
type_colors[type] = tuple(generate_color)
|
|
76
85
|
else: type_colors = colors
|
|
77
|
-
|
|
86
|
+
|
|
78
87
|
|
|
79
88
|
draw_img = Image.open(image_path)
|
|
80
89
|
for object in annotations['annotations']:
|
|
81
90
|
if any(object['id'] == d['id'] for d in object_data):
|
|
82
91
|
color_info = [data for data in object_data if object['id'] == data['id']]
|
|
83
92
|
if color_info[0]['type'] not in type_colors:
|
|
84
|
-
|
|
93
|
+
if not quiet:
|
|
94
|
+
print(f'Color for {color_info[0]["type"]} not found in colors dictionary. Skipping object.')
|
|
85
95
|
continue
|
|
86
96
|
if draw_type == 'box_2d':
|
|
87
97
|
draw_img = box_2d(object['bbox'], draw_img, line_thickness, type_colors[color_info[0]['type']])
|
|
@@ -90,11 +100,14 @@ def draw(image_path, out_dir, draw_type='box_2d', object_ids=None, object_types=
|
|
|
90
100
|
elif draw_type == 'segmentation':
|
|
91
101
|
draw_img = segmentation(object['segmentation'], draw_img, line_thickness, type_colors[color_info[0]['type']])
|
|
92
102
|
else:
|
|
93
|
-
|
|
103
|
+
if not quiet:
|
|
104
|
+
print('Provide either box_2d, box_3d, or segmentation')
|
|
94
105
|
|
|
95
106
|
outimg = out_dir+'/'+image_name+'-annotated-'+draw_type+'.'+image_ext
|
|
96
107
|
draw_img.save(outimg)
|
|
97
|
-
|
|
108
|
+
if not quiet:
|
|
109
|
+
print(f'Image saved to {outimg}')
|
|
110
|
+
return outimg
|
|
98
111
|
|
|
99
112
|
|
|
100
113
|
def box_2d(coordinates, bbox_img, width, outline):
|
|
@@ -193,7 +206,7 @@ def segmentation(coordinates, draw_img, width, color):
|
|
|
193
206
|
return draw_img
|
|
194
207
|
|
|
195
208
|
|
|
196
|
-
def check_lists(actual, expected, name_to_check):
|
|
209
|
+
def check_lists(actual, expected, name_to_check, quiet=False):
|
|
197
210
|
"""
|
|
198
211
|
Helper function that checks if one list is in another for validation on draw inputs.
|
|
199
212
|
|
|
@@ -205,16 +218,19 @@ def check_lists(actual, expected, name_to_check):
|
|
|
205
218
|
The expected list that is provided from the user.
|
|
206
219
|
name_to_check: str
|
|
207
220
|
Name of parameter to check (either object_id or object_type).
|
|
221
|
+
quiet: bool
|
|
222
|
+
If True, suppress print output.
|
|
208
223
|
|
|
209
224
|
Returns
|
|
210
225
|
-------
|
|
211
226
|
bool
|
|
212
227
|
True if lists are matching, False otherwise.
|
|
213
228
|
"""
|
|
214
|
-
|
|
229
|
+
|
|
215
230
|
if not set(expected).issubset(set(actual)):
|
|
216
231
|
out_of_bounds_check= list(set(expected) - set(actual))
|
|
217
|
-
|
|
218
|
-
|
|
232
|
+
if not quiet:
|
|
233
|
+
print(f'Provided {name_to_check} list has the following out of bounds: {out_of_bounds_check}. Please rerun with valid list. \nHere are all the {name_to_check} that can get annotated: ')
|
|
234
|
+
print(list(set(actual)))
|
|
219
235
|
return False
|
|
220
236
|
return True
|
|
@@ -347,6 +347,7 @@ try:
|
|
|
347
347
|
if channels == False or len(channels) == 0: raise Exception(f"Channel {args.channelId} not found")
|
|
348
348
|
remotechannel = channels[0]
|
|
349
349
|
starttime = time.time()
|
|
350
|
+
client.interactive = True
|
|
350
351
|
deploymentId = client.deploy_channel(channelId=remotechannel['channelId'], channelfile=args.channel)
|
|
351
352
|
print('Registering Channel Image...', flush=True)
|
|
352
353
|
registerstart = time.time()
|
|
@@ -512,6 +513,7 @@ try:
|
|
|
512
513
|
client.edit_service(serviceId=remoteservice['serviceId'], volumes=volumes)
|
|
513
514
|
remoteservice = client.get_services(serviceId=remoteservice['serviceId'])[0]
|
|
514
515
|
starttime = time.time()
|
|
516
|
+
client.interactive = True
|
|
515
517
|
deploymentId = client.deploy_service(serviceId=remoteservice['serviceId'], servicefile=args.service)
|
|
516
518
|
print('Registering Service Image...', flush=True)
|
|
517
519
|
registerstart = time.time()
|