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.
Copyimport 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:
Copyimport 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.
Copyfrom 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 frommax
: The maximum number of records to retrievetotal
: 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.
Copyheaders = {'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)