跳转到主要内容

基于flask-restless的CRUD/RPC客户端

项目描述

flask-restless-client

Build Status Codecov PyPI

简介

flask-restless-client 是一个两步库的第二部分。第一部分是 flask-restless-datamodel。与 flask-restless-datamodel 一起,这个库旨在为 Flask/SQLAlchemy 应用程序提供一个通过 HTTP 使用 flask-restless 的 CRUD/RPC 客户端。

利用 Flask-Restless 提供的简单集成来在 HTTP 上公开 REST CRUD 接口,这个库使用其功能提供动态 Python 客户端。通过读取 flask-restless-datamodel 生成的数据格式,restless-client 能够构建自身并为客户端提供旨在反映类似 SQLAlchemy 接口的对象。

这包括运行定义在服务器端的 SQLA 模型的对象方法的 RPC 可能性。要实现与该库的 RPC 部分的顺畅交互,需要一些设置。

开发者需要

  • 编写序列化程序,从 Python 原生类型到序列化程序,以将复杂对象传输到服务器
  • 如果选择的身份验证方法不受此库支持,则重写身份验证方法。

因此,建议将此库作为您应用程序自定义客户端的基础。它很可能是 flask-restless-client 上的一层薄层,设置一些配置。

安装

    pip install flask-restless-client

设置客户端

在服务器端公开您的模型

第一步是在服务器端启用 flask-restless-datamodel。您可以访问 flask-restless-datamodel 了解如何操作。

认证中

由于本库旨在即插即用,因此提供了一些内置的认证。当前即插即用的认证类型包括Bearer和Basic认证。

默认情况下,客户端将使用Bearer会话,但Basic认证会话可以从restless_client.ext.auth导入。

您还可以在初始化客户端时将您的(预认证的)会话作为参数传递。

可以使用环境变量来加快认证设置。使用前缀RESTLESS_CLIENT_,您可以设置任何涉及认证的内容,包括设置要使用的会话类型。

复杂对象的序列化和反序列化

支持类似RPC的客户端的部分工作是在对象到达目的地时保持它们与发送时相同。我们都知道反序列化并不总是忠实于最初放入的内容。因此,您可以注册自己的(反)序列化程序以处理复杂对象。

from cereal_lazer import register_class
import pandas as pd

register_class(
    'DataFrame', # Register the object as this name
    pd.DataFrame, # Register the class
    lambda x: x.to_json(), # Register a serializer
    lambda x: pd.read_json(x) # Register a deserializer
)

这些对象使用cereal_lazer库在全局范围内注册。然后客户端使用该库进行(反)序列化。

使用客户端

重要的是要重申,这是一个自构建的客户端。这意味着您与该客户端的交互方式取决于外部输入。为了有一个实际的例子,请考虑以下在服务器端定义的SQLA模型

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode, unique=True)
    birth_date = db.Column(db.Date)

class Computer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode, unique=True)
    vendor = db.Column(db.Unicode)
    purchase_time = db.Column(db.DateTime)
    owner_id = db.Column(db.Integer, db.ForeignKey('person.id'))
    owner = db.relationship(
        'Person', backref=db.backref('computers', lazy='dynamic'))
    owner_name = association_proxy('owner', 'name')
    peers = association_proxy('owner', 'computers')

基于这些模型,flask-restless-datamodel将为客户端生成输入,从而允许类似SQLA的接口。

如果我们将客户端连接到我们的服务器应用程序,我们将能够执行所有有趣的操作

C代表蜡笔

现在我们已经公开了一些服务器端模型,这些模型将在客户端可用,我们可以直接创建一些对象。

from restless_client import Client

c = Client(url='https://:5000/api')
maurice = c.Person(name='Maurice')
roy = c.Person(name='Roy')

beast = c.Computer(name='TheBeast', vendor='Pear', owner=maurice)
server = c.Computer(name='Server', vendor='Pingu', owner=maurice)
pc = c.Computer(name='pc', vendor='Doors', owner=roy)

# Save objects on the server
c.save()

# Alternatively, you can save on a per-instance basis
beast.save()

请注意,如果我们忽略c.save()语句,而是运行beast.save(),则在调用beast.save()时,maurice实例是beast.owner的依赖项,并且将不会被保存。客户端应该能够解决这些未保存的依赖关系,并首先保存它们

R代表彩虹

可以通过多种方式加载对象。对象模型有一个可访问的query属性,可以执行所有读取操作

获取给定类的所有实例

everyone = c.Person.query.all()

根据id获取实例

maurice = c.Person.query.get(1)

all/get的简写

由于allget是经常使用的方法,它们已经在对象模型本身上启用了简写

everyone = c.Person.all()
maurice = c.Person.get(1)

过滤

maurice = c.Person.query.filter(c.Person.name == 'Maurice')
maurice = c.Person.query.filter_by(name='Maurice')
# limit the results to 3
some_people = c.Person.query.limit(3).all()
# offset results, ignoring the first 2
some_people = c.Person.query.offset(2).all()
# order by name
everyone = c.Person.query.order_by(name='asc').all()
# get the first instance
maurice = c.Person.query.first()
# get the last instance
maurice = c.Person.query.last()
# expect only one result
maurice = c.Person.query.one()
# expect only one result, or no result
maurice = c.Person.query.one_or_none()

# filtering over relations, get all people that own a computer with Pear vendor
maurice = c.Person.query.filter(c.Person.computers.has_(c.Computer.vendor == 'Pear'))

U代表你和我

更新与创建对象一样简单。该库构建的方式是标记脏属性,并且只向服务器发送必要的数据。

cmptr = c.Computer.query.one()
cmptr.vendor = 'Robot'
cmptr.save()

D代表...删除

cmptr = c.Computer.query.one()
cmptr.delete()

请注意,执行delete是瞬时的,调用保存是不必要的。

运行远程对象方法

正如承诺的那样,这个库提供了一个类似RPC的功能,允许您运行在SQLA模型上定义的方法。它可能不如其他RPC那样先进,但它至少提供了一种方法来模拟在服务器上下文中与模型交互。

发送和接收复杂对象确实需要一些设置,但一旦完成这些设置,远程方法调用应该可以顺利运行。(尽管有大量远程执行可能失败的场景)。

无论如何,这里有奇迹墙

在服务器上,我们会定义一个具有以下方法的对象

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode, unique=True)

    def speak(self, what_to_say):
        return "Errr... uh... ehm... {}?".format(what_to_say)

然后我们可以通过以下方式远程运行它

maurice = c.Person.query.filter(c.Person.name == 'Maurice')
print(maurice.speak("I'd rather send an email"))

运行远程方法的未来计划

目前,如果客户端尝试反序列化尚未注册的复杂对象,则客户端将崩溃。展望未来,希望实施一个“不崩溃”策略。背后的想法是数据是存在的,并且不是由于(反)序列化失败而导致程序停止执行。

如果未为复杂对象注册(反)序列化程序,将根据现有数据模拟一个。访问它所知道的数据将允许您无问题地与之交互,访问模拟对象未知的功能或数据将导致异常。

项目详情


下载文件

下载适用于您的平台文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码发行版

flask-restless-client-0.4.14.tar.gz (27.7 kB 查看散列)

上传时间 源代码

构建发行版

flask_restless_client-0.4.14-py2.py3-none-any.whl (23.3 kB 查看散列)

上传时间 Python 2 Python 3

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面