解释 Cato API 的 Python 脚本

本文介绍了 Cato API 并分析了一个 Python 应用示例。

介绍

Cato API 是根据 GraphQL 规范 实现的。 即使 GraphQL 旨在生成易于使用的 API,学习使用任何新技术仍然需要开发人员投入时间。 本文档的目标是减少此投资的程度,并介绍一个小的 Python 应用程序,该程序执行 admins Cato API 调用并简单地返回为一个账户定义的管理员的数量。 通过这样做,读者被介绍到 Cato GraphQL API 应用程序的最重要元素。

注意

注意:

预计读者对以下内容有基本了解:

  • 脚本或编程(例如,您熟悉变量和代码库等概念)

  • JSON 规范(例如,您已经处理过 JSON 文档)

  • 网络设备(例如,您知道超文本传输协议的存在以及服务器是什么)

对 Python 语言有一些经验会有帮助,但应该仍然可以在没有这种经验的情况下理解这篇文章。

基本 Cato API 应用程序指南

此处展示的应用程序是用 Python 编写的,并使用 Cato API admins 调用来检索为账户定义的管理员总数。  Python 和 admins API 调用已被选中,因为:

  • Python 是一种非常常见的语言,易于阅读和理解

  • 可以使用 admins API 调用来创建一个调用 Cato GraphQL API 的非常简单的示例

示例程序是基本的,不包含任何错误检查。  程序只输出为账户定义的管理员总数。 

注意

注意: Cato API 不绑定到任何特定的编程语言。  可以使用任何能够使用超文本传输协议POST功能和处理JSON文档的语言来实现一个应用程序。  

示例程序概览

这个示例程序很短,并不包含任何决策逻辑或重复动作的代码。  可以通过将一些代码行合并为一行来保持更简短。  包含了额外的代码行以便更容易解释发生了什么。

# 导入 Python 库代码
import os
import urllib.request
import ssl
import json

# 从环境变量获取 Cato API 密钥
cato_api_key = os.getenv("CATO_API_KEY")

# 创建要发送的 GraphQL 请求
get_total_admins = '''{
    admins (accountID: 12345) {
        total        
    }
}'''
graphql_query = {'query': get_total_admins}

# 构建 HTTP 请求
cato_api_url = "https://api.catonetworks.com/api/v1/graphql2"
headers = {'x-api-key': cato_api_key,
           'Content-Type':'application/json'}
unverified_ctx = ssl._create_unverified_context()
json_post = json.dumps(graphql_query)
json_post_encoded = json_post.encode()
request = urllib.request.Request(url=cato_api_url, data=json_post_encoded, headers=headers)

# 发送查询并将响应转换为 Python 字典
response = urllib.request.urlopen(request, context=unverified_ctx, timeout=30)
json_response_encoded = response.read()
json_response = json_response_encoded.decode()
get_admins_total_result = json.loads(json_response)

# 从返回的数据中提取总计并打印出来
total = get_admins_total_result['data']['admins']['total']
print('定义在您的账户中的管理员总数是: {}'.format(total))

注意

重要! 本程序作为如何使用 Python 访问 Cato API 的演示提供。 这不是官方的 Cato 发行,并且不提供支持保证。 错误处理仅限于脚本与 API 协作所需的最少量,可能不足以用于实际生产环境。

所有问题或反馈应发送至 api@catonetworks.com

下图展示了在程序运行时发生的事件顺序:

  1. 程序创建一个 JSON 文档,并将其发送到 Cato API GraphQL 服务器。

  2. Cato API GraphQL 服务器检查以确保在 JSON 文档中定义的 API 调用是正确的,并从 Cato 服务中获取请求的数据。

  3. Cato API GraphQL 服务器将数据返回给程序,并以 JSON 文件的形式呈现。

Cato_API_FLow.jpeg

导入 Python 库代码

使用 Python 作为示例程序的原因之一是丰富的库集合的可用性。  这些库提供了可以处理广泛任务的函数和对象。  我们现在将逐个查看每个导入的库,并提供解释其必要性的备注。

import os
  • os库提供了一个函数,允许代码访问操作系统的环境变量中包含的数据。

import urllib.request
  • urllib 库中的 request 模块定义了一个创建对象的 Request 类,这些对象可以处理通过 URL 访问的远程服务器的通信。

  • 这将使可能发送 Cato API 请求到 Cato GraphQL API 服务器成为可能

import ssl
  • ssl库用于创建一个自定义的未验证上下文,用于发送到Cato GraphQL API服务器的请求。

import json
  • 这个库包含的函数可以将 Python 字典转换成 JSON 字符串,反之亦然。

  • 在两个不同格式之间的转换能力使编写可以处理 JSON 文档的代码变得更容易。

获取 Cato API 密钥

这行代码使用 getenv 库函数从环境变量中读取 API 密钥并将其赋值给一个变量。

cato_api_key = os.getenv("CATO_API_KEY")

Cato GraphQL服务器希望在HTTP头中收到此密钥。  该密钥不会随 JSON 文档一起提供,因为 GraphQL 规范未将授权包括在内。  在 JSON 文档中包含授权是对规范的违反。  Cato API 密钥通过 Cato 管理应用程序生成。  有关创建API密钥的更多信息,请参阅生成Cato API的API密钥

注意

警告! 虽然可以将 Cato API 密钥硬编码到代码中,但强烈建议不要这么做。

创建要发送的 GraphQL 请求

接下来的几行代码创建一个 Python 目录,包含一个键/值对。  使用一个定义将发送到 GraphQL 服务器的查询的 Python 多行字符串构建该条目的值。

get_total_admins = '''{
    admins (accountID: 12345) {
        total    
    }
}'''
graphql_query = {'query': get_total_admins}

Cato GraphQL 服务器会将此字符串解释为:执行 get_total_admins 函数,向其传递两个参数 (accountID 和 类型) 并仅返回 "总计" 的实体数量。  或者更直接地说,"返回为示例账户 # 12345 定义的管理员实体总数"。  这个特定的admins API调用示例展示了GraphQL API的一个重要优势

  • 服务器只返回应用程序请求的数据

事实是,admins 调用可以返回更多数据。  例如,可以请求应用程序请求admins返回每个管理员的详细信息。  然而,该应用程序只需要知道管理员的总数。  GraphQL 的这个特性可以避免所谓的过度获取,并且可以大大简化实现应用程序所需的代码。

构建 HTTP 请求

在程序的此部分构建一个请求对象。  此对象将用于通过HTTPS向GraphQL服务器发送API调用。 此请求对象需要由其他几个需要先创建的对象提供的信息。   首先,构建一个简单的字符串对象以包含请求对象将发送查询到的GraphQL服务器的URL。

cato_api_url = "https://api.catonetworks.com/api/v1/graphql2"

注意

注意:一个GraphQL API为所有API调用使用相同的URL。  调用的详细信息,例如参数,在JSON文档中提供。  这与REST API不同,后者为每次API调用使用不同的URL,并通过将参数附加到URL来传递参数。  使用不凌乱参数的单一URL被认为是GraphQL API的另一个优点。 

接下来创建一个字典来定义两个HTTP标头。  请求对象使用这些标头来构造一个超文本传输协议POST请求,该请求将被GraphQL服务器接受。  如果没有这些标头,超文本传输协议POST请求将被服务器拒绝。

headers = {'x-api-key': cato_api_key, 
 'Content-Type':'application/json'}

下一行代码创建一个SSL上下文对象。 Python使用此对象来确定它应该如何加密超文本传输协议请求并使用传输层安全性(TLS)发送它们。 这里我们创建一个不验证证书的SSL上下文对象。 这是为了避免在受限于上游TLS检查的网络中出现证书错误。

unverified_ctx = ssl._create_unverified_context()

注意

警告!使用未验证的SSL上下文对象意味着不会进行任何检查以确保证书有效。 Cato Networks建议您不要在生产环境中使用这种方法。 如何加强安全性的详细信息超出了本文档的范围。

接下来的两行代码将包含Cato API调用的Python字典转换为字符串,并将该字符串编码为字节。  第二步是为了允许字符串通过网络传输。

json_post = json.dumps(graphql_query)
json_post_encoded = json_post.encode()

最后,创建请求对象,程序现在准备好将get_total_admins调用发送到服务器。

request = urllib.request.Request(url=cato_api_url, data=json_post_encoded, headers=headers)

发送查询并处理响应

在这里,程序通过调用urllib库的urlopen函数将请求发送到GraphQL服务器。  调用此函数 将返回一个 HTTPResponse对象。  

response = urllib.request.urlopen(request, context=unverified_ctx, timeout=30)

注意

警告!调用urlopen函数可能会导致错误生成。  例如,GraphQL服务器可能由于语法错误而已拒绝请求,或者网络问题可能导致超时(即30秒后无响应)。  这里不处理这些错误。

urlopen函数返回的对象包括一个body字段,包含服务器返回的JSON文档。  可以通过执行其read方法从对象中提取该内容,该方法返回一个字节对象。  然后通过调用字节对象的decode方法将此字节对象转换为字符串对象。

json_response_encoded = response.read()
json_response = json_response_encoded.decode()

该解码的字符串包含一个JSON文档,其格式如下:

{
 "data" : {
 "admins" : {
 "total": 4
 }
 }
}

如您所见,返回数据的格式非常类似于发送到服务器的请求的格式。  这是有意为之的,是使用GraphQL规范实现API的另一个优点。  这种方法通过保持返回的数据与请求的格式相同来简化应用程序的编码。

程序此部分的最后一行代码使用json库函数'loads'将返回的JSON字符串转换为Python嵌套字典。  

get_total_admin_result = json.loads(json_response)

从返回的数据中提取总数并打印出来

代码的最后两行从服务器返回的total字段中提取值,并将其打印到控制台。 

total = get_total_admins_result['data']['get_total_admins']['total']
print('为您的账户定义的管理员总数为: {}'.format(total)) 

输出将如下:

为您的账户定义的管理员总数为: 4

摘要

本文档的目标是向读者展示使用Cato API是多么容易。  未包括Cato API的详细信息,也未编写代码来处理错误。  相反,使用了一个简单的Python程序来突出显示Cato API应用程序的最重要元素。  这些是:

  • 创建一个Cato API调用并将其添加到JSON文档

  • 获取Cato API密钥

  • 创建包含Cato API 密钥并已定义所发送数据的数据格式(JSON)的超文本传输协议标头

  • 使用TLS加密的超文本传输协议POST命令将JSON文档(编码为字节)发送到Cato GraphQl API服务器

  • 将服务器返回的响应对象转换为JSON文档

  • 将JSON文档转换为程序可以使用的格式

这篇文章有帮助吗?

5 人中有 5 人觉得有帮助

0 条评论