基于flask-restless的CRUD/RPC客户端
项目描述
flask-restless-client
简介
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的简写
由于all
和get
是经常使用的方法,它们已经在对象模型本身上启用了简写
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"))
运行远程方法的未来计划
目前,如果客户端尝试反序列化尚未注册的复杂对象,则客户端将崩溃。展望未来,希望实施一个“不崩溃”策略。背后的想法是数据是存在的,并且不是由于(反)序列化失败而导致程序停止执行。
如果未为复杂对象注册(反)序列化程序,将根据现有数据模拟一个。访问它所知道的数据将允许您无问题地与之交互,访问模拟对象未知的功能或数据将导致异常。
项目详情
下载文件
下载适用于您的平台文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源代码发行版
构建发行版
散列 for flask_restless_client-0.4.14-py2.py3-none-any.whl
算法 | 散列摘要 | |
---|---|---|
SHA256 | ef2c635ba61a55d584e5c05a769bdc27d7526f162dc5c1ba4218b709a28c5e5d |
|
MD5 | 3196306da9a560702af2c01e10d64634 |
|
BLAKE2b-256 | 8123fd279f1787e840f790938cdab9e1999b79985d62da15d240980df71d652b |