Debugging API calls
===================

New in version 3.0.10.

.. toctree::

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

.. code-block:: python

   from f5.bigip import ManagementRoot
   mgmt = ManagementRoot('localhost', 'admin', 'admin', port=10443, token=True, debug=True)
   resource = mgmt.tm.ltm.pools.pool.create(name='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.

.. code-block:: python

   for x in mgmt.debug_output:
       print(x)

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

.. code-block:: python

   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' \
     -H 'X-F5-Auth-Token: 2PXGGMT4QR3Y3PAQEEURAPB5DJ'

   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.

.. note::

   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
