DivKit python库
项目描述
PyDIVKit示例
此库设计用于与DivKit配合使用python。
功能
- 声明性和命令式DivKit块定义
- 原生类型提示支持
- 完整的面向对象API
- IDE类型检查和建议
对象构造
主要思想是提供一个工具,用于使用Python对象创建块。
import json
import pydivkit as dk
container = dk.DivContainer(
items=[
dk.DivGallery(
items=[
dk.DivText(text="Hello from pydivkit")
]
)
]
)
print(json.dumps(container.dict(), indent=1))
# {
# "type": "container",
# "items": [
# {
# "type": "gallery",
# "items": [
# {
# "type": "text",
# "text": "Hello from pydivkit"
# }
# ]
# }
# ]
# }
滑块示例
以下代码是一个使用pydivkit重写的滑块示例。
import pydivkit as dk
slider = dk.DivData(
log_id="sample_card",
states=[
dk.DivDataState(
state_id=0,
div=dk.DivSlider(
width=dk.DivMatchParentSize(),
max_value=10,
min_value=1,
thumb_style=dk.DivShapeDrawable(
color="#00b300",
stroke=dk.DivStroke(
color="#ffffff",
width=3,
),
shape=dk.DivRoundedRectangleShape(
item_width=dk.DivFixedSize(value=32),
item_height=dk.DivFixedSize(value=32),
corner_radius=dk.DivFixedSize(value=100)
),
),
track_active_style=dk.DivShapeDrawable(
color="#00b300",
shape=dk.DivRoundedRectangleShape(
item_height=dk.DivFixedSize(value=6)
)
),
track_inactive_style=dk.DivShapeDrawable(
color="#20000000",
shape=dk.DivRoundedRectangleShape(
item_height=dk.DivFixedSize(value=6)
)
)
)
)
]
)
这个示例可能被序列化为以下形式
import json
print(json.dumps(slider.dict(), indent=1))
# {
# "log_id": "sample_card",
# "states": [
# {
# "div": {
# "type": "slider",
# "max_value": 10,
# "min_value": 1,
# "thumb_style": {
# "type": "shape_drawable",
# "color": "#00b300",
# "shape": {
# "type": "rounded_rectangle",
# "corner_radius": {
# "type": "fixed",
# "value": 100
# },
# "item_height": {
# "type": "fixed",
# "value": 32
# },
# "item_width": {
# "type": "fixed",
# "value": 32
# }
# },
# "stroke": {
# "color": "#ffffff",
# "width": 3
# }
# },
# "track_active_style": {
# "type": "shape_drawable",
# "color": "#00b300",
# "shape": {
# "type": "rounded_rectangle",
# "item_height": {
# "type": "fixed",
# "value": 6
# }
# }
# },
# "track_inactive_style": {
# "type": "shape_drawable",
# "color": "#20000000",
# "shape": {
# "type": "rounded_rectangle",
# "item_height": {
# "type": "fixed",
# "value": 6
# }
# }
# },
# "width": {
# "type": "match_parent"
# }
# },
# "state_id": 0
# }
# ]
# }
模板化和DRY
当然,每次都手动从你的代码中构建块是非常无聊的。因此,第一个想法是将DivKit对象的初始化移动到函数中。
# Naive DRY example which strictly non-recommended
import pydivkit as dk
def get_size(value: int = 32) -> dk.DivFixedSize:
return dk.DivFixedSize(value=value)
def get_shape() -> dk.DivShape:
return dk.DivShape(
item_width=get_size(),
item_height=get_size(),
corner_radius=get_size(100)
)
slider_shape = get_shape()
slider = dk.DivData(
log_id="sample_card",
states=[
dk.DivDataState(
# other arguments
div=dk.DivSlider(
thumb_style=dk.DivShapeDrawable(
shape=slider_shape,
# other arguments
),
# other arguments
)
)
]
)
看起来好一些,但这种方法扩展性不好。为了简化布局和节省流量,DivKit有模板。这是一种布局类似元素的方法,无需声明完整的json,只需声明一个模板,并在类似项中使用多次。
PyDivKit支持通过继承定义模板。
让我们定义一个示例卡片
import json
import pydivkit as dk
class CategoriesItem(dk.DivContainer):
"""
Class inherited from dk.DivContainer will have a template
"""
# Special object for mark this fields a DivKit field in template
icon_url: str = dk.Field()
text: str = dk.Field()
# Set defaults layout for in the template
width = dk.DivWrapContentSize()
background = [dk.DivSolidBackground(color="#f0f0f0")]
content_alignment_vertical = dk.DivAlignmentVertical.CENTER
orientation = dk.DivContainerOrientation.HORIZONTAL
paddings = dk.DivEdgeInsets(left=12, right=12, top=10, bottom=10)
border = dk.DivBorder(corner_radius=12)
items = [
dk.DivImage(
width=dk.DivFixedSize(value=20),
height=dk.DivFixedSize(value=20),
margins=dk.DivEdgeInsets(right=6),
# Special object Ref it's a reference for Field property
image_url=dk.Ref(icon_url),
),
dk.DivText(
width=dk.DivWrapContentSize(),
max_lines=1,
# Special object Ref it's a reference for Field property
text=dk.Ref(text),
),
]
BASE_URL = "https://leonardo.edadeal.io/dyn/re/segments/level1/96"
# So after class definition you might use all the `Field` marked property
# names as an argument.
gallery = dk.DivGallery(
items=[
CategoriesItem(
text="Food", icon_url=f"{BASE_URL}/food.png",
),
CategoriesItem(
text="Alcohol", icon_url=f"{BASE_URL}/alcohol.png",
),
CategoriesItem(
text="Household", icon_url=f"{BASE_URL}/household.png",
),
]
)
print(json.dumps(dk.make_div(gallery), indent=1, ensure_ascii=False))
# {
# "templates": {
# "__main__.CategoriesItem": {
# "type": "container",
# "background": [
# {
# "type": "solid",
# "color": "#f0f0f0"
# }
# ],
# "border": {
# "corner_radius": 12
# },
# "content_alignment_vertical": "center",
# "items": [
# {
# "type": "image",
# "height": {
# "type": "fixed",
# "value": 20
# },
# "$image_url": "icon_url",
# "margins": {
# "right": 6
# },
# "width": {
# "type": "fixed",
# "value": 20
# }
# },
# {
# "type": "text",
# "max_lines": 1,
# "$text": "text",
# "width": {
# "type": "wrap_content"
# }
# }
# ],
# "orientation": "horizontal",
# "paddings": {
# "bottom": 10,
# "left": 12,
# "right": 12,
# "top": 10
# },
# "width": {
# "type": "wrap_content"
# }
# }
# },
# "card": {
# "log_id": "card",
# "states": [
# {
# "div": {
# "type": "gallery",
# "items": [
# {
# "type": "__main__.CategoriesItem",
# "icon_url": "https://leonardo.edadeal.io/dyn/re/segments/level1/96/food.png",
# "text": "Food"
# },
# {
# "type": "__main__.CategoriesItem",
# "icon_url": "https://leonardo.edadeal.io/dyn/re/segments/level1/96/alcohol.png",
# "text": "Alcohol"
# },
# {
# "type": "__main__.CategoriesItem",
# "icon_url": "https://leonardo.edadeal.io/dyn/re/segments/level1/96/household.png",
# "text": "Household"
# }
# ]
# },
# "state_id": 0
# }
# ]
# }
# }
模板名称
默认情况下,模板在类声明时通过元类收集到共享存储中,格式为{module_name}.{class_name}
。
以下示例,虽然不会在现实中出现,但会显示如果类的名称(因此是模板)突然冲突的警告。
import pydivkit as dk
class MyTemplate(dk.DivContainer):
width = dk.DivWrapContentSize()
class MyTemplate(dk.DivContainer):
pass
# RuntimeWarning: Template 'test.MyTemplate' already defined in
# <class 'test.MyTemplate'> and will be replaced to <class 'test.MyTemplate'>
此外,如果你不想向外界展示你的项目结构,或者出于某种原因需要使上述示例更干净,你可以通过声明特殊属性__template_name__
来重命名模板。
import pydivkit as dk
class MyTemplate(dk.DivContainer):
width = dk.DivWrapContentSize()
print(MyTemplate.template_name)
# >>> test.MyTemplate
class MyTemplate(dk.DivContainer):
__template_name__ = "MyTemplate2"
print(MyTemplate.template_name)
# >>> MyTemplate2
项目详情
下载文件
为您的平台下载文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源分发
pydivkit-30.20.0.tar.gz (80.9 kB 查看哈希)
构建分发
pydivkit-30.20.0-py3-none-any.whl (173.5 kB 查看哈希)