A-A+

如何在Python 3中使用Web API

2019年07月23日 编程开发 暂无评论 阅读 157 次

介绍

API或一个 pplication P rogram 覆盖整个院落,使开发人员能够一个应用程序与其他整合。他们以有限的方式暴露了一些程序的内部工作。

您可以使用API​​从其他程序获取信息,或自动执行您在Web浏览器中通常执行的操作。有时您可以使用API​​来执行您不能以任何其他方式执行的操作。数量惊人的网络资产提供基于网络的API以及更熟悉的网站或移动应用程序,包括Twitter,Facebook,GitHub和DigitalOcean。

如果您已经通过一些关于如何使用Python 3编写代码的教程,并且熟悉Python的语法,结构和一些内置函数,那么您可以编写利用您喜欢的API的Python程序。

在本指南中,您将学习如何使用Python和DigitalOcean API来检索有关您的DigitalOcean帐户的信息。然后我们将看看如何将您学到的知识应用到GitHub的API中

完成后,您将了解Web API中常见的概念,并且您将获得可用于尝试其他服务的API的分步过程和工作代码示例。

先决条件

在开始本指南之前,您需要以下内容:

第1步 - 熟悉API

使用新API的第一步是找到文档,并获得您的支持。DigitalOcean API文档从https://developers.digitalocean.com/开始。要查找其他服务的API,请搜索站点名称和“API” - 并非所有服务都在其首页上提升它们。

有些服务有API包装器。API包装器是您在系统上安装的代码,用于使API更易于使用您选择的编程语言。本指南不使用任何包装器,因为它们隐藏了API的大部分内部工作方式,并且通常不会公开API可以执行的所有操作。当您想要快速完成某些工作时,包装器可能很棒,但是如果能够充分了解API本身可以做什么,将有助于您确定包装器是否对您的目标有意义。

首先,请访问https://developers.digitalocean.com/documentation/v2/上的DigitalOcean API简介,并尝试仅了解有关如何发送请求的基本知识以及响应中的预期内容。此时,您只想学习三件事:

  1. 请求是什么样的?它们都只是URL吗?对于更详细的请求,数据是如何格式化的?它通常是Web浏览器使用的JSON或查询字符串参数,但有些使用XML或自定义格式。
  2. 回复是什么样的?API文档将显示示例请求和响应。您是否会获得JSON,XML或其他类型的响应?
  3. 什么进入请求或响应标头?通常,请求标头包含您的身份验证令牌,响应标头提供有关您使用服务的最新信息,例如您与速率限制的距离。

DigitalOcean API使用HTTP 方法(有时称为动词)来指示您是在尝试读取现有信息,创建新信息还是删除某些内容。这部分文档说明了使用的方法以及用途。通常,GET请求比POST更简单,但是当你在这里完成时,你不会注意到太多的差异。

API文档的下一部分讨论了服务器如何响应您的请求。通常,请求成功或失败。当它失败时,原因是请求有问题,或者服务器上有问题。所有这些信息都是使用HTTP状态代码传递的,这些代码是分为类别的3位数字。

  • 200系列意味着“成功” - 您的请求是有效的,并且响应是逻辑上遵循的。
  • 400系列意味着“错误的请求” - 请求有问题,因此服务器没有按照您的意愿处理它。HTTP 400级别错误的常见原因是格式错误的请求和身份验证问题。
  • 500系列意味着“服务器错误” - 您的请求可能没问题,但由于您无法控制的原因,服务器现在无法给您提供良好的响应。这些应该很少见,但您需要注意这种可能性,以便您可以在代码中处理它们。

在尝试对其执行任何操作之前,您的代码应始终检查HTTP状态代码以获取任何响应。如果你不这样做,你会发现自己在用不完整的信息进行故障排除时会浪费时间。

现在您已经了解了如何发送请求以及在响应中查找的内容,现在是时候发送第一个请求了。

第2步 - 从Web API获取信息

您的DigitalOcean帐户包含一些您可能未在Web UI中看到的管理信息。API可以为您提供熟悉信息的不同视图。只是看到这个替代视图有时会引发关于您可能想要使用API​​做什么的想法,或者揭示您不了解的服务和选项。

让我们从为脚本创建项目开始。为项目创建一个名为的新目录apis

  • mkdir apis

然后导航到这个新目录:

  • cd apis

为这个项目创建一个新的virtualenv:

  • python3 -m venv apis

激活virtualenv:

  • source apis/bin/activate

然后安装请求库,我们将在脚本中使用它们在脚本中发出HTTP请求:

  • pip install requests

配置环境后,创建一个名为的新Python文件do_get_account.py,并在文本编辑器中将其打开。通过导入库来启动此程序以使用JSON和HTTP请求。

do_get_account.py
import json
import requests

这些import语句加载Python代码,允许我们使用JSON数据格式和HTTP协议。我们正在使用这些库,因为我们对如何发送HTTP请求或如何解析和创建有效JSON的细节不感兴趣; 我们只想用它们来完成这些任务。本教程中的所有脚本都是这样开始的。

接下来,我们要设置一些变量来保存每个请求中相同的信息。这使我们不必一次又一次地输入它,并为我们提供了一个单独的位置来进行更新,以防万一发生任何变化。在import语句之后将这些行添加到文件中。

do_get_account.py
...
api_token = 'your_api_token'
api_url_base = 'https://api.digitalocean.com/v2/'

api_token变量是一个包含DigitalOcean API令牌的字符串。使用您自己的令牌替换示例中的值。该api_url_base变量是从DigitalOcean API中的每个URL开始的字符串。我们稍后会在代码中附加它。

接下来,我们需要按API文档描述的方式设置HTTP请求标头。将这些行添加到文件中以设置包含您的请求标头的字典

do_get_account.py
...
headers = {'Content-Type': 'application/json',
           'Authorization': 'Bearer {0}'.format(api_token)}

这会一次设置两个标头。的Content-Type报头通知服务器期望在请求的主体JSON格式的数据。该Authorization头需要包括我们的道理,所以我们使用Python的字符串格式化逻辑,我们插入api_token变量到字符串作为我们创建的字符串。我们可以将令牌放在这里作为文字字符串,但是将它分开会让事情变得更容易:

  • 如果您需要替换令牌,当它是一个单独的变量时,更容易看到该做什么。
  • 如果您想与某人分享您的代码,则可以更轻松地删除您的API令牌,并让您的朋友更轻松地查看他们的位置。
  • 它是自我记录的。如果API令牌仅用作字符串文字,那么阅读代码的人可能无法理解他们正在查看的内容。

现在我们已经涵盖了这些设置细节,现在是时候实际发送请求了。您的倾向可能只是开始创建和发送请求,但有更好的方法。如果你把这个逻辑放到一个处理请求发送和阅读响应的函数中,你就必须更清楚地思考你正在做什么。您最终还将获得使测试和重用更直接的代码。这就是我们要做的。

此函数将使用您创建的变量来发送请求,并在Python字典中返回帐户信息。

为了在这个早期阶段保持逻辑清晰,我们还不会做任何详细的错误处理,但我们会尽快补充。

定义获取帐户信息的功能。在功能之后命名一个函数总是一个好主意:这个获取帐户信息,所以我们称之为get_account_info

do_get_account.py
...
defget_account_info():

    api_url = '{0}account'.format(api_url_base)

    response = requests.get(api_url, headers=headers)

    if response.status_code == 200:
        return json.loads(response.content.decode('utf-8'))
    else:
        return None

我们api_url使用Python的字符串格式化方法来构建值,类似于我们在头文件中使用它的方式; 我们将API的基本URL附加在字符串前面account以获取URL https://api.digitalocean.com/v2/account,即应返回帐户信息的URL。

response变量包含由Python requests 模块创建的对象。此行将请求发送到我们使用我们在脚本开头定义的标头创建的URL,并从API返回响应。

接下来,我们查看响应的HTTP状态代码。

如果200是成功的响应,那么我们使用json模块的loads函数将字符串加载为JSON。我们加载的字符串是response对象 的内容response.content。该.decode('utf-8')部分告诉Python该内容使用UTF-8字符集进行编码,因为DigitalOcean API的所有响应都是。该json模块创建一个对象了这一点,这是我们作为这个函数的返回值使用。

如果响应没有 200,那么我们返回None,这是Python中的一个特殊值,我们可以在调用此函数时检查它。你会注意到我们现在只是忽略了任何错误。这是为了保持“成功”逻辑的清晰。我们将尽快添加更全面的错误检查。

现在调用此函数,检查以确保它得到了良好的响应,并打印出API返回的详细信息:

do_get_account.py
...
account_info = get_account_info()

if account_info is not None:
    print("Here's your info: ")
    for k, v in account_info['account'].items():
        print('{0}:{1}'.format(k, v))

else:
    print('[!] Request Failed')

account_info = get_account_info()account_info变量设置为从调用返回的任何内容get_account_info(),因此它将是特殊值,None或者它将是有关该帐户的信息的集合。

如果不是None,那么我们使用items()所有Python字典具有的方法在自己的行上打印出每条信息。

否则(即,如果account_infoNone),我们打印错误消息。

我们暂停一会儿。这个if带有双重否定的声明起初可能会感觉很尴尬,但它是一种常见的Python习语。它的优点在于保持成功运行的代码非常接近条件而不是处理错误情况。

如果您愿意,可以采用其他方式实现,并且自己实际编写代码可能是一个很好的练习。而不是if account_info is not None:你可能会开始,if account_info is None:看看其余的如何落实到位。

保存脚本并试用:

  • python do_get_account.py

输出看起来像这样:

Output
Here's your info: 
droplet_limit:25
email:sammy@digitalocean.com
status:active
floating_ip_limit:3
email_verified:True
uuid:123e4567e89b12d3a456426655440000
status_message:

您现在知道如何从API检索数据。接下来,我们将继续讨论更有趣的事情 - 使用API​​来更改数据。

第3步 - 修改服务器上的信息

在使用只读请求练习之后,是时候开始进行更改了。让我们通过使用Python和DigitalOcean API为您的DigitalOcean帐户添加SSH密钥来探索这一点。

首先,请查看SSH密钥的API文档,可从https://developers.digitalocean.com/documentation/v2/#ssh-keys获取

API允许您列出帐户中的当前SSH密钥,还可以添加新密钥。获取SSH密钥列表的请求很像获取帐户信息的请求。但是响应不同:与帐户不同,您可以拥有零个,一个或多个SSH密钥。

为此脚本创建一个名为的新文件do_ssh_keys.py,并将其与最后一个文件完全相同。导入jsonrequests模块,这样您就不必担心JSON或HTTP协议的细节。然后将您的DigitalOcean API令牌添加为变量,并在字典中设置请求标头。

do_ssh_keys.py
import json
import requests


api_token = 'your_api_token'
api_url_base = 'https://api.digitalocean.com/v2/'
headers = {'Content-Type': 'application/json',
           'Authorization': 'Bearer {0}'.format(api_token)}

我们将创建用于获取SSH密钥的功能类似于我们用于获取帐户信息的功能,但这次我们将更直接地处理错误。

首先,我们将进行API调用并将响应存储在 response响应变量中。但是api_url,它与先前的脚本不同; 这次需要指出https://api.digitalocean.com/v2/account/keys

将此代码添加到脚本中:

do_ssh_keys.py
...
def get_ssh_keys():

    api_url = '{0}account/keys'.format(api_url_base)

    response = requests.get(api_url, headers=headers)

现在让我们通过查看响应中的HTTP状态代码来添加一些错误处理。如果是的话200,我们将把响应的内容作为字典返回,就像我们之前做的那样。如果是其他任何内容,我们将打印与状态代码类型相关的有用错误消息,然后返回None

将这些行添加到get_ssh_keys函数中:

do_ssh_keys.py
...

    if response.status_code >= 500:
        print('[!] [{0}] Server Error'.format(response.status_code))
        return None
    elif response.status_code == 404:
        print('[!] [{0}] URL not found: [{1}]'.format(response.status_code,api_url))
        return None  
    elif response.status_code == 401:
        print('[!] [{0}] Authentication Failed'.format(response.status_code))
        return None
    elif response.status_code == 400:
        print('[!] [{0}] Bad Request'.format(response.status_code))
        return None
    elif response.status_code >= 300:
        print('[!] [{0}] Unexpected Redirect'.format(response.status_code))
        return None
    elif response.status_code == 200:
        ssh_keys = json.loads(response.content.decode('utf-8'))
        return ssh_keys
    else:
        print('[?] Unexpected Error: [HTTP {0}]: Content: {1}'.format(response.status_code, response.content))
    return None

此代码通过查看响应中的HTTP状态代码来处理六种不同的错误情况。

  • 代码500或更高代表服务器上的问题。这些应该很少见,并且它们不是由请求问题引起的,因此我们只打印状态代码。
  • 404“未找到”的代码,可能源于URL中的拼写错误。对于此错误,我们会打印状态代码和导致它的URL,以便您了解失败的原因。
  • 代码401表示身份验证失败。最可能的原因是错误或缺失api_key
  • 300范围中的代码表示重定向。DigitalOcean API不使用重定向,因此永远不会发生这种情况,但是当我们处理错误时,检查它并没有什么坏处。很多错误都是由程序员认为永远不会发生的事情引起的。
  • 代码200表示请求已成功处理。为此,我们不打印任何东西。我们只使用我们在前一个脚本中使用的相同语法将ssh键作为JSON对象返回。
  • 如果响应代码是其他任何内容,我们将状态代码打印为“意外错误”。

这应该可以处理我们可能通过调用API获得的任何错误。此时,我们有一个错误消息和None对象,或者我们有成功和一个包含零个或多个SSH密钥的JSON对象。我们的下一步是打印出来:

do_ssh_keys.py
...

ssh_keys = get_ssh_keys()

if ssh_keys is not None:
    print('Here are your keys: ')
    for key, details in enumerate(ssh_keys['ssh_keys']):
        print('Key {}:'.format(key))
        for k, v in details.items():
            print('  {0}:{1}'.format(k, v))
else:
    print('[!] Request Failed')

因为响应包含SSH密钥的列表(或数组),所以我们希望迭代整个列表以查看所有密钥。我们使用Python的enumerate方法。这与items字典可用的方法类似,但它适用于列表。

我们使用enumerate而不仅仅是一个for循环,因为我们希望能够告诉我们对任何给定密钥的列表有多远。

每个密钥的信息都作为字典返回,因此我们使用与for k,v in details.items():前一个脚本中的帐户信息字典相同的代码。

运行此脚本,您将获得帐户中已有的SSH密钥列表。

  • python get_ssh_keys.py

输出看起来像这样,具体取决于您帐户中已有多少SSH密钥。

Output
Here are your keys: 
Kcy 0:
  id:280518
  name:work
  fingerprint:96:f7:fb:9f:60:9c:9b:f9:a9:95:01:5c:5c:2c:d5:a0
  public_key:ssh-rsa AAAAB5NzaC1yc2cAAAADAQABAAABAQCwgr9Fzc/YTD/V2Ka5I52Rx4I+V2Ka5I52Rx4Ir5LKSCqkQ1Cub+... sammy@work
Kcy 1:
  id:290536
  name:home
  fingerprint:90:1c:0b:ac:fa:b0:25:7c:af:ab:c5:94:a5:91:72:54
  public_key:ssh-rsa AAAAB5NzaC1yc2cAAAABJQAAAQcAtTZPZmV96P9ziwyr5LKSCqkQ1CubarKfK5r7iNx0RNnlJcqRUqWqSt... sammy@home

现在您可以在帐户中列出SSH密钥,此处的最后一个脚本将是一个向列表添加新密钥的脚本。

在我们添加新的SSH密钥之前,我们需要生成一个。要更全面地处理此步骤,请查看教程如何设置SSH密钥

但是,出于我们的目的,我们只需要一个简单的密钥。执行此命令以在Linux,BSD或MacOS上生成新命令。如果您愿意,可以在现有的Droplet上执行此操作。

  • ssh-keygen -t rsa

出现提示时,输入文件以保存密钥,但不提供密码。

Output
Generating public/private rsa key pair.
Enter file in which to save the key (/home/sammy/.ssh/id_rsa): /home/sammy/.ssh/sammy 
Created directory '/home/sammy/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/sammy/.ssh/sammy.
Your public key has been saved in /home/sammy/.ssh/sammy.pub.
...

记下公钥文件的保存位置,因为脚本需要它。

启动一个新的Python脚本,然后调用它add_ssh_key.py,并像其他脚本一样启动它:

add_ssh_key.py
import json
import requests


api_token = 'your_api_token'
api_url_base = 'https://api.digitalocean.com/v2/'
headers = {'Content-Type': 'application/json',
           'Authorization': 'Bearer {0}'.format(api_token)}

我们将使用一个函数来提出我们的请求,但这个会稍有不同。

创建一个名为的函数add_ssh_key,该函数将接受两个参数:用于新SSH密钥的名称,以及本地系统上密钥本身的文件名。该函数将读取文件,并发出HTTP POST请求,而不是GET

add_ssh_key.py
...

def add_ssh_key(name, filename):

    api_url = '{0}account/keys'.format(api_url_base)

    with open(filename, 'r') as f:
        ssh_key = f.readline()

    ssh_key = {'name': name, 'public_key': ssh_key}

    response = requests.post(api_url, headers=headers, json=ssh_key)

该行with open(filename, 'r') as f:以只读模式打开文件,后面的行从文件中读取第一行(也是唯一一行),并将其存储在ssh_key变量中。

接下来,我们ssh_key使用API​​期望的名称和值来创建一个Python字典。

但是,当我们发送请求时,还有一些新内容。它是一个POST而不是一个GET,我们需要发送请求ssh_key的主体POST,编码为JSON。该requests模块将为我们处理细节; requests.post告诉它使用该POST方法,并json=ssh_key告诉它ssh_key在请求的主体中发送变量,编码为JSON。

根据API,响应将是201成功的HTTP ,而不是200,响应的主体将包含我们刚刚添加的密钥的详细信息。

将以下错误处理代码添加到该add_ssh_key函数。它类似于以前的脚本,除了这次我们必须寻找代码201而不是200成功:

add_ssh_key.py
...
    if response.status_code >= 500:
        print('[!] [{0}] Server Error'.format(response.status_code))
        return None
    elif response.status_code == 404:
        print('[!] [{0}] URL not found: [{1}]'.format(response.status_code,api_url))
        return None
    elif response.status_code == 401:
        print('[!] [{0}] Authentication Failed'.format(response.status_code))
        return None
    elif response.status_code >= 400:
        print('[!] [{0}] Bad Request'.format(response.status_code))
        print(ssh_key )
        print(response.content )
        return None
    elif response.status_code >= 300:
        print('[!] [{0}] Unexpected redirect.'.format(response.status_code))
        return None
    elif response.status_code == 201:
        added_key = json.loads(response.content)
        return added_key
    else:
        print('[?] Unexpected Error: [HTTP {0}]: Content: {1}'.format(response.status_code, response.content))
        return None

此函数与之前的函数一样,返回任一None或响应内容,因此我们使用与以前相同的方法来检查结果。

接下来,调用函数并处理结果。将路径传递给新创建的SSH密钥作为第二个参数:

add_ssh_key.py
...
add_response = add_ssh_key('tutorial_key', '/home/sammy/.ssh/sammy.pub')

if add_response is not None:
    print('Your key was added: ' )
    for k, v in add_response.items():
        print('  {0}:{1}'.format(k, v))
else:
    print('[!] Request Failed')

运行此脚本,您将收到一条消息,告诉您已添加新密钥。

  • python add_ssh_key.py

输出看起来像这样:

Output
Your key was added: 
  ssh_key:{'id': 9458326, 'name': 'tutorial_key', 'fingerprint': '64:76:37:77:c8:c7:26:05:f5:7b:6b:e1:bb:d6:80:da', 'public_key': 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCUtY9aizEcVJ65/O5CE6tY8Xodrkkdh9BB0GwEUE7eDKtTh4NAxVjXc8XdzCLKtdMwfSg9xwxSi3axsVWYWBUhiws0YRxxMNTHCBDsLFTJgCFC0JCmSLB5ZEnKl+Wijbqnu2r8k2NoXW5GUxNVwhYztXZkkzEMNT78TgWBjPu2Tp1qKREqLuwOsMIKt4bqozL/1tu6oociNMdLOGUqXNrXCsOIvTylt6ROF3a5UnVPXhgz0qGbQrSHvCEfuKGZ1kw8PtWgeIe7VIHbS2zTuSDCmyj1Nw1yOTHSAqZLpm6gnDo0Lo9OEA7BSFr9W/VURmTVsfE1CNGSb6c6SPx0NpoN sammy@tutorial-test'}

如果您忘记更改“成功”条件以查找HTTP 201而不是200,则会看到报告错误,但仍会添加密钥。您的错误处理会告诉您状态代码是201。你应该认识到作为200系列的一员,这表明成功。这是基本错误处理如何简化故障排除的示例。

使用此脚本成功添加密钥后,再次运行它以查看当您尝试添加已存在的密钥时会发生什么。

API将发回一个HTTP 422响应,您的脚本将转换为一条消息“SSH密钥已在您的帐户中使用。”:

Output
[!] [422] Bad Request
{'name': 'tutorial_key', 'public_key': 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCUtY9aizEcVJ65/O5CE6tY8Xodrkkdh9BB0GwEUE7eDKtTh4NAxVjXc8XdzCLKtdMwfSg9xwxSi3axsVWYWBUhiws0YRxxMNTHCBDsLFTJgCFC0JCmSLB5ZEnKl+Wijbqnu2r8k2NoXW5GUxNVwhYztXZkkzEMNT78TgWBjPu2Tp1qKREqLuwOsMIKt4bqozL/1tu6oociNMdLOGUqXNrXCsOIvTylt6ROF3a5UnVPXhgz0qGbQrSHvCEfuKGZ1kw8PtWgeIe7VIHbS2zTuSDCmyj1Nw1yOTHSAqZLpm6gnDo0Lo9OEA7BSFr9W/VURmTVsfE1CNGSb6c6SPx0NpoN sammy@tutorial-test'}
b'{"id":"unprocessable_entity","message":"SSH Key is already in use on your account"}'
[!] Request Failed

现在get_ssh_keys.py再次运行您的脚本,您将在列表中看到新添加的密钥。

通过少量修改,这两个脚本可以在您需要时快速向您的DigitalOcean帐户添加新的SSH密钥。此API中的相关功能允许您使用其唯一的密钥ID或指纹重命名或删除特定密钥。

让我们看看另一个API,看看你刚学到的技能是如何翻译的。

第4步 - 使用不同的API

GitHub也有一个API。您学习使用DigitalOcean API的所有内容都直接适用于使用GitHub API。

熟悉GitHub API,就像使用DigitalOcean一样。搜索API文档,并浏览“ 概述”部分。您将立即看到GitHub API和DigitalOcean API有一些相似之处。

首先,您会注意到所有API URL都有一个共同的根目录:https://api.github.com/。您知道如何将其用作代码中的变量,以简化并减少出错的可能性。

GitHub的API使用JSON作为其请求和响应格式,就像DigitalOcean一样,因此您知道如何发出这些请求并处理响应。

响应包括有关HTTP响应标头中的速率限制的信息,使用与DigitalOcean几乎相同的名称和完全相同的值。

GitHub使用OAuth进行身份验证,您可以在请求标头中发送令牌。该令牌的细节略有不同,但它的使用方式与您使用DigitalOcean API的方式完全相同。

也有一些差异。GitHub鼓励使用请求标头来指示您要使用的API的版本。您知道如何在Python中为请求添加标头。

GitHub还希望您User-Agent在请求中使用唯一字符串,这样如果您的代码导致问题,他们可以更轻松地找到您。你也可以用标题来处理这个问题。

GitHub API使用相同的HTTP请求方法,但也使用一个PATCH为某些操作调用的新方法。GitHub API用于GET读取信息,POST添加新项目以及PATCH修改现有项目。此PATCH请求是您希望在API文档中查找的内容。

并非所有GitHub API调用都需要身份验证。例如,您可以获取用户存储库的列表,而无需访问令牌。让我们创建一个脚本来发出请求并显示结果。

我们将简化此脚本中的错误处理,并仅使用一个语句来处理所有可能的错误。你并不总是需要代码来单独处理每种错误,但是如果只是为了提醒自己事情并不总是像你期望的那样,那么做错事情的习惯就是一个好习惯。

创建一个github_list_repos.py在编辑器中调用的新文件,并添加以下内容,这些内容应该非常熟悉:

github_list_repos.py
import json
import requests


api_url_base = 'https://api.github.com/'
headers = {'Content-Type': 'application/json',
           'User-Agent': 'Python Student',
           'Accept': 'application/vnd.github.v3+json'}

进口与我们一直使用的相同。这api_url_base是所有GitHub API开始的地方。

标题包括GitHub在其概述中提及的两个可选项,以及表示我们在请求中发送JSON格式数据的标题。

即使这是一个小脚本,我们仍然会定义一个函数,以保持我们的逻辑模块化并封装用于发出请求的逻辑。通常,您的小脚本会变成更大的脚本,因此努力做到这一点很有帮助。添加一个名为get_reposaccept 的函数作为参数:

github_list_repos.py

...
def get_repos(username):

    api_url = '{}orgs/{}/repos'.format(api_url_base, username)

    response = requests.get(api_url, headers=headers)

    if response.status_code == 200:
        return (response.content)
    else:
        print('[!] HTTP {0} calling [{1}]'.format(response.status_code, api_url))
        return None

在函数内部,我们构建了URL api_url_base,我们感兴趣的用户的名称,以及告诉GitHub我们想要存储库列表的URL的静态部分。然后我们检查响应的HTTP状态代码以确保它是200(成功)。如果成功,我们会返回响应内容。如果不是,那么我们打印出实际的状态代码和我们构建的URL,这样我们就可以知道我们可能出错的地方。

现在,调用该函数并传入您要使用的GitHub用户名。我们将octokit用于这个例子。然后将结果打印到屏幕:

github_list_repos.py

...
repo_list = get_repos('octokit')

if repo_list is not None:
    print(repo_list)
else:
    print('No Repo List Found')

保存文件并运行脚本以查看指定用户的存储库。

  • python github_list_repos.py

您将在输出中看到大量数据,因为在此示例中我们没有将响应解析为JSON,也没有将结果过滤到特定键。使用您在其他脚本中学到的知识来做到这一点。查看您获得的结果,看看是否可以打印出存储库名称。

这些GitHub API的优点在于您可以直接在Web浏览器中访问不需要身份验证的请求,这样您就可以将响应与您在脚本中看到的内容进行比较。尝试在浏览器中访问https://api.github.com/orgs/octokit/repos以查看响应。

到目前为止,您知道如何阅读文档并编写必要的代码,以便使用GitHub API发送更具体的请求以支持您自己的目标。

您可以在GitHub上的此存储库中找到本教程中所有示例的完整代码。

结论

在本教程中,您学习了如何将Web API用于两种风格略有不同的不同服务。您了解了包含错误处理代码的重要性,以使调试更容易,脚本更强大。您使用了Python模块requests并将json这些技术的详细信息隔离开来并完成工作,并将请求和响应处理封装在一个函数中,以使您的脚本更加模块化。

而且,在学习任何新的Web API时,您现在可以采用可重复的流程:

  1. 查找文档并阅读简介以了解如何与API交互的基础知识。
  2. 如果需要,请获取身份验证令牌,并编写具有基本错误处理功能的模块化脚本,以发送简单请求,响应错误并处理响应。
  3. 创建将从服务中获取所需信息的请求。

现在,巩固这些新获得的知识并找到另一个要使用的API,或者甚至是您在此处使用的API之一的其他功能。您自己的项目将有助于巩固您在此学到的知识。

 

原文来源:这里

给我留言

Copyright © 浩然东方 保留所有权利.   Theme  Ality 07032740

用户登录