关于SDK和API的区别 and 阿里云SDK的使用浅析

参考链接:https://blog.csdn.net/weixin_43846916/article/details/125703852

我的理解:

起因:

测试工作中,即需要测试API,又需要测试SDK,本质上来说我感觉是在做一样的工作。

理解:

API:

API是一种通过url去访问数据的方式,需要四样东西【接口文档、url、入参、接口环境】,这其实是一种很简单的方式,你只需要按文档的要求传入参数就可以了,当然如果你没有相应接口环境的话就会比较复杂了,因为传递数据中肯定不可能是明文传递,有一系列的加密操作,所以你要自己写加密(一般文档中也会提供给你,有兴趣的话可以去研究一下例如hashlib.md5,你的入参加密过后传给服务器,服务器拿到以后根据固定的间隔比如“&”符号,拆分你的入参,然后跟自己的加密字段撞一下,然后撞一下密码blablablabla…)
当然了,这整个过程中,你的需求很明确,给入参,拿返参,中间的过程你不需要了解,你也无法了解。

SDK:

SDK就是一个kit(工具包),里面包含了关于此软件的所有方法,使用的时候,通俗来说就是看代码,你要调哪个接口、需要什么参数、什么格式,代码里面都会明确的规定出来。
另外,既然你已经拿到工具包了,你就可以操作一些比较复杂的action,举个栗子:
如果我需要验证创建出的某个实例是否可以开启加密,那么我可以调用创建实例的接口,返回的出参,做下处理,直接转给实例加密的接口去做处理。

研究下阿里云的SDK

从官方给出的Sample的调用接口开始说吧

  1. 先创建一个带AKSK的客户对象client
  2. 最终调用的代码是:client.describe_regions_with_options(describe_regions_request, runtime)。print一下可以得到我们想要的返回参数。
    2.1 describe_regions_request —>DescribeRegionsRequest类的对象,里面有一些方法,可以简单理解成把一些入参整合在一起,作为一个对象
    2.2 runtime —> 支撑程序运行的环境配置
  3. describe_regions_with_options方法中规定返回的是一个DescribeRegionsResponse对象,看了下最后的return
return TeaCore.from_map(
            r_kvstore_20150101_models.DescribeRegionsResponse(),
            self.call_api(params, req, runtime)
        )

不知道返回个啥,我们看下这个from_map方法:

@staticmethod
    def from_map(
            model: TeaModel,
            dic: Dict[str, Any]
    ) -> TeaModel:
        if isinstance(model, TeaModel):
            try:
                return model.from_map(dic)
            except Exception:
                model._map = dic
                return model
        else:
            return model

所以前面的这个api.call返回的应该是一个字典类型的东西,打印一下发现就是我想要的返参。
isinstance(model, TeaModel) ----> 判断下model是不是TeaModel的一个对象
所以这个程序应该会走到model.from_map(dic),点进去看一下发现是TeaModel下的一个方法:

    def from_map(self, map=None):
        pass

这个程序没有返回,因此我们分析一下,这边的from_map是model下面的,应该是存在了重写情况,果然在DescribeRegionsResponse(TeaModel)这个类下面发现了:

    def from_map(self, m: dict = None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeRegionsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self

这个我粗略的看了下,应该是个校验作用吧,查漏补缺,最后把自己返回,也就是把对象(self)返回。
这时我们再看回这部分代码:

@staticmethod
    def from_map(
            model: TeaModel,
            dic: Dict[str, Any]
    ) -> TeaModel:
        if isinstance(model, TeaModel):
            try:
                return model.from_map(dic)
            except Exception:
                model._map = dic
                return model
        else:
            return model

可以看出,最终return出来的这个对象model是会含有我想要的dic信息的。

  1. 最后一个问题。回到一开始的Sample代码:
    print(client.describe_regions_with_options(describe_regions_request, runtime)) 可以得到我们想要的内容?这里面是对象啊,如果打印对象,返回的应该是这个对象的内存地址。所以我们考虑到应该是这个对象的类中写了__str__方法,最终在他的父类(DescribeRegionsResponse)的父类(TeaModel)中找到了:
    def __str__(self):
        s = self.to_map()
        if s:
            # print(111)
            return str(s)
        else:
            # print(222)
            return object.__str__(self)

可以看出,你如果打印这个对象,他最后会return给你一个字符串信息。

其实到这边,你如果只想看返回内容的话,就已经结束了。但是如果你还想获得其中的关键参数做后续开发操作的话,就需要转成Python数据类型方便操作,比如dict

  1. 我在研究他SDK内部代码之前的方法是:
str1 = str(client.describe_regions_with_options(describe_regions_request, runtime))
res = str1.replace('\'', '\"')
res1 = json.loads(res)

他原本的类型是一个自定义类型,自然是没有字典的.get(‘xxx’)这样的操作的,所以我想先把他转成json格式,然后在json.loads()转换成他原本的Python数据类型(在这里就是字典)。在这里的做法是先强制转换成字符串,然后转成json格式,因为他内部是单引号,而json格式要求是双引号。改完以后得到字典。

  1. 当我研究了内部代码:
    def __str__(self):
        s = self.to_map()
        if s:
            # print(111)
            return str(s)
        else:
            # print(222)
            return object.__str__(self)

之后,找到了

    def to_map(self):
        _map = super().to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

原来这个s拿到的已经是个字典了,就不用我后面再转来转去了。而这个to_map()方法,我的对象是有的,所以我直接:
res = client.describe_regions_with_options(describe_regions_request, runtime).to_map()
拿到的res就已经是字典了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值