├── .gitignore ├── README.md ├── example.py └── genieacs.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | *.pyc 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python-genieacs 2 | 3 | A Python API to interact with the [GenieACS](https://github.com/zaidka/genieacs) [REST API](https://github.com/zaidka/genieacs/wiki/API-Reference), but with the easiness and comfort of Python. 4 | 5 | ### Requirements 6 | 7 | * Python 2 or 3 8 | * [Requests](http://python-requests.org/) 9 | 10 | ### Usage 11 | 12 | Take a look at *example.py*. 13 | 14 | ### License 15 | 16 | This software is released under the terms of the 17 | GNU General Public License v2: 18 | 19 | [http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt](http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt) 20 | 21 | ### Todos 22 | 23 | * high level abstracting methods for comfortable usage of the API 24 | * user-definable error/exception handling (stop on error or warn and continue) 25 | * setup.py 26 | 27 | The following list contains all possible interactions with the GenieACS REST API. Interactions already implemented are enclosed in brackets. 28 | 29 | #### Query GenieACS database: 30 | 31 | * (list IDs of all devices) 32 | * (search for devices:) 33 | * (by ID) 34 | * (by MAC) 35 | * (list parameters for a given device) 36 | 37 | #### Manage devices: 38 | 39 | * (delete a given device from the database) 40 | 41 | #### Manage tasks: 42 | 43 | * (list all tasks) 44 | * (filtered by device) 45 | * (create a task for a given device) 46 | * (refreshObject) 47 | * (setParameterValues) 48 | * (getParameterValues) 49 | * (addObject) 50 | * (reboot) 51 | * (factoryReset) 52 | * (download) 53 | * (retry a faulty task at the next inform) 54 | * (delete a given task) 55 | 56 | #### Manage tags: 57 | 58 | * (list tags filtered by device) 59 | * (assign a tag to a device) 60 | * (remove a tag from a device) 61 | 62 | #### Manage presets: 63 | 64 | * (list all presets) 65 | * (write all presets to a file) 66 | * (create or update a preset) 67 | * (create all presets from a file) 68 | * (delete a preset) 69 | 70 | #### Manage objects: 71 | 72 | * (list all objects) 73 | * (write all objects to a file) 74 | * (create or update an object) 75 | * (create all objects from a file) 76 | * (delete an object) 77 | 78 | #### Manage provisions: 79 | 80 | * (list all provisions) 81 | * (write all provisions to a file) 82 | * (create or update a provision) 83 | * (create all provisions from a file) 84 | * (delete a provision) 85 | 86 | #### Manage files: 87 | 88 | * (list all files) 89 | * (list data of one or more specific files) 90 | * (upload or overwrite a file) 91 | * (delete an uploaded file) 92 | 93 | #### Manage faults: 94 | 95 | * (list IDs of all faults) 96 | * (list all faults) 97 | * (filtered by device) 98 | * (delete a given fault) 99 | -------------------------------------------------------------------------------- /example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Usage examples for python-genieacs 5 | 6 | import genieacs 7 | 8 | # set a device_id for the following methods 9 | device_id = "000149-c1500-000149014AF8" 10 | 11 | # Create a Connection object to interact with a GenieACS server 12 | acs = genieacs.Connection("tr069.tdt.de", ssl=True, auth=True, user="tdt", passwd="tdt") 13 | 14 | # refresh some device parameters 15 | acs.task_refresh_object(device_id, "InternetGatewayDevice.DeviceInfo.") 16 | # set a device parameter 17 | acs.task_set_parameter_values(device_id, [["InternetGatewayDevice.BackupConfiguration.FileList", "backup.cfg"]]) 18 | # get a device parameter 19 | acs.task_get_parameter_values(device_id, [["InternetGatewayDevice.BackupConfiguration.FileList"]]) 20 | # factory reset a device 21 | acs.task_factory_reset(device_id) 22 | # reboot a device 23 | acs.task_reboot(device_id) 24 | # add an object to a device 25 | acs.task_add_object(device_id, "VPNObject", [["InternetGatewayDevice.X_TDT-DE_OpenVPN"]]) 26 | # download a file 27 | acs.task_download(device_id, "9823de165bb983f24f782951", "Firmware.img") 28 | # retry a faulty task 29 | acs.task_retry("9h4769svl789kjf984ll") 30 | 31 | 32 | # print all tasks of a given device 33 | print(acs.task_get_all(device_id)) 34 | # print IDs of all devices 35 | print(acs.device_get_all_IDs()) 36 | # search a device by its ID and print all corresponding data 37 | print(acs.device_get_by_id(device_id)) 38 | # search a device by its MAC address and print all corresponding data 39 | print(acs.device_get_by_MAC("00:01:49:ff:0f:01")) 40 | # print the value of a given parameter of a given device 41 | print(acs.device_get_parameter(device_id, "InternetGatewayDevice.DeviceInfo.SoftwareVersion")) 42 | # print 2 given parameters of a given device 43 | print(acs.device_get_parameters(device_id, "InternetGatewayDevice.DeviceInfo.SoftwareVersion,InternetGatewayDevice.X_TDT-DE_Interface.2.ProtoStatic.Ipv4.Address")) 44 | # delete a task 45 | acs.task_delete("9h4769svl789kjf984ll") 46 | 47 | # create a new preset 48 | acs.preset_create("Tagging", r'{ "weight": 0, "precondition": "{\"_tags\":{\"$ne\":\"tagged\"}}", "configurations": [ { "type": "add_tag", "tag":"tagged" }] }') 49 | # write all existing presets to a file and store them in a json object 50 | preset_data = acs.preset_get_all('presets.json') 51 | # delete all presets 52 | for preset in preset_data: 53 | acs.preset_delete(preset["_id"]) 54 | # create all presets from the file 55 | acs.preset_create_all_from_file('presets.json') 56 | 57 | # create a new object 58 | acs.object_create("CreatedObject", r'{"Param1": "Value1", "Param2": "Value2", "_keys":["Param1"]}') 59 | # write all existing objects to a file and store them in a json object 60 | object_data = acs.object_get_all('objects.json') 61 | # delete all objects 62 | for gobject in object_data: 63 | acs.object_delete(gobject["_id"]) 64 | # create all objects from the file 65 | acs.object_create_all_from_file('objects.json') 66 | 67 | # create a new provision 68 | acs.provision_create("Logging", '// This is a comment\nlog("Hello World!");') 69 | # write all existing provisions to a file and store them in a json object 70 | provision_data = acs.provision_get_all('provisions.json') 71 | # delete all provisisions 72 | for provision in provision_data: 73 | acs.provision_delete(provision["_id"]) 74 | # create all provisions from the file 75 | acs.provision_create_all_from_file('provisions.json') 76 | 77 | # print all tags of a given device 78 | print(acs.tag_get_all(device_id)) 79 | # assign a tag to a device 80 | acs.tag_assign(device_id, "tagged") 81 | # remove a tag from a device 82 | acs.tag_remove(device_id, "tagged") 83 | 84 | # print all existing files in the database 85 | print(acs.file_get_all()) 86 | # print data of a specific file 87 | print(str(acs.file_get(fileType="12 Other File", version="0.4"))) 88 | # upload a new or modified file 89 | acs.file_upload("Firmware.img", "1 Firmware Upgrade Image", "123456", "r4500", "2.0") 90 | # delete a file from the database 91 | acs.file_delete("Firmware.img") 92 | 93 | # delete the device from the database 94 | acs.device_delete(device_id) 95 | 96 | # get IDs of all existing faults and delete all 97 | faults = acs.fault_get_all_IDs() 98 | for fault in faults: 99 | acs.fault_delete(fault) 100 | -------------------------------------------------------------------------------- /genieacs.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # python-genieacs 4 | # A Python API to interact with the GenieACS REST API 5 | # https://github.com/TDT-GmbH/python-genieacs 6 | 7 | import requests 8 | import json 9 | 10 | class Connection(object): 11 | """Connection object to interact with the GenieACS server.""" 12 | def __init__(self, ip, port=7557, ssl=False, verify=False, auth=False, user="", passwd="", url="", timeout=10): 13 | self.server_ip = ip 14 | self.server_port = port 15 | self.use_ssl = ssl 16 | self.ssl_verify = verify 17 | self.use_auth = auth 18 | self.username = user 19 | self.password = passwd 20 | self.server_url = url 21 | self.timeout = timeout 22 | self.base_url = "" 23 | self.session = None 24 | self.__set_base_url() 25 | self.__create_session() 26 | 27 | def __set_base_url(self): 28 | if not self.use_ssl: 29 | self.base_url = "http://" 30 | else: 31 | self.base_url = "https://" 32 | self.base_url += self.server_ip + ":" + str(self.server_port) + self.server_url 33 | 34 | def __create_session(self): 35 | if self.session is None: 36 | self.session = requests.Session() 37 | if self.use_auth: 38 | self.session.auth = (self.username, self.password) 39 | if self.use_ssl: 40 | self.session.verify = self.ssl_verify 41 | try: 42 | # do a request to test the connection 43 | self.file_get_all() 44 | except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError): 45 | raise ConnectionError 46 | 47 | def __request_get(self, url): 48 | request_url = self.base_url + url 49 | try: 50 | r = self.session.get(request_url, timeout=self.timeout) 51 | r.raise_for_status() 52 | except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError): 53 | raise ConnectionError 54 | if r.text: 55 | data = r.json() 56 | return data 57 | 58 | def __request_post(self, url, data, conn_request=True): 59 | if conn_request: 60 | request_url = self.base_url + url + "?connection_request" 61 | else: 62 | request_url = self.base_url + url 63 | try: 64 | r = self.session.post(request_url, json=data, timeout=self.timeout) 65 | r.raise_for_status() 66 | except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError): 67 | raise ConnectionError 68 | if r.text: 69 | data = r.json() 70 | return data 71 | 72 | def __request_put(self, url, data, headers=None): 73 | request_url = self.base_url + url 74 | try: 75 | if headers is not None: 76 | r = self.session.put(request_url, data, timeout=self.timeout, headers=headers) 77 | else: 78 | r = self.session.put(request_url, data, timeout=self.timeout) 79 | r.raise_for_status() 80 | except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError): 81 | raise ConnectionError 82 | if r.text: 83 | data = r.json() 84 | return data 85 | 86 | def __request_delete(self, url): 87 | request_url = self.base_url + url 88 | try: 89 | r = self.session.delete(request_url, timeout=self.timeout) 90 | r.raise_for_status() 91 | except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError): 92 | raise ConnectionError 93 | if r.text: 94 | data = r.json() 95 | return data 96 | 97 | ##### methods for devices ##### 98 | 99 | def device_get_all_IDs(self): 100 | """Get IDs of all devices""" 101 | jsondata = self.__request_get("/devices/" + "?projection=_id") 102 | data = [] 103 | for device in jsondata: 104 | data.append(device["_id"]) 105 | return data 106 | 107 | def device_get_by_id(self, device_id): 108 | """Get all data of a device identified by its ID""" 109 | quoted_id = requests.utils.quote("{\"_id\":\"" + device_id + "\"}", safe = '') 110 | return self.__request_get("/devices/" + "?query=" + quoted_id) 111 | 112 | def device_get_by_MAC(self, device_MAC): 113 | """Get all data of a device identified by its MAC address""" 114 | quoted_MAC = requests.utils.quote("{\"summary.mac\":\"" + device_MAC + "\"}", safe = '') 115 | return self.__request_get("/devices/" + "?query=" + quoted_MAC) 116 | 117 | def device_get_by_serial(self, device_serial): 118 | """Get all data of a device identified by its Serial""" 119 | quoted_serial = requests.utils.quote("{\"InternetGatewayDevice.DeviceInfo.SerialNumber\":\"" + device_serial + "\"}", safe = '') 120 | return self.__request_get("/devices/" + "?query=" + quoted_serial) 121 | 122 | def device_get_parameter(self, device_id, parameter_name): 123 | """Directly get the value of a given parameter from a given device""" 124 | quoted_id = requests.utils.quote("{\"_id\":\"" + device_id + "\"}", safe = '') 125 | data = self.__request_get("/devices" + "?query=" + quoted_id + "&projection=" + parameter_name) 126 | try: 127 | if parameter_name in ["_tags", "_lastInform", "_registered", "_lastBootstrap", "_lastBoot"]: 128 | return data[0][parameter_name] 129 | else: 130 | value = data[0] 131 | for part in parameter_name.split('.'): 132 | value = value[part] 133 | return value["_value"] 134 | except (IndexError, KeyError): 135 | return None 136 | 137 | def device_get_parameters(self, device_id, parameter_names): 138 | """Get a defined list of parameters from a given device""" 139 | quoted_id = requests.utils.quote("{\"_id\":\"" + device_id + "\"}", safe = '') 140 | data = self.__request_get("/devices" + "?query=" + quoted_id + "&projection=" + parameter_names) 141 | try: 142 | data = data[0] 143 | values = {} 144 | src = data 145 | dest = values 146 | except (IndexError): 147 | return {} 148 | for parameter in parameter_names.split(','): 149 | parameter_parts = parameter.split('.') 150 | for part in parameter_parts: 151 | if part != parameter_parts[-1]: 152 | try: 153 | src = src[part] 154 | except (KeyError): 155 | src[part] = {} 156 | src = src[part] 157 | if part not in dest.keys(): 158 | dest[part] = {} 159 | dest = dest[part] 160 | else: 161 | try: 162 | dest[part] = src[part]["_value"] 163 | except (KeyError): 164 | dest[part] = None 165 | dest = values 166 | src = data 167 | return values 168 | 169 | def device_delete(self, device_id): 170 | """Delete a given device from the database""" 171 | self.__request_delete("/devices/" + requests.utils.quote(device_id)) 172 | 173 | ##### methods for tasks ##### 174 | 175 | def task_get_all(self, device_id=None): 176 | if device_id: 177 | """Get all existing tasks of a given device""" 178 | quoted_id = requests.utils.quote("{\"device\":\"" + device_id + "\"}", safe = '') 179 | return self.__request_get("/tasks/" + "?query=" + quoted_id) 180 | else: 181 | """Get all existing tasks""" 182 | return self.__request_get("/tasks/") 183 | 184 | def task_refresh_object(self, device_id, object_name, conn_request=True): 185 | """Create a refreshObject task for a given device""" 186 | data = { "name": "refreshObject", 187 | "objectName": object_name } 188 | try: 189 | return self.__request_post("/devices/" + requests.utils.quote(device_id) + "/tasks", data, conn_request) 190 | except requests.exceptions.HTTPError: 191 | raise ItemNotFoundError 192 | 193 | def task_set_parameter_values(self, device_id, parameter_values, conn_request=True): 194 | """Create a setParameterValues task for a given device""" 195 | data = { "name": "setParameterValues", 196 | "parameterValues": parameter_values } 197 | try: 198 | return self.__request_post("/devices/" + requests.utils.quote(device_id) + "/tasks", data, conn_request) 199 | except requests.exceptions.HTTPError: 200 | raise ItemNotFoundError 201 | 202 | def task_get_parameter_values(self, device_id, parameter_names, conn_request = True): 203 | """Create a getParameterValues task for a given device""" 204 | data = { "name": "getParameterValues", 205 | "parameterNames": parameter_names} 206 | try: 207 | return self.__request_post("/devices/" + requests.utils.quote(device_id) + "/tasks", data, conn_request) 208 | except requests.exceptions.HTTPError: 209 | raise ItemNotFoundError 210 | 211 | def task_add_object(self, device_id, object_name, object_path, conn_request=True): 212 | """Create an addObject task for a given device""" 213 | data = { "name": "addObject", object_name : object_path} 214 | try: 215 | return self.__request_post("/devices/" + requests.utils.quote(device_id) + "/tasks", data, conn_request) 216 | except requests.exceptions.HTTPError: 217 | raise ItemNotFoundError 218 | 219 | def task_reboot(self, device_id, conn_request=True): 220 | """Create a reboot task for a given device""" 221 | data = { "name": "reboot"} 222 | try: 223 | return self.__request_post("/devices/" + requests.utils.quote(device_id) + "/tasks", data, conn_request) 224 | except requests.exceptions.HTTPError: 225 | raise ItemNotFoundError 226 | 227 | def task_factory_reset(self, device_id, conn_request=True): 228 | """Create a factoryReset task for a given device""" 229 | data = { "name": "factoryReset"} 230 | try: 231 | return self.__request_post("/devices/" + requests.utils.quote(device_id) + "/tasks", data, conn_request) 232 | except requests.exceptions.HTTPError: 233 | raise ItemNotFoundError 234 | 235 | def task_download(self, device_id, file_id, filename, conn_request=True): 236 | """Create a download task for a given device""" 237 | data = { "name": "download", "file": file_id, "filename": filename} 238 | try: 239 | return self.__request_post("/devices/" + requests.utils.quote(device_id) + "/tasks", data, conn_request) 240 | except requests.exceptions.HTTPError: 241 | raise ItemNotFoundError 242 | 243 | def task_retry(self, task_id): 244 | "Retry a faulty task at the next inform" 245 | try: 246 | return self.__request_post("/tasks/" + task_id + "/retry", None) 247 | except requests.exceptions.HTTPError: 248 | raise ItemNotFoundError 249 | 250 | def task_delete(self, task_id): 251 | """Delete a Task for a given device""" 252 | try: 253 | return self.__request_delete("/tasks/" + task_id) 254 | except requests.exceptions.HTTPError: 255 | raise ItemNotFoundError 256 | 257 | ##### methods for tags ###### 258 | 259 | def tag_get_all(self, device_id): 260 | """Get all existing tags of a given device""" 261 | quoted_id = requests.utils.quote("{\"_id\":\"" + device_id + "\"}", safe = '') 262 | data = self.__request_get("/devices" + "?query=" + quoted_id + "&projection=_tags") 263 | try: 264 | return data[0]["_tags"] 265 | except (IndexError, KeyError): 266 | return [] 267 | 268 | def tag_assign(self, device_id, tag_name): 269 | """Assign a tag to a device""" 270 | try: 271 | self.__request_post("/devices/" + requests.utils.quote(device_id) + "/tags/" + tag_name, None, False) 272 | except requests.exceptions.HTTPError: 273 | raise ItemNotFoundError 274 | 275 | def tag_remove(self, device_id, tag_name): 276 | """Remove a tag from a device""" 277 | try: 278 | self.__request_delete("/devices/" + requests.utils.quote(device_id) + "/tags/" + tag_name) 279 | except requests.exceptions.HTTPError: 280 | raise ItemNotFoundError 281 | 282 | ##### methods for presets ##### 283 | 284 | def preset_get_all(self, filename=None): 285 | """Get all existing presets as a json object, optionally write them to a file""" 286 | data = self.__request_get("/presets") 287 | try: 288 | if filename is not None: 289 | f = open(filename, 'w') 290 | json.dump(data, f, indent=4, separators=(',', ': ')) 291 | f.close() 292 | except IOError as err: 293 | print("preset_get_all:\nIOError: " + str(err) + "\n") 294 | finally: 295 | return data 296 | 297 | def preset_create(self, preset_name, data): 298 | """Create a new preset or update a preset with a given name""" 299 | quoted_name = requests.utils.quote(preset_name) 300 | try: 301 | self.__request_put("/presets/" + quoted_name, data) 302 | except requests.exceptions.HTTPError: 303 | raise InvalidRequestDataError 304 | 305 | def preset_create_all_from_file(self, filename): 306 | """Create all presets contained in a json file""" 307 | try: 308 | f = open(filename, 'r') 309 | data = json.load(f) 310 | f.close() 311 | for preset in data: 312 | preset_name = requests.utils.quote(preset["_id"]) 313 | del preset["_id"] 314 | self.__request_put("/presets/" + preset_name, json.dumps(preset)) 315 | except IOError as err: 316 | print("preset_create_all_from_file:\nIOError: " + str(err) + "\n") 317 | except ValueError: 318 | print("preset_create_all_from_file:\nValueError: File contains faulty values\n") 319 | except KeyError: 320 | print("preset_create_all_from_file:\nKeyError: File contains faulty keys\n") 321 | 322 | def preset_delete(self, preset_name): 323 | """Delete a given preset""" 324 | quoted_name = requests.utils.quote(preset_name) 325 | try: 326 | self.__request_delete("/presets/" + quoted_name) 327 | except requests.exceptions.HTTPError: 328 | raise ItemNotFoundError 329 | 330 | ##### methods for objects ##### 331 | 332 | def object_get_all(self, filename=None): 333 | """Get all existing objects as a json object, optionally write them to a file""" 334 | data = self.__request_get("/objects") 335 | try: 336 | if filename is not None: 337 | f = open(filename, 'w') 338 | json.dump(data, f, indent=4, separators=(',', ': ')) 339 | f.close() 340 | except IOError as err: 341 | print("object_get_all:\nIOError: " + str(err) + "\n") 342 | finally: 343 | return data 344 | 345 | def object_create(self, object_name, data): 346 | """Create a new object or update an object with a given name""" 347 | quoted_name = requests.utils.quote(object_name) 348 | try: 349 | self.__request_put("/objects/" + quoted_name, data) 350 | except requests.exceptions.HTTPError: 351 | raise InvalidRequestDataError 352 | 353 | def object_create_all_from_file(self, filename): 354 | """Create all objects contained in a json file""" 355 | try: 356 | f = open(filename, 'r') 357 | data = json.load(f) 358 | f.close() 359 | for gobject in data: 360 | object_name = requests.utils.quote(gobject["_id"]) 361 | del gobject["_id"] 362 | self.__request_put("/objects/" + object_name, json.dumps(gobject)) 363 | except IOError as err: 364 | print("object_create_all_from_file:\nIOError: " + str(err) + "\n") 365 | except ValueError: 366 | print("object_create_all_from_file:\nValueError: File contains faulty values\n") 367 | except KeyError: 368 | print("object_create_all_from_file:\nKeyError: File contains faulty keys\n") 369 | 370 | def object_delete(self, object_name): 371 | """Delete a given object""" 372 | quoted_name = requests.utils.quote(object_name) 373 | try: 374 | self.__request_delete("/objects/" + quoted_name) 375 | except requests.exceptions.HTTPError: 376 | raise ItemNotFoundError 377 | 378 | ##### methods for provisions ##### 379 | 380 | def provision_get_all(self, filename=None): 381 | """Get all existing provisions as a json object, optionally write them to a file""" 382 | data = self.__request_get("/provisions") 383 | try: 384 | if filename is not None: 385 | f = open(filename, 'w') 386 | json.dump(data, f, indent=4, separators=(',', ': ')) 387 | f.close() 388 | except IOError as err: 389 | print("provision_get_all:\nIOError: " + str(err) + "\n") 390 | finally: 391 | return data 392 | 393 | def provision_create(self, provision_name, data): 394 | """Create a new provision or update a provision with a given name""" 395 | quoted_name = requests.utils.quote(provision_name) 396 | try: 397 | self.__request_put("/provisions/" + quoted_name, data) 398 | except requests.exceptions.HTTPError: 399 | raise InvalidRequestDataError 400 | 401 | def provision_create_all_from_file(self, filename): 402 | """Create all provisions contained in a json file""" 403 | try: 404 | f = open(filename, 'r') 405 | data = json.load(f) 406 | f.close() 407 | for provision in data: 408 | provision_name = requests.utils.quote(provision["_id"]) 409 | provision_data = provision["script"] 410 | self.__request_put("/provisions/" + provision_name, provision_data) 411 | except IOError as err: 412 | print("provision_create_all_from_file:\nIOError: " + str(err) + "\n") 413 | except ValueError: 414 | print("provision_create_all_from_file:\nValueError: File contains faulty values\n") 415 | except KeyError: 416 | print("provision_create_all_from_file:\nKeyError: File contains faulty keys\n") 417 | 418 | def provision_delete(self, provision_name): 419 | """Delete a given provision""" 420 | quoted_name = requests.utils.quote(provision_name) 421 | try: 422 | self.__request_delete("/provisions/" + quoted_name) 423 | except requests.exceptions.HTTPError: 424 | raise ItemNotFoundError 425 | 426 | ##### methods for files ##### 427 | 428 | def file_upload(self, filename, fileType, oui, productClass, version): 429 | """Upload or update a file""" 430 | try: 431 | self.__request_put("/files/" + filename, data=open(filename, "rb"), headers={"fileType": fileType, "oui": oui, "productClass": productClass, "version" : version}) 432 | except IOError as err: 433 | print("file_upload:\nIOError: " + str(err) + "\n") 434 | 435 | def file_delete(self, filename): 436 | """Delete a given file""" 437 | self.__request_delete("/files/" + filename) 438 | 439 | def file_get_all(self): 440 | """Get all files as a json object""" 441 | return self.__request_get("/files") 442 | 443 | def file_get(self, filename=None, fileType=None, oui=None, productClass=None, version=None): 444 | """Get all data from one or several files""" 445 | url = "{" 446 | if filename is not None: 447 | url += "\"filename\":\"" + filename + "\"" 448 | else: 449 | if fileType is not None: 450 | if url != "{": 451 | url += "," 452 | url += "\"metadata.fileType\":\"" + fileType + "\"" 453 | if oui is not None: 454 | if url != "{": 455 | url += "," 456 | url += "\"metadata.oui\":\"" + oui + "\"" 457 | if productClass is not None: 458 | if url != "{": 459 | url += "," 460 | url += "\"metadata.productClass\":\"" + productClass + "\"" 461 | if version is not None: 462 | if url != "{": 463 | url += "," 464 | url += "\"metadata.version\":\"" + version + "\"" 465 | if url == "{": 466 | raise InvalidRequestDataError 467 | return self.__request_get("/files/?query=" + requests.utils.quote(url + "}", safe = '')) 468 | 469 | ##### methods for faults ##### 470 | 471 | def fault_get_all_IDs(self): 472 | """Get IDs of all faults""" 473 | jsondata = self.__request_get("/faults/" + "?projection=_id") 474 | data = [] 475 | for fault in jsondata: 476 | data.append(fault["_id"]) 477 | return data 478 | 479 | def fault_get_all(self, device_id=None): 480 | if device_id: 481 | """Get all existing faults for a given device""" 482 | quoted_id = requests.utils.quote("{\"device\":\"" + device_id + "\"}", safe = '') 483 | return self.__request_get("/faults/" + "?query=" + quoted_id) 484 | else: 485 | """Get all existing faults""" 486 | return self.__request_get("/faults/") 487 | 488 | def fault_delete(self, fault_id): 489 | """Delete a given fault""" 490 | quoted_id = requests.utils.quote(fault_id) 491 | try: 492 | self.__request_delete("/faults/" + quoted_id) 493 | except requests.exceptions.HTTPError: 494 | raise ItemNotFoundError 495 | 496 | class ConnectionError(Exception): 497 | def __str__(self): 498 | return "Could not (re-)connect to the ACS" 499 | 500 | class ItemNotFoundError(Exception): 501 | def __str__(self): 502 | return "Could not find the requested item (device, task, preset, object, file, etc)" 503 | 504 | class InvalidRequestDataError(Exception): 505 | def __str__(self): 506 | return "Request contained invalid data" 507 | --------------------------------------------------------------------------------