PyDIVKit examples
This library is designed to work with DivKit with python.
Features:
- Declarative and imperative DivKit blocks definition
- Native Type-hints support
- Complete object-oriented API
- IDE type checks and suggestions
Object construction
The main idea is to provide a tool for creating blocks using Python objects.
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))
Slider example
Following code is a rewritten slider example using 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)
)
)
)
)
]
)
This example might be serialised like this:
import json
print(json.dumps(slider.dict(), indent=1))
Templating and DRY
Of course, manually building blocks from your code every time is boring.
So, the first idea is to move the initialization of DivKit objects
into functions.
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(
div=dk.DivSlider(
thumb_style=dk.DivShapeDrawable(
shape=slider_shape,
),
)
)
]
)
Looks a little better, but this approach doesn't scale well. To simplify layout
and save traffic, DivKit has templates. This is a way to layout similar elements
without having to declare the complete json, but just declare a template and use
this many times in similar items.
PyDivKit supports defining templates through the inheritance.
Let's define an example card:
import json
import pydivkit as dk
class CategoriesItem(dk.DivContainer):
"""
Class inherited from dk.DivContainer will have a template
"""
icon_url: str = dk.Field()
text: str = dk.Field()
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),
image_url=dk.Ref(icon_url),
),
dk.DivText(
width=dk.DivWrapContentSize(),
max_lines=1,
text=dk.Ref(text),
),
]
BASE_URL = "https://leonardo.edadeal.io/dyn/re/segments/level1/96"
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))
Template names
By default, templates are collecting by the metaclass into shared storage when
the class is declaring at import time, and have the
format {module_name}.{class_name}
.
The following example, sure will not occur in the wild, shows a warning if
suddenly the names of the classes, and hence the templates, conflict.
import pydivkit as dk
class MyTemplate(dk.DivContainer):
width = dk.DivWrapContentSize()
class MyTemplate(dk.DivContainer):
pass
Also, if you do not want to show the structure of your project to the outside,
or for some reason you need to make the example above clean, you can rename the
template by declaring a special attribute __template_name__
import pydivkit as dk
class MyTemplate(dk.DivContainer):
width = dk.DivWrapContentSize()
print(MyTemplate.template_name)
class MyTemplate(dk.DivContainer):
__template_name__ = "MyTemplate2"
print(MyTemplate.template_name)