.. image:: /images/hpe_logo2.png :width: 150pt | .. toctree:: :maxdepth: 1 ============== Advanced Usage ============== The following sections describe advanced usage of the python-ilorest-library. A deeper dive into the Client Classes ===================================== The **RedfishClient** and **LegacyRestClient** are both based on the **RestClient** class. The only difference between the two is that one is configured for *Legacy Rest* and the other one is configured for *Redfish*. So it is possible to directly use the **RestClient** class instead if you want. For other REST APIs, it is even possible to use the **RestClientBase** class as a client. Modifying Remote Connection Settings ------------------------------------ A remote connection eventually turns into a *urllib3* **PoolManager** class. Because of this setting, any extra arguments passed to the Client class that **PoolManager** takes (and any urllib3 adds in the future)are added to the *urllib3* connection. Useful arguments include: * **timeout** (in seconds) * **retries** * **ca_certs** For a full list of arguments possible, see urllib3's `documentation `_. The following example sets a **RedfishClient** with a timeout of 30 seconds and five retries. >>> REST_OBJ = redfish.RedfishClient(base_url=iLO_host, username=login_account, password=login_password, timeout=30, retries=5) Proxy Support ------------- The python-ilorest-library **version 2.5.0 and greater** supports both HTTP and SOCKS proxies. If you are using a socks proxy, you must `install the [socks] add-on `_. >>> REST_OBJ = redfish.RedfishClient(base_url="https://10.0.0.100", username="username", password="password", proxy='http://proxy.proxy.com:8080') SOCKS proxies must start with `socks` >>> REST_OBJ = redfish.RedfishClient(base_url="https://10.0.0.100", username="username", password="password", proxy='socks5://proxy.proxy.com:8080') HTTPS verification ------------------ By default the python-ilorest-library creates an unverified context for HTTPS connections. To verify the HTTPS certificate, pass an optional argument to urllib3 through a Client object, **ca_certs**. >>> REST_OBJ = redfish.RedfishClient(base_url="https://hostname", username="username", password="password", ca_certs='C:\\CA.crt') For a full description of possible arguments in ca_certs, see `urllib3's documentation on the subject `_. A deeper dive into the Response Class ===================================== The **Response** class was already mentioned briefly in the `Quick Start `_ section, but this section provides more details about the useful properties of the Response class. You can use the **getheader()** function to search for a specific header in a response. *getheader is case insensitive* >>> response.getheader('link') '; rel=describedby' The **ori** property returns the response body in its original form, and it is useful for binary responses. >>> response.ori The **obj** property returns the response body in dot notation. >>> resp_obj = response.obj >>> resp_obj.AssetTag u'assettag' For keys with special characters, the dictionary notation still works. >>> resp_obj.Bios['@odata.id'] u'/redfish/v1/systems/1/bios' Response Object --------------- A class has been implemented within the library to handle HTTP response codes from iLO for patch, post and put type requests. HTTP response data is parsed and then combined with the relevant error response resource as associated with the applied properties (categorized by type and MessageId). Error response data is guided by HTTP status codes. See `List of HTTP status codes `_ for more information: * **200** response codes indicate success. Generally these types of responses include simple messages, such as "successful" or "one or more properties have been changed, an ilo reset is required for the properties to take effect" (on some rare occassions no response message or an empty response string will occur). * **400** response codes indicate client failures such as an invalid post or patch, or the resource could not be modified. Additional detailed information will likely accompany the response message. .. note:: Response codes outside of 200 and 400 have not been extensively tested or witnessed. Responses for HTTP response codes under 300 redirects or 500 server errors might be observed; please feel free to note and share the results of such encounters by opening a GitHub issue. Generally 400 error response codes result in a full error response. A response might include the following data; however, the entries are not guaranteed for every response: * An error response message ID ("MessageId"), iLO response error message code identification. * An error response message description ("Description"), essentially a quick synopsis of the issue. * An error response message ("Message") describing the reason for the error in greater detail. The offending properties are noted as per the relevant error response resource. * An error response resolution ("Resolution") describing steps to correct the error. The following is an example response message for an error in the iLODateTime type regarding the property "NTPServers": .. code-block:: TEXT HTTP Response Code: [400] MessageId: iLO.2.8.PropertyNotWritableOrUnknown Description: The request included a value for a read-only or unknown property. Message: The property "NTPServers" is a read-only property and cannot be assigned a value, or not valid for this resource. Resolution: If the operation did not complete, remove the property from the request body and resubmit the request. .. note:: The response data is also available when utilizing the iLO Channel Interface Driver (Chif). Request Object -------------- The **response** property of the Response object returns a **Request** object, which describes the request that generated the response. >>> response.request The **url** property shows the actual system the call was made against. >>> response.request.url 'https://10.0.0.100' The **method** property shows the method applied. >>> response.request.method 'PATCH' The **path** property shows what path the method was made against. >>> response.request.path '/redfish/v1/systems/1' The **body** property shows what body (if any) was passed along with the request. >>> response.request.body '{"AssetTag": "new tag"}' Multi-part Form Data ==================== .. note:: Multi-part Form data is only supported on iLO with a **Remote Object**. Multi-part form data is sent as a list of tuples. Standard fields are a tuple of `(field, value)` >>> ('field1': 'value') Json data is just another value >>> ('jsondata', {'key1': 'value1', 'key2': 'value2'}) Files & binary data are similar to the standard fields, except instead of a value we have another tuple. This value tuple has 2 or 3 items `(filename, filedata)` or optionally include the MIME type explicitly `(filename, filedata , MIME type)` >>> ('filedata', ('filename.data', '', 'application/octet-stream')) So putting it all together in a single form data request: >>> [('field1': 'value'), ('jsondata', {'key1': 'value1', 'key2': 'value2'}), ('filedata', ('filename.data', '', 'application/octet-stream'))] For an example of Multi-part form data in action, see the `example for uploading firmware to the iLO repository `_. Logging ======= Logging of all request and responses is available through the redfish_logger function. First, import the logging and redfish_logger functions. >>> import logging >>> from redfish import redfish_logger Then, specify the logger file name, format of the logger, and the logging level. See the `logging` python documentation for more information on these arguments. >>> LOGGERFILE = "RedfishApiExamples.log" >>> LOGGERFORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" >>> LOGGER = redfish_logger(LOGGERFILE, LOGGERFORMAT, logging.DEBUG) After running some commands, your log file should be populated in the file specified at creation.