赞
踩
上一次,我们新建了 core/rest_client.py 这个文件,并且可以使用其中的RestClient类来收发http请求。这一小节,我们接着上次的rest 请求客户端,向其中增加登录 Github的功能。
在官方文档的这里:
https://developer.github.com/v3/#authentication
和这里:
https://developer.github.com/v3/auth/
介绍了 Github api 支持的登录方式:
1.用户名密码登录。最直接的方式,向服务端发送用户名密码来登录。此外,特定的一些 api 只能用这个方式登录。
2.token登录。最常用的方式,使用一个特殊字符串 token 来代替用户名密码,完成用户登录权限验证。
3.SAML登录。企业级里常用的方式,可以和企业里其他用户认证方式结合。
4.two-factor 登录。要求二次鉴权的登录方式,比如手机验证码登录。
在本教程中,我们将实现用户名密码登录和token登录两种方式。
例1.用户名密码登录和token登录的实现
class
这里,通过修改 RestClient 类的初始化方法,添加了三个参数, username,password 和 token。
当 username 和 password 不为空时使用用户名密码登录,向 requests session 中添加 auth 信息。
当 token不为空时使用 token 登录,向 requests session 的 header 里的 Authorization 字段里添加 token 信息。
任务1. 修改 RestClient 类
上面例1的代码中,有一个bug, 当用户同时输入了username,password和token时,两种鉴权方式的信息都会被存入 session,这就有可能导致未知的错误,请尝试通过修改代码修复这个bug。
接下来我们要封装一个 Github 接口,来看看登录的效果。在封装这个接口之前,我们来看看目录结构:
如图所示,在 TUGithubAPI 工程目录下,我们新建了两个目录,分别是 api 和 core, core 里存放核心的工具类 RestClient, api 里则会存放封装好的接口类。而这两个目录外面还有一个 github.py,这个文件将作为总入口,提供给这个代码库的用户使用。
那么今天我们要用的 repos 接口是从 github 文档的这里查到的:
https://developer.github.com/v3/repos/
这里,我们注意到文档的导航栏里有:
这么多页面都挂在 Repositories 下面。没错,这些都是我们后续要实现的。现在我们的目录结构中,只有api/repositories/repos.py,那后面就会有其他这些,比如branches.py等。而其他接口则会放在其他目录下。比如 api/search目录会包含文档中 search下的接口。
除了这些简单接口的封装,存放在 api 目录下以外,我们还会实现更业务化的连续操作,比如通过调用若干个接口实现一个完整功能,这种,我们将来会在 api目录同级别的地方建立 domain 目录,来存放这类用户操作。
在这个小节中,我们只是简单封装一下repos的一个接口,来看看登录前后调用接口的区别,下一小节才会正式封装这个接口。
我们开始写代码封装第一个接口。
例2. api/repositories/repos.py
- from core.rest_client import RestClient
- class Repos(RestClient):
- def __init__(self,api_root_url,**kwargs):
- super(Repos, self).__init__(api_root_url,**kwargs)
-
-
- def list_your_repos(self):
- return self.get("/user/repos")
例3.github.py
- from api.repositories.repos import Repos
-
-
- class Github():
- def __init__(self, **kwargs):
- self.api_root_url="http://api.github.com"
- self.repos = Repos(self.api_root_url,**kwargs)
-
-
-
-
- if __name__ == '__main__':
- r=Github(token="xxxxxxxxxxxxxx")
- x= r.repos.list_your_repos()
- print(x.text)
-
-
- r=Github(username="xxxxxx",password="xxxxx")
- x= r.repos.list_your_repos()
- print(x.text)
介绍下例2和例3,
例2中,我们又建立了一个新的类Repos,Repos是 RestClient的一个子类。
值得注意的是,它的初始化方法有着和父类不一样的参数表(注意子类和父类的初始化方法可以接受不同的参数表):
def __init__(self, api_root_url,**kwargs)
它接受了一个固定参数 api_root_url, 和一个关键字参数 **kwargs。
其中 固定参数大家很好理解,而关键字参数的意思是,可以传入任意的键值对作为参数。当然了,观察其父类的代码我们就知道,这里虽然可以传任意的关键字参数,但只 username,password,token 这三个参数会被处理。这里的关键是:Repos 作为一个子类,它不需要知道哪些参数会被处理以及会被怎样处理,它就直接在自己的初始化方法里调用了父类的初始化方法,不论用户传入了几个参数,它都原封不动传给它的父类:
super(Repos, self).__init__(api_root_url,**kwargs)
这里的super就是表示父类,这一行调用的父类的 init 方法。
初始化完成后,自然就可以在子类中使用 self 来直接使用父类的方法了,比如 get 方法。
def list_your_repos(self):
return self.get("/user/repos")
现在我们不忙着运行例2 例3 的代码。先通过浏览器访问一下https://api.github.com/user/repos
得到响应如下:
401 Unauthorized
{ "message": "Requires authentication", "documentation_url": " https:// developer.github.com/v3 /repos/#list-your-repositories " }
这是因为,我们通过浏览器访问时,没有登录。系统返回401未授权的访问,并要求我们登录。
而运行例3的代码,则会得到你登录的用户的所有 repo信息。注意,把例3中的xxxxx信息改成你真实的信息。
例3 的代码中,我们使用了组合模式来做封装。组合模式,在 《java 编程思想》一书中有介绍。 这里就是借鉴了这个思路来写的。
首先我们建立一个 Github 类,Github 类负责接收用户输入的 用户名,密码,token, url 等参数,并且在其成员变量中去新建 repos 类的实例。而repos 类又继承自 RestClient 类。所以,相当于,一个 Github 类实例里有多个 RestClient的子类。类比于一辆车上有前轮后轮,而前轮后轮都是继承自轮子这个类。
本小节代码地址:
https://github.com/TestUpCommunity/TUGithubAPI/tree/teach_002
本文首发于测试进阶知识星球,
完整的接口测试教程正在我的知识星球火热更新中,
扫码即可加入。费用为128元/年。
关于项目实战的介绍:张挺:测试进阶社群项目实战启动
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。