目录

简介

先决条件

要求

使用的组件

配置

概述

模块

生成令牌

测试API

带有报头参数的API

具有查询参数的API

简介

本文档介绍如何使用Python使用Cisco Catalyst Center上提供的不同API。

先决条件

要求

基本知识：

- 思科Catalyst中心

- API

- Python

使用的组件

- 思科Catalyst Center 2.3.5.x

- Python 3.x.x

本文档中的信息都是基于特定实验室环境中的设备编写的。本文档中使用的所有设备最初均采用原始（默认）配置。如果您的网络处于活动状态，请确保您了解所有命令的潜在影响。

注意：思科技术支持中心(TAC)不为Python提供技术支持。如果您遇到Python问题，请联系Python支持寻求技术支持。

配置

概述

Cisco Catalyst Center提供许多API。要验证可以使用哪些API，请在Catalyst Center上导航到平台>开发人员工具包> API。

Catalyst Center API页面

每个API都有其自己的用途，具体取决于需要在Catalyst Center上执行的信息或操作。要使API正常工作，前提条件是，必须使用令牌向Catalyst Center正确进行身份验证，并获得成功的API响应。令牌相应地标识REST调用方的权限。

确定构成API的组件也很重要，这些组件如下所示：

- URL：提供对特定资源的访问的终端。

- 方法：所有API都必须包含方法。它定义客户端要对特定终端执行的操作/操作。示例：POST、GET、PUT、DELETE。

- 报头：以键值对格式提供有关请求的其他信息。例如，授权报头提供使用凭证的身份验证方法。

- 参数：通过使用API向终端提供特定说明的变量。参数可以是终端URL的一部分。

- 负载：在API调用期间需要发送到终端的数据。

注意：有关Catalyst Center上可用的每个API的详细信息，请参阅API参考指南。

模块

使用的Python模块：

- 请求：此模块允许向特定URL发送HTTP/1.1请求。有关模块的更多信息，请参阅请求模块指南。

- base64：提供编码和解码功能。有关模块的详细信息，请参阅base64模块指南。

- json：此模块允许从API响应获取特定数据。有关模块的更多信息，请参阅json模块指南。

注意：有关如何安装Python模块的更多信息，请参阅安装Python模块文档。

生成令牌

必须使用称为身份验证API的API生成新令牌。

身份验证API:

POST      https://

/dna/system/api/v1/auth/token

必须说明生成的令牌有效期为1小时。1小时后，必须使用上面提到的相同API生成新的令牌。

在新的Python文件中，导入模块(请求、base64和json)，然后创建四个变量：

import requests

import base64

import json

user = 'user'    # User to login to Catalyst Center

password = 'password'    # Password to login to Catalyst Center

token = ''    # Variable to store the token string

authorizationBase64 = ''   # Variable that stores Base64 encoded string of "username:password"

身份验证API在报头中支持基本身份验证作为授权令牌。基本身份验证是一种可用于对终端进行身份验证的方法，提供用户名和密码，用冒号(username:password)分隔。 这两个值都是base64编码的，终端解码登录凭证并检查用户是否可以访问。

要为我们的用户名和密码创建Base64包含字符串，请使用base64模块。为此，使用b64encode功能。

byte_string = (f'{user}:{password}').encode("ascii")

authorizationBase64 = base64.b64encode(byte_string).decode()

从上述代码中，byte_string变量是使用“.encode("ascii")”函数创建的。这是因为base64.b64encode函数需要类似字节的对象。另请注意，user和password变量用于保留字符串格式“user:password”。最后，使用用户和密码创建一个base64编码的字节字符串。使用“decode()”方法，该值被转换为str对象。

要进行验证，可以打印authorizationBase64变量的值：

print(authorizationBase64)

输出示例：

am9yZ2QhbDI6Sm9yZ2VhbDXxXxXx

警告：base64不是加密算法。不得用于安全目的。Authentication API还支持AES密钥加密作为报头中的授权令牌，从而提供更高的安全性。

现在已创建一个base64编码的字符串，该字符串使用用户和密码进行身份验证(Catalyst Center)，现在应该使用模块请求继续执行API身份验证API调用。另外，名为request的函数允许获取包含请求文本的响应对象。

方法的语法：

requests.request(“method”, “url”, **kwargs)

**kwargs表示传入请求的任何参数，例如cookie、用户代理、负载、报头等。

身份验证API指定方法为POST,URL为"/dna/system/api/v1/auth/token"，并且需要在Header中指定基本身份验证。

创建这些变量是为了将其用于request()函数。

url = https://

/api/system/v1/auth/token

headers = {

‘content-type’: “application/json”,

‘Authorization’: ‘Basic ’ + authorizationBase64

}

对于headers变量，指定了两个内容。第一个是content-type，它指定发送到终端的资源的媒体类型（这有助于终端准确分析和处理数据）。 第二个是Authorization，在这种情况下，变量authorizationBase64（它存储了我们的base64包含字符串）作为参数发送到Catalyst Center进行身份验证。

现在，继续使用request()函数执行API调用。下一个代码显示函数的语法：

response = requests.request(“POST”, url, headers=headers)

创建response变量以存储所做的API调用的数据。

要打印获取的响应，请在响应变量中将print函数与text()方法一起使用。text()方法使用从Catalyst Center接收的响应生成str对象。

print(response.text)

输出示例：

{“Token”:“eyJhbGci0iJSUzI1NiIsInR5JK09s1zVmNjk0NjhkNTFhNDJ1ZWeLCU291cmNlIjoiaW50ZXJuYWwiLCW2vMPUbU0JNlqxOXNe1jMzY1LTQ5MWEtODljNC0yZmE2YjVhM2

!--- Output is supressed

注意：如果Catalyst Center使用自签名证书，则API请求可能会失败，并出现下一个错误：

requests.exceptions.SSLError: HTTPSConnectionPool(host='X.X.X.X', port=443): Max retries exceeded with url: /api/system/v1/auth/token (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1000)')))

要解决此问题，需要将verify参数作为False添加到请求功能中。这会忽略验证来自终端(Catalyst Center)的SSL证书。

response = requests.request(“POST”, url, headers=headers, verify=False)

从API authentication调用收到的响应中，请注意该结构类似于Python中的字典，但它是一个str对象。

要验证对象的类型，请使用type()函数。

print(type(response.text))

返回下一个输出：

在实际中，只需要从从API接收的响应中提取令牌值，而不是整个字符串，因为要使用其他Catalyst Center API，必须仅将令牌作为参数传递。

由于从API调用接收的响应具有类似于Python中的词典的结构，但对象类型为str，所以需要使用json模块将所述的对象转换为词典。这会从从API接收的整个字符串中提取令牌值。

为此，函数json.loads()将字符串转换为字典，以便稍后仅提取令牌值并将其直接分配到令牌变量。

token = json.loads(response.text)  # Converting the response.text string value into a dictionary (It is creating a JSON object).

token = (token["Token"])  # Extracting just the token value by specifying the key as a parameter.

要验证token变量是否仅将令牌作为其值，请继续打印。

print(token)

输出示例：

eyJhbGci0iJSUzI1NiIsInR5JK09s1zVmNjk0NjhkNTFhNDJ1ZWeLCU291cmNlIjoiaW50ZXJuYWwiLCW2vMPUbU0JNlqxOXNe1jMzY1LTQ5MWEtODljNC0yZmE2YjVhM2

!--- Output is supressed

提示：由于每个生成的令牌默认在1小时内到期，因此可以创建包含生成令牌的代码的Python方法，并且在每次令牌到期时调用它，而无需通过调用创建的方法来运行整个程序。

测试API

既然令牌已成功分配给token变量，就可以使用可用的Catalyst Center API。

在本例中，Cisco DNA Center Nodes Configuration Summary API已经过测试。

思科DNA中心节点配置摘要

GET     https://

/dna/intent/api/v1/nodes-config

此API提供有关Catalyst Center当前配置的详细信息，例如配置的NTP服务器、节点名称、集群内链路、LACP模式等。

Cisco DNA Center Nodes Configuration Summary API指定，在本例中，使用的方法是GET,URL是"/dna/intent/api/v1/nodes-config"，由于已提取令牌字符串并将其分配给token变量，因此这次令牌作为API调用报头中的变量传递为“X-Auth-Token”：后跟令牌。

这将验证对执行的每个API调用的向Catalyst Center的请求。请记住，每个令牌持续1小时。1小时后，必须生成新令牌才能继续对Catalyst Center进行API调用。

继续创建变量以测试API:

nodeInfo_url = "https://

/dna/intent/api/v1/nodes-config"

nodeInfo_headers = {

'X-Auth-Token': token

}

nodeInfoResponse = requests.request("GET", nodeInfo_url, headers=nodeInfo_headers)

创建nodeInfo_url变量是为了存储我们的API的URL。nodeInfo_headers变量存储我们的API的标头。在本例中，'X-Auth-Token:'和token变量作为参数传递到Catalyst Center，以成功对请求进行身份验证。最后，nodeInfoResponse变量存储API的响应。

要验证收到的响应，您可以使用print()函数。

输出示例：

{"response": {"nodes": [{"name": "Catalyst Center", "id": "ea5dbec1-fbb6-4339-9242-7694eb1cXxXx", "network": [{"slave": ["enp9s0"], "lacp_supported": true, "intra_cluster_link": false, "interface": "enterprise", "inet6": {}, "inet": {"routes": [{"netmask": "255.255.0.0"

!--- Output is supressed

注意：如果Catalyst Center中使用自签名证书，API请求可能会失败，并出现下一个错误：

requests.exceptions.SSLError: HTTPSConnectionPool(host='X.X.X.X', port=443): Max retries exceeded with url: /api/system/v1/auth/token (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1000)')))

要解决此问题，需要将verify参数添加为False到请求中。这会抑制从终端(Catalyst Center)验证SSL证书。

nodeInfoResponse = requests.request("GET", nodeInfo_url, headers=nodeInfo_headers, verify=False)

从API收到的响应可能难以读取。使用json()模块，可以用更易读的字符串打印响应。首先，必须使用json.loads()函数后跟json.dumps()函数将API响应加载到JSON对象中：

jsonFormat = (json.loads(nodeInfoResponse.text)) # Creating a JSON object from the string received from the API response.

print(json.dumps(jsonFormat, indent=1)) # Printing the response in a more readable string using the dumps() function.

json.dumps:此函数返回JSON格式字符串中用作参数的JSON对象。

缩进：此参数定义JSON格式字符串的缩进级别。

输出示例：

{

"response": {

"nodes": [

{

"name": "X.X.X.X",

"id": "ea5dbec1-fbb6-4339-9242-7694eb1xXxX",

"network": [

{

"slave": [

"enp9s0"

],

"lacp_supported": true,

"intra_cluster_link": false,

!--- Output is supressed

带有报头参数的API

有些API需要在报头中发送一些参数才能按预期工作。在本例中，将测试Get Client Encryption Details API。

GET        https://

/dna/intent/api/v1/client-enrichment-details

要验证API需要哪些报头参数才能按预期工作，请导航到平台>开发人员工具包> APIs >获取客户端丰富详细信息，然后点击API的名称。将打开一个新窗口，并在Parameters选项下显示API工作所需的报头参数。

在这种情况下，对于entity_type参数，根据描述，值可以是network_user_id或mac_address，并且entity_value参数必须包含已定义的实体类型的值。

要继续操作，需要定义两个新变量entity_type和entity_value及其相应的值：

entity_type = 'mac_address'   #This value could be either 'network_user_id' or 'mac_address'.

entity_value = 'e4:5f:02:ff:xx:xx'    #Depending of the 'entity_type' used, need to add the corresponding value for 'entity_value'. In this case, 'mac_address' value was chosen for 'entity_type' parameter so, a MAC Address was assigned to the 'entity_value' parameter.

还会创建新变量以执行API调用。API调用的URL存储在userDerivation_url变量中。信头存储在userEnfurationHeaders变量中。收到的响应存储在userDerivationResponse变量中。

userEnrichment_url = "https://

/dna/intent/api/v1/user-enrichment-details"

userEnrichmentHeaders = {

'X-Auth-Token': token,

'entity_type': entity_type,

'entity_value': entity_value,

}

userEnrichmentResponse = requests.request("GET", userEnrichment_url, headers=userEnrichmentHeaders)

如您所见，从userEncryptionHeaders中，entity_type和entity_value变量作为API调用的报头参数以及token变量传递。

要验证收到的响应，请使用print()函数。

print(userEnrichmentResponse.text)

输出示例：

[ {

"userDetails" : {

"id" : "E4:5F:02:FF:xx:xx",

"connectionStatus" : "CONNECTED",

"tracked" : "No",

"hostType" : "WIRELESS",

"userId" : null,

"duid" : "",

"identifier" : "jonberrypi-1",

"hostName" : "jonberrypi-1",

"hostOs" : null,

"hostVersion" : null,

"subType" : "RaspberryPi-Device",

"firmwareVersion" : null,

"deviceVendor" : null,

"deviceForm" : null,

"salesCode" : null,

"countryCode" : null,

"lastUpdated" : 1721225220000,

"healthScore" : [ {

"healthType" : "OVERALL",

"reason" : "",

"score" : 10

}, {

"healthType" : "ONBOARDED",

"reason" : "",

"score" : 4

!--- Output is suppressed

具有查询参数的API

查询参数可用于过滤API返回的特定数量的结果。这些参数将添加到API的URL中。

Get Device List API调用已测试。

GET          https://10.88.244.133/dna/intent/api/v1/network-device

Get Device List API返回Catalyst Center中添加的所有设备的列表。如果请求特定设备的详细信息，查询参数可以帮助过滤特定信息。

要验证哪些查询参数可用于API，请导航到Platform > Developer Toolkit > APIs > Get Device List，然后点击API的名称。将打开一个新窗口，并在Parameters选项下显示可用于API的查询参数。

在本示例中，使用managementIpAddress和serialNumber查询参数（考虑不必要的所有查询参数用于API调用）。 继续创建并分配两个查询参数的相应值。

managementIpAddress = '10.82.143.250'

serialNumber = 'FDO25160X9L'

如上所述，查询参数将使用“？”添加到API的URL中，特别是其末尾 后跟查询参数。

如果要使用多个查询参数，则会在它们之间放置&'符号，以形成所谓的查询字符串。

下一个示例显示如何将查询参数添加到存储API调用的URL的deviceListUrl变量。

deviceListUrl = "https://

/dna/intent/api/v1/network-device?managementIpAddresss=" + managementIpAddress + "&serialNumber=" + serialNumber

请注意，之前创建的变量已附加到URL字符串。换句话说，URL的整个字符串如下所示：

deviceListUrl = "https://

/dna/intent/api/v1/network-device?managementIpAddresss=10.82.143.250&serialNumber=FDO25160X9L"

继续执行API调用，会创建deviceListHeaders变量以存储API报头以及作为参数传递的token变量，而deviceListResponse变量存储API响应。

deviceListHeaders = {

'X-Auth-Token': token,

}

deviceListResponse = requests.request("GET", deviceListUrl, headers=deviceListHeaders)

要验证收到的响应，您可以使用print()函数。

print(deviceListResponse.text)

输出示例：

{"response":[{"family":"Switches and Hubs","description":"Cisco IOS Software [Cupertino], Catalyst L3 Switch Software (CAT9K_IOSXE), Version 17.9.4a, RELEASE SOFTWARE (fc3) Technical Support: http://www.cisco.com/techsupport Copyright (c) 1986-2023 by Cisco Systems, Inc. Compiled Fri 20-Oct-23 10:44 by mcpre","lastUpdateTime":1721205664979,"deviceSupportLevel":"Supported","softwareType":"IOS-XE","softwareVersion":"17.9.4a","serialNumber":"FDO25160X9L","inventoryStatusDetail":"

提示：要以更易读的方式打印响应，您可以使用测试API部分中描述的json.loads()和json.dumps()函数。