Building Modular Applications with Semablocks

Reading time ~2 minutes

Semablocks

Semablocks

Semablocks is an internal approach to building modular, reusable code blocks—inspired by Lego Blocks—that you can compose into larger applications.
Instead of writing monolithic scripts, you build small, versioned blocks in Bash, Python, Go, and other languages. These blocks can then be combined into composite workflows, orchestrated by a runner, and imported into your applications (like Flask).

Why Semablocks?

  • Reusability: Write once, reuse in multiple projects.
  • Versioning: Update or patch individual blocks without breaking larger workflows.
  • Cross-Language: Use Bash for automation, Python for data handling, and Go for high-performance binaries—all in one ecosystem.
  • Simplicity: Each block has a single responsibility, making debugging and scaling easier.

Example Project Structure

semablocks/
  blocks/
    bash/
      fetch_data/
        v1.0/
          fetch_data.sh
    python/
      parse_json/
        v1.1/
          parse_json/           # Python package
            __init__.py
            core.py
          pyproject.toml
          tests/
    go/
      generate_report/
        v1.0/
          cmd/
            main.go
          go.mod
  composites/
    daily_report/
      workflow.yaml
  orchestration/
    runner/
      run_block.py
      runner.go
  docs/
    index.md
  registry/
    index.json   # optional metadata index for all blocks
  • Blocks: Small, atomic units (e.g., parse_json for JSON parsing).
  • Composites: Combine multiple blocks into larger workflows (e.g., daily_report).
  • Orchestration: Scripts or binaries that run blocks in sequence.

Using Semablocks in a Flask Application

Step 1: Package a Python Block

A simple Python block (parse_json) could look like this in a core.py file:

import json

def parse_json_string(json_string):
    """Parse JSON and return a Python object."""
    return json.loads(json_string)

THe __init__.py would look like this:

from .core import parse_json_string

The pyproject.toml would look like:

[project]
name = "semablocks-parse-json"
version = "1.1.0"
description = "Semablock for parsing JSON"
dependencies = []

[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

Build the block:

python3 -m build

This generates a .whl file under dist/.

Step 2: Install the Block in Your Flask App

You can install the package from a local build:

pip install dist/semablocks_parse_json-1.1.0-py3-none-any.whl

Or from your internal PyPI (see next section).

Step 3: Import and Use the Block in Flask

From your app.py:

from flask import Flask, request, jsonify
from semablocks_parse_json import parse_json_string

app = Flask(__name__)

@app.route("/parse", methods=["POST"])
def parse():
    data = request.get_data(as_text=True)
    try:
        result = parse_json_string(data)
        return jsonify(result)
    except Exception as e:
        return jsonify({"error": str(e)}), 400

if __name__ == "__main__":
    app.run()

Using an Internal PyPI with Semablocks

For distributing Python Semablocks across multiple projects and teams, set up an internal PyPI-like registry.

Option 1: Devpi (Lightweight Internal PyPI)

Install Devpi

pip install devpi-server devpi-client

Initialize and Run

devpi-server --start --host 0.0.0.0 --port 3141
devpi use http://localhost:3141
devpi login root --password=''
devpi user -c myuser password=secret
devpi index -c semablocks
devpi use semablocks

Upload a Block

From your block directory:

python3 -m build
devpi upload

Install from Internal PyPI

pip install --index-url http://myuser:secret@your-internal-pypi:3141/semablocks semablocks-parse-json==1.1.0

Option 2: Private GitHub Repo

For quick adoption, you can also host your block in a private GitHub repo and install directly:

pip install git+ssh://git@github.com:YourOrg/semablocks.git@main#subdirectory=blocks/python/parse_json/v1_1

Summary

Semablocks lets you build modular, reusable code blocks that integrate seamlessly into larger applications like Flask.

Use an internal PyPI (e.g., Devpi) to easily distribute Python Semablocks across projects.

With proper packaging, your blocks are versioned, reusable, and maintainable.