Skip to main content

discomposer for discord.py

Validate, fetch and send Discord message templates as Components V2.
Design the message in the visual editor, send it from your bot with a code.

PyPI Python versions MIT license

discomposer only builds messages. What a button or selection does (open a ticket, hand out a role) stays in your bot.

Install

pip install discomposer

Requires Python 3.11+ and discord.py 2.6+.

Fetch a template and send it

import discord
from discomposer import EditorClient, MediaStore, render_message, select_rows

editor = EditorClient(media=MediaStore("data/media"))

async def send(channel, code):
    design = await editor.fetch(code)  # validates and keeps a copy of every image
    view = discord.ui.LayoutView(timeout=None)
    for item in render_message(
        design,
        guild=channel.guild,
        buttons={"ticket": lambda b: discord.ui.Button(label=b["label"], custom_id="mybot:ticket")},
        slots={"online": "12 members online"},
        selects=lambda menu, guild: select_rows(menu, f"mybot:{menu['id']}"),
    ):
        view.add_item(item)
    await channel.send(view=view, files=editor.media.files_for(design))

render_message returns the text outside the box (if any) and the filled container. Use render to fill a container you created yourself.

Offer your bot's features in the editor

from discomposer import guild_context

link = await editor.open({
    "title": "Ticket panel",
    "context": {
        **guild_context(guild),
        "buttons": [{"id": "ticket", "label": "Open ticket"}],
        "selects": [{"purpose": "ticket_categories", "label": "Ticket categories", "roles": "optional"}],
    },
    "design": {"blocks": [{"text": "## Support"}]},
})

The person designs the message at link and gives your bot the new code.

Handle a selection

Values and roles only ever come from the stored template, never from the interaction:

from discomposer import category_roles, chosen_category, ticket_overwrites

option = chosen_category(saved_design, "tickets", interaction.data["values"][0])
if option:
    roles = category_roles(guild, option)
    channel = await guild.create_text_channel(
        f"ticket-{interaction.user.name}",
        overwrites=ticket_overwrites(guild, interaction.user, roles),
    )

API overview

Area Functions
Format validate, validate_design, find_select, selects_for, chosen_options
Sending render, render_message, outside_text, select_rows, fill_variables, VARIABLES
Editor EditorClient (open, fetch, fetch_document, upload, adopt_images, expose_attachments, open_message), guild_context, parse_code
Images MediaStore (save, files_for)
Tickets ticket_categories, chosen_category, category_roles, missing_roles, ticket_overwrites, transcript_markdown

Errors: TemplateError (format), EditorError (editor, network), MediaError (images). Messages are written for end users.

The template format is specified in spec/FORMAT.md. A JavaScript version for discord.js is available as discomposer on npm.

discomposer is not affiliated with or endorsed by Discord Inc.

Metadata

Release files for discomposer 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for discomposer 0.1.0
File Size Uploaded Provenance Actions
discomposer-0.1.0.tar.gz 17.2 kB With provenance Details for discomposer-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for discomposer 0.1.0
File Interpreter ABI Platform Actions
discomposer-0.1.0-py3-none-any.whl Python 3 none any Details for discomposer-0.1.0-py3-none-any.whl

Total release size: 35.0 kB

Release files / discomposer-0.1.0.tar.gz

Download URL discomposer-0.1.0.tar.gz
Size 17.2 kB
Tags Source
SHA-256 checksum
How to use checksums
384f2021cdfc524f544272951cda7d233b768c0763cad1532066acea66f2cc1e
BLAKE2b-256 checksum
How to use checksums
2f0b27c4a6d3f29383a162f7022ede7953882395524194f75a65421c275532c4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.

Transparency log

Release files / discomposer-0.1.0-py3-none-any.whl

Download URL discomposer-0.1.0-py3-none-any.whl
Size 17.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2fcda79068d5868a30644227642eda9cd064fd6b7be857459e01fa66cad197be
BLAKE2b-256 checksum
How to use checksums
c58871f25e2bcae5f3e9f93a46ff24dfa5f618b539122669c2674601f93a6273
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.

Transparency log

Security for discomposer 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for discomposer-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page