本文介绍了 Cato API 并分析了一个 Python 应用示例。
Cato API 是根据 GraphQL 规范 实现的。 即使 GraphQL 旨在生成易于使用的 API,学习使用任何新技术仍然需要开发人员投入时间。 本文档的目标是减少此投资的程度,并介绍一个小的 Python 应用程序,该程序执行 admins
Cato API 调用并简单地返回为一个账户定义的管理员的数量。 通过这样做,读者被介绍到 Cato GraphQL API 应用程序的最重要元素。
注意
注意:
预计读者对以下内容有基本了解:
-
脚本或编程(例如,您熟悉变量和代码库等概念)
-
JSON 规范(例如,您已经处理过 JSON 文档)
-
网络设备(例如,您知道超文本传输协议的存在以及服务器是什么)
对 Python 语言有一些经验会有帮助,但应该仍然可以在没有这种经验的情况下理解这篇文章。
此处展示的应用程序是用 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
下图展示了在程序运行时发生的事件顺序:
-
程序创建一个 JSON 文档,并将其发送到 Cato API GraphQL 服务器。
-
Cato API GraphQL 服务器检查以确保在 JSON 文档中定义的 API 调用是正确的,并从 Cato 服务中获取请求的数据。
-
Cato API GraphQL 服务器将数据返回给程序,并以 JSON 文件的形式呈现。
使用 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 文档的代码变得更容易。
这行代码使用 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 密钥硬编码到代码中,但强烈建议不要这么做。
接下来的几行代码创建一个 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 的这个特性可以避免所谓的过度获取,并且可以大大简化实现应用程序所需的代码。
在程序的此部分构建一个请求对象。 此对象将用于通过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)
0 条评论
文章评论已关闭。