python中基于类型化decorator的json-rpc库

typedjsonrpc的Python项目详细描述


https://img.shields.io/pypi/status/typedjsonrpc.svghttps://img.shields.io/pypi/l/typedjsonrpc.svghttps://img.shields.io/pypi/pyversions/typedjsonrpc.svghttps://img.shields.io/pypi/wheel/typedjsonrpc.svghttps://badge.fury.io/py/typedjsonrpc.svghttps://circleci.com/gh/palantir/typedjsonrpc.svg?style=shield

typedjsonrpc是一个基于decorator的JSON-RPC库,用于 公开参数和返回类型的python。它受 Flask JSON-RPC但是有一些关键的区别:

键入djsonrpc…

  • 允许返回类型检查
  • 专注于简单的调试

这些文档也可以在Read the Docs上找到。

使用djsonrpc类型

安装

使用pip安装djsonrpc类型:

$ pip install typedjsonrpc

项目设置

要在项目中包含typedjsonrpc,请使用:

fromtypedjsonrpc.registryimportRegistryfromtypedjsonrpc.serverimportServerregistry=Registry()server=Server(registry)

注册表将跟踪json-rpc可用的方法。每当你注释 一个方法,它将被添加到注册表中。您始终可以使用方法rpc.describe()来获取 所有可用方法的说明。ServerWSGI处理请求的兼容应用程序。Server 还有一个可以使用server.run(host, port)运行的开发模式。

示例用法

为方法添加注释,使其可访问并提供类型信息:

@registry.method(returns=int,a=int,b=int)defadd(a,b):returna+b@registry.method(returns=str,a=str,b=str)defconcat(a,b):returna+b

返回类型具有要使用returns关键字声明的。对于不返回的方法 任何东西,您都可以使用type(None)None

@registry.method(returns=type(None),a=str)deffoo(a):print(a)@registry.method(returns=None,a=int)defbar(a):print(5*a)

您可以使用任何基本的json类型:

JSON typePython type
stringbasestring (Python 2), str (Python 3)
numberint, float
nullNone
booleanbool
arraylist
objectdict

函数也可以接受*args**kwargs,但不能声明它们的类型。所以 正确的使用方法是:

@registry.method(a=str)deffoo(a,*args,**kwargs):returna+str(args)+str(kwargs)

要检查一切是否正常运行,请尝试(假设在main中声明了add 模块):

$ curl -XPOST http://<host>:<port>/api -d @- <<EOF
{
    "jsonrpc": "2.0",
    "method": "__main__.add",
    "params": {
        "a": 5,
        "b": 7
    },
    "id": "foo"
}
EOF{"jsonrpc": "2.0",
    "id": "foo",
    "result": 12}

将任何非整数参数传递到add将引发InvalidParamsError

配料

您可以将json-rpc请求对象的列表作为一个请求发送,并将收到json-rpc的列表 作为回报的响应对象。这些响应对象可以使用 id。下面是使用两组参数调用add方法的示例:

$ curl -XPOST http://<host>:<port>/api -d @- <<EOF
[
    {
        "jsonrpc": "2.0",
        "method": "__main__.add",
        "params": {
            "a": 5,
            "b": 7
        },
        "id": "foo"
    }, {
        "jsonrpc": "2.0",
        "method": "__main__.add",
        "params": {
            "a": 42,
            "b": 1337
        },
        "id": "bar"
    }
]
EOF[{"jsonrpc": "2.0",
        "id": "foo",
        "result": 12}, {"jsonrpc": "2.0",
        "id": "bar",
        "result": 1379}]

调试

如果使用参数debug=True创建注册表,则可以使用 werkzeug’s debugger。在这种情况下,如果 执行期间出错-例如,您试图将字符串用作add的参数之一- 响应将包含一个带有debug_url

的错误对象
$ curl -XPOST http://<host>:<port>/api -d @- <<EOF
{
    "jsonrpc": "2.0",
    "method": "__main__.add",
    "params": {
        "a": 42,
        "b": "hello"
    },
    "id": "bar"
}
EOF{"jsonrpc": "2.0",
    "id": "bar",
    "error": {"message": "Invalid params",
        "code": -32602,
        "data": {"message": "Value 'hello' for parameter 'b' is not of expected type <type 'int'>.",
            "debug_url": "/debug/1234567890"}}}

这告诉您在<host>:<port>/debug/1234567890找到回溯解释器。

记录

注册表在模块typedjsonrpc.registry中有一个默认记录器,它记录所有错误 不是由typedjsonrpc定义的。您可以如下配置记录器:

importlogginglogger=logging.getLogger("typedjsonrpc.registry")# Do configuration to this logger

http状态代码

由于typedjsonrpc 0.4.0,http状态代码被添加到来自 typedjsonrpc.server.Server类。这是为了改进http上的typedjsonrpc的使用。这个 下表是返回的SATUS代码:

ConditionBatchedStatus code
SuccessY200
N200
All notificationsY204
N204
ParseError or InvalidRequestErrorY200
N400
MethodNotFoundErrorY200
N404
All other errorsY200
N500

附加功能

自定义类型序列化

如果要序列化自定义类型,可以设置json_encoderjson_decoderServer上的属性设置为您自己的自定义json.JSONEncoderjson.JSONDecoder 实例。默认情况下,我们使用默认的编码器和解码器。

在第一个请求之前添加钩子

可以在调用第一个请求之前添加要运行的函数。这对某些人可能有用 您的wsgi应用程序需要的特殊设置。例如,您可以注册一个函数来打印 第一次请求前的调试信息:

importdatetimefromtypedjsonrpc.registryimportRegistryfromtypedjsonrpc.serverimportServerregistry=Registry()server=Server(registry)defprint_time():now=datetime.datetime.now()print("Handling first request at: {}".format(now))server.register_before_first_request(print_time)

从json-rpc方法访问http请求

在某些情况下,您可能希望从json-rpc方法访问http请求。例如, 您可能需要根据请求中的头执行逻辑。在中键入djsonrpc.server 模块中,有一个特殊的typedjsonrpc.server.current_request属性,允许您 访问用于调用CU的HTTP请求当前方法。

警告

current_request作为线程本地实现。如果你想打电话 Server.wsgi_app来自Registry.method,然后current_request将在中重写 那个线程

示例:

fromtypedjsonrpc.serverimportcurrent_request@registry.method(returns=list)defget_headers():returnlist(current_request.headers)

禁用浮动的严格性

typedjsonrpc默认情况下将只接受浮动到float类型参数中。例如,如果 您的功能如下:

importmath@registry.method(returns=int,x=float)deffloor(x):returnint(math.floor(x))

您的输入是:

{
    "jsonrpc": "2.0",
    "method": "floor",
    "params": {
        "x": 1
    },
    "id": "foo"
}

您将得到一个无效的参数错误,如下所示:

{
    "error": {
        "code": -32602,
        "data": {
            "debug_url": "/debug/4456954960",
            "message": "Value '1' for parameter 'x' is not of expected type <type 'float'>."
        },
        "message": "Invalid params"
    },
    "id": "foo",
    "jsonrpc": "2.0"
}

实际上,当您使用json编码器时,经常会出现这种情况。json编码器可以选择编写 浮点1.0作为整数1。为了解决这个问题,您可以手动编辑json 或者在typedjsonrpc.registry.registry中将strict_floats设置为False

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
尝试连接到Red5服务器时出现java问题   java实现Runnable的类被认为是ExecutorServices的“Runnable任务”?   java struts2类中的多个@validation   java未能应用插件[class'org.gradle.api.plugins.scala.ScalaBasePlugin']:gradle v2。13   如何使用Java流仅收集长度最大的元素?   从spring引导应用程序连接到firestore的java引发空指针异常   java从SQLite插入和获取真实数据类型会为连续插入获取空值吗?   当存在未知数量的空格时,使用java替代正向查找   部署如何为当今的浏览器部署java小程序(小程序、嵌入、对象)?   @OneToMany和@ManyToOne@Formula之间的java双向关系返回null   java为什么在我的例子中,协议缓冲区的性能比JSON差?   如何部署混合C++/Java(JNI)应用程序?   java如何在程序中显示字符串的完整信息。反恐精英?   java在Hibernate中从持久性上下文中分离实体中的实体