GithubAPI

Introduction

  • 在前面学习了一个简单的API(Application Program Interface )国际空间站 International Space Station (ISS),我们可以通过向国际空间站网页服务器发出一个数据请求,并可获得空间站的一些信息。但是通常情况下想要通过API获取一个网站服务器的数据是需要授权的。比如你想利用Reddit API 来获取一些你自己的私人信息,Reddit这个网站肯定是不愿意别人随便获得这种私人数据,所以你的API必须获得Reddit网站的授权才可以。
  • API可以使用户开发很有意思的应用和服务,为了确保API能被所有用户获取和并且能相应用户的请求,API会限制你在短时间内进行大量的请求、这就是速率限制,确保了一个用户不会因为太多太快的请求而使API服务器超载。
  • 本文会学习如何利用Github API从用户以及仓库中拉取一些有意思的数据。

API Authentication

为了使得Github API得到Github的授权,我们需要利用访问令牌(access token)。一个访问令牌是一个凭证(是一个字符串),可以在这里获取,有了这个凭证,API就可以读取以及关联你的账户。一般使用令牌而不是账号和密码是因为:

  • 通常,你会从一个脚本来访问API。如果你把你的账号和密码输入到这个脚本中,那么别人就有可能会设法获取到它,他们可以管理你的账户。但是如果你使用的是令牌,如果有安全漏洞,你可以取消这个令牌,而不用冒着账号被盗的风险。
  • 令牌一般访问的数据有限制,举例来说,你可以生成一个令牌,允许它对你的Github进行写操作,或者只有读操作。这使你能够自定义使得令牌更安全,而且只有读操作权限的话讲不会产生潜在不安全或者共享的脚本。
  • 用户Vik Paruchuri生成的令牌:1f36137fbbe1602f779300dad26e4c1b7fbab631
  • 通常如果我们想API提出一个请求时,我们需要将令牌信息传送过去:
# Create a dictionary of headers, with our Authorization header. headers = {"Authorization": "token 1f36137fbbe1602f779300dad26e4c1b7fbab631"} # Make a GET request to the Github API with our headers. # This API endpoint will give us details about Vik Paruchuri. response = requests.get("https://api.github.com/users/VikParuchuri", headers=headers) # Print the content of the response. As you can see, this token is associated with the account of Vik Paruchuri. print(response.json()) # his will tell you which organizations a Github user is in. response = requests.get("https://api.github.com/users/VikParuchuri/orgs", headers=headers) orgs = response.json() print(orgs) ''' {'subscriptions_url': 'https://api.github.com/users/VikParuchuri/subscriptions', 'repos_url': 'https://api.github.com/users/VikParuchuri/repos', 'following_url': 'https://api.github.com/users/VikParuchuri/following{/other_user}', 'owned_private_repos': 17, 'blog': 'http://www.vikparuchuri.com', 'avatar_url': 'https://avatars.githubusercontent.com/u/913340?v=3', 'hireable': None, 'disk_usage': 711120, 'name': 'Vik Paruchuri', 'public_gists': 9, 'gists_url': 'https://api.github.com/users/VikParuchuri/gists{/gist_id}', 'bio': None, 'location': 'Boston, MA', 'collaborators': 4, 'starred_url': 'https://api.github.com/users/VikParuchuri/starred{/owner}{/repo}', 'type': 'User', 'html_url': 'https://github.com/VikParuchuri', 'gravatar_id': '', 'updated_at': '2015-08-19T18:44:48Z', 'url': 'https://api.github.com/users/VikParuchuri', 'email': '[email protected]', 'followers_url': 'https://api.github.com/users/VikParuchuri/followers', 'events_url': 'https://api.github.com/users/VikParuchuri/events{/privacy}', 'received_events_url': 'https://api.github.com/users/VikParuchuri/received_events', 'plan': {'name': 'medium', 'collaborators': 0, 'private_repos': 20, 'space': 976562499}, 'total_private_repos': 17, 'private_gists': 1, 'site_admin': False, 'company': 'dataquest.io', 'public_repos': 60, 'created_at': '2011-07-13T18:18:07Z', 'login': 'VikParuchuri', 'following': 10, 'organizations_url': 'https://api.github.com/users/VikParuchuri/orgs', 'followers': 100, 'id': 913340} [{'avatar_url': 'https://avatars.githubusercontent.com/u/11148054?v=3', 'description': None, 'repos_url': 'https://api.github.com/orgs/dataquestio/repos', 'url': 'https://api.github.com/orgs/dataquestio', 'login': 'dataquestio', 'events_url': 'https://api.github.com/orgs/dataquestio/events', 'members_url': 'https://api.github.com/orgs/dataquestio/members{/member}', 'id': 11148054, 'public_members_url': 'https://api.github.com/orgs/dataquestio/public_members{/member}'}] '''

Endpoints And Objects

API通常是用来让你获取数据库中特定对象的信息,比如上面那个例子,我们获取了VikParuchuri的数据。当然我们也可以使用相同的端点来获取Github上其他用户的信息。比如:https://api.github.com/users/torvalds 将会给我们Torvalds的信息。

# headers is loaded in.
response = requests.get("https://api.github.com/users/torvalds", headers=headers)
torvalds = response.json()

Other Objects

  • GithubAPI不仅仅只有用户对象,还有组织对象,比如https://api.github.com/orgs/dataquestio将会显示Dataquest Github organization的信息,https://api.github.com/repos/octocat/Hello-World将会给你用户octocat的Hello-World repository 仓库的信息。关于端点(endpoints)的信息全在这里。
response = requests.get("https://api.github.com/repos/octocat/Hello-World", headers=headers)
hello_world = response.json()
  • 总的来说就是你获取了一个API的授权令牌,你就可以通过这些端点来访问相应对象的信息。

Pagination

有时,一个特定的请求会返回很多对象。这可能发生在比如你想获取一个用户所有的仓库信息,那么将返回一个很长的列表。返回太多的数据将需要很长时间,使得将服务器速度慢下来。例如,如果用户有1000 +仓库,请求他们可能需要10 +秒。这不是一个很棒的用户体验,所以API提供者实现了分页技术。这意味着API提供者每个页面只会返回一个特定数量的记录。您可以指定您想要访问的页号。访问所有的页面,你需要写一个循环。

  • 我们想要获取一个用户标记星号的仓库,其中per_page表示每页显示的对象个数(不能高于上限,否则这个分页就没作用),page表示想要获取的页数:
params = {"per_page": 50, "page": 1} response = requests.get("https://api.github.com/users/VikParuchuri/starred", headers=headers, params=params) page1_repos = response.json()
'''
page1_repos list (<class 'list'>) [{'archive_url': 'https://api.github.com/repos/stackforge/requests-mock/{archive_format}{/ref}',
 'assignees_url': 'https://api.github.com/repos/stackforge/requests-mock/assignees{/user}',
 'blobs_url': 'https://api.github.com/repos/stackforge/requests-mock/git/blobs{/sha}',
 'branches_url': 'https://api.github.com/repos/stackforge/requests-mock/branches{/branch}',
'''
params = {"per_page": 50, "page": 2} response = requests.get("https://api.github.com/users/VikParuchuri/starred", headers=headers, params=params) page2_repos = response.json()

User-Level Endpoints

# Making a GET request to https://api.github.com/user will give you information about the user that the authentication token is for.
response = requests.get("https://api.github.com/user", headers=headers)
user = response.json()

POST Requests

前面我们一直用到的是GET请求,这个请求是返回服务器信息。还有一类请求叫做POST请求,POST请求用来向服务器传送信息,然后在服务器上创建对象。比如,我们利用POST请求创建一个新的仓库。
不同的API端点会选择不同类型的请求,不是所有的端点都可以接受POST/GET请求,可以查阅 API documentation 来查询哪种端点接受哪种请求。

  • 在当前授权的用户下面创建两个分别名为test以及learning-about-apis的仓库
# Create the data we'll pass into the API endpoint.  This endpoint only requires the "name" key, but others are optional.
payload = {"name": "test"}

# We need to pass in our authentication headers!
response = requests.post("https://api.github.com/user/repos", json=payload, headers=headers)
print(response.status_code) payload = {"name": "learning-about-apis"} response = requests.post("https://api.github.com/user/repos", json=payload, headers=headers) status = response.status_code
'''
201
'''

PUT/PATCH Requests

有的时候我们并不想创建新的对象,我们只想更新一个已知的对象,那么需要用到PATCH和PUT请求。当我们想修改一个对象的一些属性时,而并不想将整个对象传送给服务器时利用PATCH请求,当我们需要将整个对象传送给服务器来替换原有的版本时需要用到PUT请求。

  • 修改test仓库的描述信息为The best repository ever!。当执行成功时PATCH请求通常返回200的状态码。
payload = {"description": "The best repository ever!", "name": "test"}
response = requests.patch("https://api.github.com/repos/VikParuchuri/test", json=payload, headers=headers)
print(response.status_code)
''' 200 '''
  • 修改test的描述信息为:Learning about requests!.
payload = {"description": "Learning about requests!", "name": "learning-about-apis"}
response = requests.patch("https://api.github.com/repos/VikParuchuri/learning-about-apis", json=payload, headers=headers)
status = response.status_code

DELETE Requests

最后一个主要的请求类型是DELETE请求,这个请求将删除服务器上的对象。我们可以理由DELETE请求删除某个仓库。

  • 删除前面创建的两个仓库:
response = requests.delete("https://api.github.com/repos/VikParuchuri/test", headers=headers)
print(response.status_code) response = requests.delete("https://api.github.com/repos/VikParuchuri/learning-about-apis", headers=headers) status = response.status_code
print(status)
'''
204
204
'''

你可能感兴趣的:(GithubAPI)