| #!/usr/bin/env python3 | 
 | r""" | 
 | This is an extended user library to support Robot Selenium code. | 
 | The class contains functions which the robot framework will use | 
 | and import as a user-defined keyword. | 
 | """ | 
 | import json | 
 | import ssl | 
 |  | 
 | import gen_print as gp  # NOQA | 
 | import gen_valid as gv  # NOQA | 
 | import requests | 
 | import websocket | 
 |  | 
 |  | 
 | class event_notification:  # NOQA | 
 |     r""" | 
 |     Main class to subscribe and receive event notifications. | 
 |     """ | 
 |  | 
 |     def __init__(self, host, username, password): | 
 |         r""" | 
 |         Initialize instance variables. | 
 |  | 
 |         Description of argument(s): | 
 |         host        The IP or host name of the system to subscribe to. | 
 |         username    The username for the host system. | 
 |         password    The password for the host system. | 
 |         """ | 
 |         self.__host = host | 
 |         self.__user = username | 
 |         self.__password = password | 
 |         self.__websocket = None | 
 |  | 
 |     def __del__(self): | 
 |         try: | 
 |             self.__websocket.close() | 
 |         except AttributeError: | 
 |             pass | 
 |  | 
 |     def login(self): | 
 |         r""" | 
 |         Login and return session object. | 
 |         """ | 
 |         http_header = {"Content-Type": "application/json"} | 
 |         session = requests.session() | 
 |         response = session.post( | 
 |             "https://" + self.__host + "/login", | 
 |             headers=http_header, | 
 |             json={"data": [self.__user, self.__password]}, | 
 |             verify=False, | 
 |             timeout=30, | 
 |         ) | 
 |         gv.valid_value(response.status_code, valid_values=[200]) | 
 |         login_response = json.loads(response.text) | 
 |         gp.qprint_var(login_response) | 
 |         gv.valid_value(login_response["status"], valid_values=["ok"]) | 
 |         return session | 
 |  | 
 |     def subscribe(self, dbus_path, enable_trace=False): | 
 |         r""" | 
 |         Subscribe to the given path and return a list of event notifications. | 
 |  | 
 |         For more details on "subscribe" and "events" go to | 
 |         https://github.com/openbmc/docs/blob/master/rest-api.md#event-subscription-protocol | 
 |  | 
 |         Example robot code: | 
 |         ${event_notifications}=  Subscribe  /xyz/openbmc_project/sensors | 
 |         Rprint Vars  event_notifications | 
 |  | 
 |         Example output: | 
 |         event_notifications: | 
 |           [0]: | 
 |             [interface]:             xyz.openbmc_project.Sensor.Value | 
 |             [path]:                  /xyz/openbmc_project/sensors/temperature/ambient | 
 |             [event]:                 PropertiesChanged | 
 |             [properties]: | 
 |               [Value]:               23813 | 
 |  | 
 |         Description of argument(s): | 
 |         dbus_path              The subscribing event's path (e.g. | 
 |                                "/xyz/openbmc_project/sensors"). | 
 |         enable_trace           Enable or disable trace. | 
 |         """ | 
 |  | 
 |         session = self.login() | 
 |         cookies = session.cookies.get_dict() | 
 |         # Convert from dictionary to a string of the following format: | 
 |         # key=value;key=value... | 
 |         cookies = gp.sprint_var( | 
 |             cookies, | 
 |             fmt=gp.no_header() | gp.strip_brackets(), | 
 |             col1_width=0, | 
 |             trailing_char="", | 
 |             delim="=", | 
 |         ).replace("\n", ";") | 
 |  | 
 |         websocket.enableTrace(enable_trace) | 
 |         self.__websocket = websocket.create_connection( | 
 |             f"wss://{self.__host}/subscribe", | 
 |             sslopt={"cert_reqs": ssl.CERT_NONE}, | 
 |             cookie=cookies, | 
 |         ) | 
 |         dbus_path = [path.strip() for path in dbus_path.split(",")] | 
 |         dbus_path = {"paths": dbus_path} | 
 |  | 
 |         self.__websocket.send(json.dumps(dbus_path)) | 
 |         event_notifications = json.loads(self.__websocket.recv()) | 
 |         self.__websocket.close() | 
 |         return event_notifications |