一个简单的库,用于获取数据并将其转换为python类型定义。
dict-typer的Python项目详细描述
Dict打字机
一个简单的工具,用于获取json负载并将其转换为Python TypedDict类 定义
web版本在https://pytyper.dev/上可用
为什么这个有用?在
在处理API响应时,很可能使用JSON响应, 你可能有很深的嵌套字典,项目列表 有点难把你的头围绕着你的反应结构 与合作。我通常做的第一件事就是创建一些数据结构 这样我就可以从代码中的linting和键入信息中获益。在
现在这往往是耗时和容易出错的,所以我认为这可能是一个 用一个未来的工具自动化这个过程是个好主意。就像一个 例如,如果我们从下面的示例部分生成的输出和 想象一下这是我们从api得到的响应。我们可以这样插入:
fromproject.typesimportRootdefget_from_api()->Root:passdefrun()->None:response=get_from_api()test1=response["nested_dict"]["number"]+1test2=response["nested_dict"]["string"]+1test3=response["nested_dict"]["non_existant"]+1foriteminresponse["optional_items"]:print(item+1)
如果我们查一下mypy
^{pr2}$它将立即检测到四个问题!在
我还想用这个项目来学习更多关于分析代码的知识,确保 这个项目经过了很好的测试,所以很容易进行实验和尝试不同的方法 方法。在
使用
提供文件的路径或将json输出管道发送到dict-typer
-> % dict-typer --help Usage: dict-typer [OPTIONS] [FILE]... Options: --imports / --no-imports Show imports at the top, default: True -r, --rich Show rich output. -l, --line-numbers Show line numbers if rich. --version Show the version and exit. --help Show this message and exit. -> % dict-typer ./.example.json ... -> % curl example.com/test.json | dict-typer ...
TypeDict定义
定义TypedDict有两种方法,第一种是使用类的方法 基于结构,如这里的示例所示。它更容易阅读 一种限制,即每个密钥必须是avalid标识符,而不是保留的 关键字。通常这不是问题,但如果你有,例如 以下数据
{"numeric-id":123,"from":"far away",}
它是有效的json,但具有无效的标识符numeric-id
并保留
关键字from
,表示定义
classRoot(TypedDict):numeric-id:intfrom:str
无效。在检测到的情况下,dict typer将使用alternative way来定义 那些类型,看起来像这样
Root=TypedDict('Root',{'numeric-id':int,'from':str'})
这不是可读的,但是是有效的。在
默认情况下,dict typer仅对具有 无效的密钥。在
列表
如果有效负载的根是一个列表,那么它将被视为一个列表 在字典中,对每个项进行解析并为sub创建定义 项目。在这些情况下,类型别名也会添加到要捕获的输出中 列表的类型。{cd4>将生成以下定义:
fromtyping_extensionsimportTypedDictclassRootItem(TypedDict):id:intRoot=List[Union[RootItem,float,int,str]]
示例
从shell调用
-> % cat .example.json {"number_int": 123, "number_float": 3.0, "string": "string", "list_single_type": ["a", "b", "c"], "list_mixed_type": ["1", 2, 3.0], "nested_dict": {"number": 1, "string": "value"}, "same_nested_dict": {"number": 2, "string": "different value"}, "multipe_levels": {"level2": {"level3": {"number": 3, "string": "more values"}}}, "nested_invalid": {"numeric-id": 123, "from": "far away"}, "optional_items": [1, 2, "3", "4", null, 5, 6, null]} -> % cat .example.json | dict-typer from typing import List, Union from typing_extensions import TypedDict class NestedDict(TypedDict): number: int string: str class Level2(TypedDict): level3: NestedDict class MultipeLevels(TypedDict): level2: Level2 NestedInvalid= TypedDict("NestedInvalid", {"numeric-id": int, "from": str, }) class Root(TypedDict): number_int: int number_float: float string: str list_single_type: List[str] list_mixed_type: List[Union[float, int, str]] nested_dict: NestedDict same_nested_dict: NestedDict multipe_levels: MultipeLevels nested_invalid: NestedInvalid optional_items: List[Union[None, int, str]]
从Python调用
In[1]:source={...:"number_int":123,...:"number_float":3.0,...:"string":"string",...:"list_single_type":["a","b","c"],...:"list_mixed_type":["1",2,3.0],...:"nested_dict":{...:"number":1,...:"string":"value"...:},...:"same_nested_dict":{...:"number":2,...:"string":"different value"...:},...:"multipe_levels":{...:"level2":{...:"level3":{...:"number":3,...:"string":"more values"...:}...:}...:},...:"nested_invalid":{"numeric-id":123,"from":"far away"},...:"optional_items":[1,2,"3","4",None,5,6,None]...:}...:In[2]:fromdict_typerimportget_type_definitionsIn[3]:print(get_type_definitions(source,show_imports=True))fromtypingimportList,Unionfromtyping_extensionsimportTypedDictclassNestedDict(TypedDict):number:intstring:strclassLevel2(TypedDict):level3:NestedDictclassMultipeLevels(TypedDict):level2:Level2NestedInvalid=TypedDict("NestedInvalid",{"numeric-id":int,"from":str,})classRoot(TypedDict):number_int:intnumber_float:floatstring:strlist_single_type:List[str]list_mixed_type:List[Union[float,int,str]]nested_dict:NestedDictsame_nested_dict:NestedDictmultipe_levels:MultipeLevelsnested_invalid:NestedInvalidoptional_items:List[Union[None,int,str]]
- 项目
标签: