BeckettPython的HTTP API客户端

联合创作 · 2023-09-29 08:01

Beckett是一个基于惯例的(convention-based)框架,是为了建设HTTP APIs的 Python接口。

因为它是基于惯例的,它不需要使用魔法就能用语HTTP APIs,像REST风格的URI和资源一样。

资源被声明为Python类,像这样: 

# resources.py
from beckett.resources import BaseResource


class Product(BaseResource):  
    class Meta:
        name = 'Product'
        identifier = 'slug'
        attributes = (
            'slug',
            'brand',
            'price',
            'images',
        )
        valid_status_codes = (
            200,
            201,
        )
        methods = (
            'get',
            'post',
        )

然后你用客户端获取你要的资源并进行记录:

# client.py
from beckett.clients import BaseClient  
from .resources import Product

class MyClient(BaseClient):  
    class Meta:
        name = 'My API Client'
        base_url = 'https://myapi.com/api/'
        resources = (
            Product,
        )

就是这样,这就是你需要做的所有事。

Beckett会在客户端使用 reflection产生python方法,用于与注册资源交互:

from .clients import MyClient  
client = MyClient()  
client.get_product(uid='product-slug')  
>>> <Product | product-slug>

这些方法产生URI结构来匹配restful风格的URIs:

uri-structures

客户端的响应是资源类的类型实例,所有你定义的属性将从JSON响应中提取,并作为属性添加在实例中:

resource = clients.get_product(uid='some-slug')[0]  
type(resource)  
>>> <class 'resources.Product'>
resource.name  
>>> 'Handbag'

灵活性

因为过并不是所有的API都是一样的,Beckett被设计得很灵活,允许你修改它工作方式的各个方面:

    • URI生成

    • 分页响应渲染

    • 请求头和请求会话

    • 安全认证

举个例子,如果你需要修改我们的产品资源使其与我前面提到的唯一的URI协同工作, 我们可以子类化我们资源中的get_url方法

class Product(BaseResource):  
    class Meta:
        ...

    @classmethod
    def get_url(cls, url, uid, **kwargs):
        return '{}/products/?id={}&country={}'.format(
            url,
            uid,
            kwargs.get('country')
        )

这个方法利用了继承的优势,从而比串行化语言能够提供更多的灵活性。

超媒体

Beckett能够理解超媒体,并帮助你遍历API的相关资源。如果我们的Product 资源和Designers有关,我们可以在我们的代码中使用HypermediaResource基类进行声明,它将检查和理解超媒体链接:

class Designer(HypermediaResource):  
    ...

class Product(HypermediaResource):  
    class Meta:
        ...
        base_url = 'http://myapi.com/api'
        related_resources = (
            Designer,
        )

Beckett将检查JSON响应数据,为Designer 资源匹配URL模式,并生成和它交互的方法:

product = client.get_product(uid='some-slug')[0]  
# Will raise an error if uid is not related
product.get_designers(uid=4)  
<Designer | Some Designer>

谁正在使用Beckett

如果没有途径测试它,我就不可能发布它。Beckett正在为 PokéAPI 和 SWAPI的Python用户提供支持。它也已经在Lyst上测试过了,为我们最繁忙的API服务提供集成。这个内部API一天之内有超过十万次的请求,并在最初的几个版本的Beckett中帮助修复了一些bug。

未来的计划

我现在的计划是把Beckett一直作为一个开源的项目。我想它可以作为一个很好的例子,可以提供API客户端是怎样集成的,尤其是与超媒体概念协同工作的那些。

目前Beckett可以对HTTP请求以及它所处理的HTTP响应对象提供灵活的控制。我想在未来提供更多的灵活性,但要做到这一点,我需要更多的特定领域的用例。

最后。我希望你可以下载它并尝试把它集成到你的项目中,然后给我提供一些如何改进它的反馈。

浏览 3
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报