将Python类型注释转换为JSON模式的包

pytojsonschema的Python项目详细描述


Test

皮托日森舍马

使用静态分析-ast-将python3函数类型注释转换为JSON模式的包。在

这允许您为用Python编写的JSON-RPC后端函数自动生成验证模式。在

当前支持Python3.8+和JSON模式草稿7+。在

入门

安装

在python3.8+环境中,运行pip install pytojsonschema。在

扫描包

安装包后,可以从repo的根目录打开python终端并运行:

importosimportpprintfrompytojsonschema.functionsimportprocess_packagepprint.pprint(process_package(os.path.join("test","example")))

将扫描示例包,并为它可以找到的所有顶级函数生成JSON模式。在

扫描文件

您也可以针对特定的文件,这些文件不会在结果值中包含包名称空间。 在同一终端上:

^{pr2}$

包括和排除模式

Include和exclude类unix模式可用于筛选要允许/不允许的函数和模块名称 正在扫描。当您现在运行此选项时,可以看到不同之处:

pprint.pprint(process_package(os.path.join("test","example"),exclude_patterns=["_*"]))

类似地,但适用于特定文件:

pprint.pprint(process_file(os.path.join("test","example","service.py"),exclude_patterns=["_*"]))

需要考虑的事项:

  • 排除模式匹配覆盖包含匹配项。在
  • __init__.py文件不受模式规则的影响,并且总是被扫描。但是,您仍然可以过滤 内部功能。在

类型批注规则

将Python的类型模型调整为JSON意味着函数签名中不允许所有内容。 这是JSON数据序列化附带的一个自然限制。希望你需要的大部分有用的东西是 允许。在

允许的类型

基本类型

允许使用基本类型boolintfloatstrNone和{}。此外,您还可以构建更复杂的、嵌套的 使用typing.Uniontyping.Optionaltyping.Dict(只允许str键)和 typing.List。所有这些类型在JSON和JSON模式中都有一个直接的、非歧义的表示。在

自定义类型

您的函数也可以使用自定义类型,例如使用typing.Uniontyping.List赋值定义的类型, typing.Dict和{},如:

ServicePort=typing.Union[int,float]ServiceConfig=typing.Dict[str,typing.Any]

您可以使用python3.8的一个新特性typing.TypedDict,在dict-like上构建更强的验证 对象(仅基于类的语法)。如您所见,您可以无限制地链接类型:

classService(typing.TypedDict):address:strport:ServicePortconfig:ServiceConfigtags:typing.List[str]debug:bool=False

注意:虽然Python本身不会自动填充默认值,但是可以使用它们使属性不需要。

另外,如果需要限制类型的选择,可以使用Python枚举:

importenumclassHTTPMethod(enum.Enum):GET="GET"POST="POST"PATCH="PATCH"DELETE="DELETE"defmy_func(http_method:HTTPMethod):pass# My code

注意:枚举的所有属性必须是常量:Noneintfloatboolstr

注意:结果验证使用不同的枚举值,例如HTTPMethod.GET.value或简单地"GET",作为 有效的选择而不是枚举实例本身,例如HTTPMethod.GET,因为这是JSON模式可以理解的。这个 可能导致与其他静态分析工具(如http://mypy-lang.org/)不兼容, 所以请记住这一点。

从其他文件导入类型

您可以在包中导入这些自定义类型,它们将被提取。但是,由于 无法遵循来自外部包的扫描、自定义类型,因此不受支持。换句话说,你可以 仅使用相对导入在包中共享这些类型。在

其他静态分析工具,如mypy使用带有存根文件的存储库来解决此问题,请参阅 https://mypy.readthedocs.io/en/stable/stubs.html。这是不可能的 像这样一个小项目的范围,至少现在是这样。在

规则

  1. 需要对要扫描的函数进行类型注释。很明显的要求,对吧?在

  2. 只能使用上一节中定义的类型。他们是c安全地序列化为JSON。在

  3. 函数参数应该以键值格式传递,就像json对象一样。这有几个限制 关于*args、**kwargs、仅位置参数和仅关键字参数:

    允许以下情况:

    • **kwargsdef func(**kwargs): pass
    • keyword only参数def func(*, a): pass

    不允许出现以下情况:

    • *argsdef func(*args): pass
    • 仅位置参数def func(a, /): pass

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

推荐PyPI第三方库


热门话题
java OpenShift的齿轮特性   java如何在Liferay站点的每个页面上放置公司地址和电话?   java确定整数数组中是否存在一个子集,在两个条件下求和到给定的目标值   序列化为什么java中的serialVersionUID必须是静态的、最终的、长类型的?   java响应返回null   java注入接口实现Quarkus   java我不明白为什么第二次排序的运行时间比第一次慢?   (Java)显示图像的最佳方式?   java Android应用程序因添加布局而崩溃   java如何在运行时获取泛型变量的类   java Selenium web驱动程序:无效的选择器:*:WebKitFullScreenSentor   Spring中的java注入值始终为空   Eclipse中带有TestNG插件的@BeforeSuite和@AfterSuite的java问题   使用trycatch块、filewriter和printwriter在java中创建自定义类   如何在Java 安卓上绘制相交的两条线