Skip to main content

A lightweight, async-friendly library for building dynamic, context-aware UI blocks with Pydantic validation and variable substitution.

Project description

EBlock (Easy Block Builder)

A flexible, schema-driven library for building dynamic, context-aware content blocks with variable substitution, nested composition, validation, and asynchronous rendering.

Designed for use in page builders, CMS backends, or dynamic UI generation systems where content is defined as structured JSON, rendered with context variables, and validated via Pydantic models.


Core Concepts

Context

A container for variables and metadata used during block rendering.

  • Variables are case-normalized to uppercase.
  • Supports deep copying for safety.
  • Allows dynamic assignment via ctx["key"] = value.
  • Stores:
    • vars: dictionary of scalar or structured values (strings, numbers, lists, dicts, etc.)
    • path: logical path in the block tree (e.g., /page/hero)
    • extra: arbitrary metadata (not used in substitution)

BaseBlock

Abstract base class for all content blocks.

Each block:

  • Accepts properties (dict) on initialization.
  • Optionally validates input/output using Pydantic models.
  • Recursively resolves {{ variable }} placeholders from Context.
  • Supports nesting (blocks inside dicts, lists, etc.).
  • Exposes a standardized async build() method.
  • Allows custom output transformation via prepare_output().

Features

Variable substitution
Placeholders like {{ user_name }} are replaced with values from context.

Recursive structure support
Handles dicts, lists, tuples, sets, and nested BaseBlock instances.

Input/Output validation
Define _input_schema and _output_schema using Pydantic models.

Computed fields
Override prepare_output() to add or transform fields after substitution but before output validation.

Static dependency analysis
Use .get_vars() to extract all required variables from a block (including nested ones).

Async-first design
Full async/await support for future extensibility (e.g., async data fetching in prepare_output).

Structured logging
Each block and context instance logs actions with a unique hierarchical logger name.


Usage Examples

Basic Block

from easy_block_builder import BaseBlock, Context

class TextBlock(BaseBlock):
    _type = "text"

ctx = Context("/", vars={"name": "Alice"})
block = TextBlock({"content": "Hello, {{ name }}!"})
result, _ = await block.build(ctx)
# result = {"content": "Hello, Alice!"}

Validated Block with Computed Output

from pydantic import BaseModel

class Input(BaseModel):
    title: str
    score: int

class Output(BaseModel):
    title: str
    score: int
    badge: str

class ScoreCard(BaseBlock):
    _type = "score_card"
    _input_schema = Input
    _output_schema = Output

    async def prepare_output(self, result, ctx):
        result["badge"] = "🏆" if result["score"] >= 90 else "📝"
        return result

Nested Blocks

header = TextBlock({"text": "Welcome, {{ user }}!"})
page = PageBlock({"header": header, "theme": "{{ theme }}"})
# Both `user` and `theme` will be resolved from context

Variable Inspection

block = TextBlock({"msg": "Hi {{ first }}, {{ last }}!"})
print(block.get_vars())  # {"first", "last"}

API Reference

class Context

  • __init__(self, path: str, vars: dict | None = None, **extra)
  • __getitem__(key), __setitem__(key, value)
  • Properties: path, vars (deep copy), extra (shallow copy)

class BaseBlock

  • __init__(self, properties: dict)
  • async build(self, ctx: Context) -> tuple[dict, Type[BaseModel] | None]
  • async prepare_output(self, result: dict, ctx: Context) -> dict (override to customize)
  • get_vars(self) -> set[str]
  • Properties: type (read-only)

Class-level attributes (define in subclass)

  • _type: str — block identifier (e.g., "image", "form")
  • _input_schema: Type[BaseModel] | None
  • _output_schema: Type[BaseModel] | None

Requirements

  • Python ≥ 3.10
  • Pydantic ≥ 2.0

Notes

  • All string placeholders must use double curly braces: {{ var_name }}.
  • Whitespace inside placeholders is stripped: {{ user_id }}user_id.
  • If a variable is missing in context, it resolves to None and logs a warning.
  • Blocks are not reusable across different build() calls if they hold mutable state — design them as stateless.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

eblock-0.2.0.tar.gz (14.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

eblock-0.2.0-py3-none-any.whl (10.3 kB view details)

Uploaded Python 3

File details

Details for the file eblock-0.2.0.tar.gz.

File metadata

  • Download URL: eblock-0.2.0.tar.gz
  • Upload date:
  • Size: 14.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for eblock-0.2.0.tar.gz
Algorithm Hash digest
SHA256 dc902cec442426b64276397d21be38a38b14551b7d827f83b999fa31977ef737
MD5 7190b9703a6bfe38c2fb816fd3183e0e
BLAKE2b-256 82f78d0088a78264cc28015dae7b4f2bd3a4598d69b7651140a60c050401a08b

See more details on using hashes here.

Provenance

The following attestation bundles were made for eblock-0.2.0.tar.gz:

Publisher: python-publish.yml on GAKiknadze/easy_block_builder

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file eblock-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: eblock-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 10.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for eblock-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e9b62d18b4f42deb8c5b0483a4c3de05dd94c15df71ac109bdc76cc56ef66228
MD5 2f2ace711b6c9538df877dd642bbb62d
BLAKE2b-256 97c8afe695b817ea0905e3e8e04af015dc8d4c253559f3e1ba2b7f8b7b0c03f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for eblock-0.2.0-py3-none-any.whl:

Publisher: python-publish.yml on GAKiknadze/easy_block_builder

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page