Debugging API calls

New in version 3.0.10.

The F5 SDK provides an abstraction on top of the actual F5 REST API. We’ve discussed in other pages, however, that this is a rather loose abstraction. In reality, it follows the actual API design a lot more than would be typical of other SDKs.

Despite this close adherence to the API, there may come a time where users of the SDK (or tools built on top of it) need a more familiar set of information than method calls to debug a problem. For this purpose we’ve made available the cURL command equivalents that the F5 SDK makes.

When the F5 SDK is used to make an API call, it will keep track of these calls and make them available to the user in an attribute of the ManagementRoot called _debug.

Let’s look at an example of how to trigger this tracing.

Tracing calls

API tracing always happens. The trace information is available to you regardless of whether you ask for it or not. It is discarded, however, if you destroy the ManagementRoot object.

Consider the following SDK usage

from f5.bigip import ManagementRoot
mgmt = ManagementRoot('localhost', 'admin', 'admin', port=10443, token=True, debug=True)
resource ='foobar')

This SDK call communicates with a BIG-IP to create an LTM pool. What if you needed to recreate this API call in a more familiar tool like cURL? How would you know what exactly the API called so that you could re-create the exact cURL command.

Tools like Postman have a handy “Code” link to give you your actual API calls. The F5 SDK has a very similar feature that happens automatically under the hood for you.

You can view the commands generated by the code above by printing the ._debug property of the mgmt object. This property contains a list of items. Therefore, for readability, let’s print each of them.

for x in mgmt.debug_output:

When this is done, we will be presented with output that resembles the following (printed for readability).

curl -k -X GET \
  https://localhost:10443/mgmt/tm/sys/ \
  -H 'Connection: keep-alive' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Accept: */*' \
  -H 'User-Agent: python-requests/2.18.4 f5-icontrol-rest-python/1.3.4' \
  -H 'Content-Type: application/json' \

curl -k -X POST \
  https://localhost:10443/mgmt/tm/ltm/pool/ \
  -H 'Connection: keep-alive' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Accept: */*' \
  -H 'User-Agent: python-requests/2.18.4 f5-icontrol-rest-python/1.3.4' \
  -H 'Content-Type: application/json' \
  -H 'Content-Length: 18' \
  -H 'X-F5-Auth-Token: 2PXGGMT4QR3Y3PAQEEURAPB5DJ' \
  -d '{"name": "foobar"}'

As you can see, there are a couple of commands there. In particular, the second command is the command that created the pool in the above SDK code.

What about the first item in the list though. What is its relevance? This is an implementation detail of the SDK. To provide the functionality that it does, the SDK needs to know what version of the REST API is being used. This is accomplished by the first command there. From the response of that command, we get the version of the REST API.


The commands shown in the trace are only a convenient illustration of what the SDK is doing. The SDK is not using cURL for the work it does.

These commands are useful in exploring how the SDK actually behaves. One area where they come in particularly handy is in the process of debugging errors, or, in implementing new functionality.

You can copy and paste the commands as they are printed and use them to issue the same API calls the the equivalent SDK code does.

Enabling and disabling

The debug logging can also be enabled and disabled as desired. To do this, you can set the debug property of the ManagementRoot object to either a truth-like or false-like value. These include,

Truth ‘y’, ‘yes’, ‘on’, ‘1’, ‘true’, ‘t’, 1, 1.0, True

False ‘n’, ‘no’, ‘off’, ‘0’, ‘false’, ‘f’, 0, 0.0, False