Examples

In this section, we will show some common examples of how the API can be used. The examples are written in Python using the HTTPX library as a Requests alternative.

Acquire a JWT token.

There are multiple ways to do this. Below is one example.

import httpx
import logging

logging.basicConfig()
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

server = "api-cx.cisco.com"
client_id = "clientid"
client_secret = "secret"

def get_jwt(server: str, client_id: str, client_secret: str) -> str:
    """
    Helper function that will obtain a JSON Web Token (JWT) using the provided client id and client secret
    and storing this JWT
    """
    
    url = f'https://{server}/torii-auth/v1/token'
    
    data = {
        "grantType": "client_credentials",
        "clientId": client_id,
        "secret": client_secret,
        "scope": "api.bcs.manage"
    }
    
    try:
        resp = httpx.Client().post(url=url, json=data)
        resp.raise_for_status()
    except (httpx.HTTPStatusError, httpx.RequestError) as err:
        logger.error(
            f'Failed to JSON Web Token(JWT): {err}'
        )
        raise err
    else:
        return resp.json().get('accessToken')


jwt = get_jwt(
    server,
    client_id,
    client_secret
)

# This is the token you want to pass in subsequent API calls
print(jwt)

The jwt variable now stores a JWT token. You can decode it to verify this token has exactly the data you expect it to have:

import jwt as jj

decoded_jwt = jj.decode(jwt, options={'verify_signature': False})
print(decoded_jwt)

With a JWT acquired, you can query the other API resources.

Query your BCS monitored devices.

Here is an example of querying the /inventory/device resource. We pass the previously received JWT as a Bearer token in the HTTP Authorization headers.

from typing import Optional, List, Dict, Generator

def get_all_items(url: str, headers: Dict[str, str], url_params: dict = None) -> Generator[dict, None, None]:
    """
    Function that will fetch all items
    :param url:         str representing the url
    :param headers:     dictionary containing the headers to be added to the request
    :param url_params:  dictionary containing the url parameters
    :return:            Generator
    """
    offset, total = None, None
    params = url_params if url_params is not None else {}
    
    while offset is None or offset <= total:
        if offset is not None:
            params['offset'] = offset
        try:
            response = httpx.Client().get(url=url, headers=headers, params=params)
            response.raise_for_status()
            
        except (httpx.HTTPError, httpx.RequestError) as err:
            logger.error(
                f'Failed to get items: {err}'
            )
            raise err
        
        else:
            response_body = response.json()
            response_headers = response.headers
            
            offset = int(response_headers.get('offset')) + int(response_headers.get('max'))
            total = int(response_headers.get('total'))
            
            for item in response_body.get('items'):
                yield item
    



def get_devices(jwt: str, server: str, url_params: dict = {}) -> list:
    """
    Function that queries the devices resource
    :param jwt:             The JWT to connect with
    :param server:          The server to connect to
    :return:                List containing the Devices as JSON blobs
    """
    
    # If your data is in the US region, use this URI.
    url = f'https://{server}/us/bcs/v2/inventory/devices'
    
    # If your data is in the EMEA region, use this URI instead
    # url = f'https://{server}/emea/bcs/v2/inventory/devices'
    
    headers = {'Authorization': f'Bearer {jwt}'}
    results = []

    for item in get_all_items(url=url, headers=headers, url_params=url_params):
        results.append(item)

    return results


# Fetch all the devices
# Use the Access Token we got in the JWT to do the request
devices = get_devices(
    jwt, 
    server
)

# Do something with the devices data
for device in devices:
    ...

Pagination

In the get_all_items() function from the previous example, we use pagination. The API response headers have the following interesting fields:

  • offset: The first requested record to start from
  • max: The maximum number of records to retrieve
  • total: The total amount of records that are available for retrieval

At any time you can pass the offset and max as a URL parameter to influence which group of records you want to retrieve.

Get the count of all devices or assets.

One way would be to get all the items from either endpoint, and then count them. We made it easier for you so you can simply do an HTTP HEAD request to both endpoints. This will return you with the number of items without having to download the entire response.

headers = {'Authorization': f'Bearer {jwt}'}
url = f'https://{server}/us/bcs/v2/inventory/assets'

resp = httpx.Client().head(url=url, headers=headers)
resp.raise_for_status()

print(resp)