Skip to content

Commit df39bee

Browse files
srtaalejzimeg
andauthored
docs(maintainers): adding block kit types instructions (#1861)
Co-authored-by: Eden Zimbelman <eden.zimbelman@salesforce.com>
1 parent 9435412 commit df39bee

2 files changed

Lines changed: 71 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ Defined in `.github/workflows/ci-build.yml`, runs on push to `main`, all PRs, an
281281
3. Add tests mirroring the module structure
282282
4. Validate: `./scripts/run_validation.sh`
283283

284+
### Adding a New Block Kit Type
285+
286+
See [`slack_sdk/models/AGENTS.md`](slack_sdk/models/AGENTS.md) for detailed steps on defining, registering, exporting, and testing new Block Kit blocks, elements, and composition objects.
287+
284288
### Fixing a Bug
285289

286290
1. Write a test that reproduces the bug

slack_sdk/models/AGENTS.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# AGENTS.md — Block Kit Models
2+
3+
The `slack_sdk/models/` package provides Python classes for building [Block Kit](https://api.slack.com/block-kit) UI layouts. Each class serializes to/from the JSON payloads that the Slack API expects, with helper methods for parsing nested composition objects.
4+
5+
## Adding a New Block Kit Type
6+
7+
Block Kit models live in `slack_sdk/models/blocks/` across three files:
8+
9+
| File | Contents |
10+
| --- | --- |
11+
| `blocks.py` | Layout blocks (`SectionBlock`, `ActionsBlock`, `HeaderBlock`, etc.) |
12+
| `block_elements.py` | Interactive elements (`ButtonElement`, `StaticSelectElement`, `DatePickerElement`, etc.) |
13+
| `basic_components.py` | Composition objects (`TextObject`, `Option`, `ConfirmObject`, etc.) |
14+
15+
All types are exported from `slack_sdk/models/blocks/__init__.py`.
16+
17+
### Base class hierarchy
18+
19+
```
20+
JsonObject
21+
├── Block → layout blocks
22+
├── BlockElement → non-interactive elements
23+
│ └── InteractiveElement → elements with action_id
24+
│ └── InputInteractiveElement → elements usable inside InputBlock
25+
├── TextObject → PlainTextObject, MarkdownTextObject
26+
├── Option / OptionGroup
27+
└── ConfirmObject, etc.
28+
```
29+
30+
Choose the base class that matches the type you're adding.
31+
32+
### Steps
33+
34+
1. **Define the class** in the appropriate file. Follow this pattern:
35+
36+
```python
37+
class MyNewBlock(Block):
38+
type = "my_new_block"
39+
40+
@property
41+
def attributes(self) -> Set[str]:
42+
return super().attributes.union({"text", "optional_field"})
43+
44+
def __init__(self, *, text: Union[str, dict, TextObject], optional_field: Optional[str] = None, block_id: Optional[str] = None, **others: dict):
45+
super().__init__(type=self.type, block_id=block_id)
46+
show_unknown_key_warning(self, others)
47+
self.text = TextObject.parse(text, default_type=PlainTextObject.type)
48+
self.optional_field = optional_field
49+
```
50+
51+
Key conventions:
52+
- Set `type` class attribute to the Slack API type string
53+
- Override `attributes` to return the set of JSON field names for serialization
54+
- Call `super().__init__()` with `type=self.type`
55+
- Call `show_unknown_key_warning(self, others)` to log unexpected kwargs
56+
- Use `TextObject.parse()`, `ConfirmObject.parse()`, and `BlockElement.parse()` for nested composition objects
57+
58+
2. **Register for deserialization:**
59+
- **Elements:** Automatic — `BlockElement.parse()` discovers subclasses at runtime via `__subclasses__()`. No manual step needed.
60+
- **Blocks:** Manual — add an `elif` clause in `Block.parse()` (in `blocks.py`) mapping the type string to the new class.
61+
62+
3. **Export the class** — add it to the imports and `__all__` list in `slack_sdk/models/blocks/__init__.py`.
63+
64+
4. **Add tests** in `tests/slack_sdk/models/test_blocks.py`. Cover:
65+
- Round-trip: `input_dict == MyNewBlock(**input_dict).to_dict()`
66+
67+
5. **Validate:** `./scripts/run_validation.sh`

0 commit comments

Comments
 (0)