slack-events 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.3
2
+ Name: slack-events
3
+ Version: 0.1.0
4
+ Summary: TypedDicts for every Slack event, with optional pydantic validation, FastAPI dispatch, and ergonomic bot handlers
5
+ Requires-Dist: typing-extensions>=4.12
6
+ Requires-Dist: slack-sdk[optional]>=3.27 ; extra == 'client'
7
+ Requires-Dist: fastapi>=0.110 ; extra == 'fastapi'
8
+ Requires-Dist: pydantic>=2.0 ; extra == 'fastapi'
9
+ Requires-Dist: pydantic>=2.0 ; extra == 'pydantic'
10
+ Requires-Python: >=3.11
11
+ Provides-Extra: client
12
+ Provides-Extra: fastapi
13
+ Provides-Extra: pydantic
14
+ Description-Content-Type: text/markdown
15
+
16
+ # slack-events
17
+
18
+ Typed Slack events, dispatch, and bot reply helpers.
19
+
20
+ ```sh
21
+ pip install slack-events
22
+ pip install 'slack-events[fastapi,client]'
23
+ ```
24
+
25
+ The Python import is `slack_events`. The base package depends only on `typing-extensions`;
26
+ `pydantic`, `fastapi`, and `client` extras enable validation, HTTP routing, and the
27
+ Slack SDK client respectively.
28
+
29
+ ## Responding with Block Kit
30
+
31
+ `Thread.post`, `Message.reply`, `SlashCommand.respond`, `Action.respond`, and
32
+ string returns from `SlackBot` command handlers accept **standard Markdown**.
33
+ They send a `markdown` block and top-level `text` containing the same content for
34
+ notifications and screen readers. Slack performs the Markdown conversion.
35
+ `post_stream` uses Slack's native Markdown streaming protocol; its post-and-edit
36
+ fallback sends blocks on both the initial post and every update.
37
+
38
+ ```python
39
+ await message.reply("## Results\n**Done.** See [the report](https://example.com).")
40
+ ```
41
+
42
+ Use explicit `blocks=` for interactive layouts, structured `rich_text`, or legacy
43
+ Slack `mrkdwn`. In this case `text` is your accessible fallback and should contain
44
+ all necessary information. Explicit blocks are passed through unchanged; `[]`
45
+ is an intentional opt-out. Raw dictionary returns and the low-level dispatcher
46
+ also remain caller-controlled.
47
+
48
+ `message_payload(text, blocks=...)` exposes the same policy to response layers
49
+ that call Slack directly. Generated Markdown is capped at Slack's cumulative
50
+ 12,000-character limit, with a visible truncation notice. Applications can use
51
+ `truncate_markdown` to reserve room for a link to the full response. Callers
52
+ supplying their own blocks are responsible for block limits and content.
53
+
54
+ Slack's references:
55
+
56
+ - [Markdown blocks for LLM output](https://docs.slack.dev/reference/block-kit/blocks/markdown-block/)
57
+ - [Rich text for structured user-authored content](https://docs.slack.dev/reference/block-kit/blocks/rich-text-block/)
58
+ - [Fallback text and accessibility](https://docs.slack.dev/reference/methods/chat.postMessage/)
59
+ - [Streaming finalization](https://docs.slack.dev/reference/methods/chat.stopStream/)
60
+
61
+ In mo, finalized replies replace the complete message with Markdown blocks after
62
+ stopping a native stream. Blocks passed to `chat.stopStream` would be appended to
63
+ the streamed content, so that method is not used to replace the answer.
@@ -0,0 +1,48 @@
1
+ # slack-events
2
+
3
+ Typed Slack events, dispatch, and bot reply helpers.
4
+
5
+ ```sh
6
+ pip install slack-events
7
+ pip install 'slack-events[fastapi,client]'
8
+ ```
9
+
10
+ The Python import is `slack_events`. The base package depends only on `typing-extensions`;
11
+ `pydantic`, `fastapi`, and `client` extras enable validation, HTTP routing, and the
12
+ Slack SDK client respectively.
13
+
14
+ ## Responding with Block Kit
15
+
16
+ `Thread.post`, `Message.reply`, `SlashCommand.respond`, `Action.respond`, and
17
+ string returns from `SlackBot` command handlers accept **standard Markdown**.
18
+ They send a `markdown` block and top-level `text` containing the same content for
19
+ notifications and screen readers. Slack performs the Markdown conversion.
20
+ `post_stream` uses Slack's native Markdown streaming protocol; its post-and-edit
21
+ fallback sends blocks on both the initial post and every update.
22
+
23
+ ```python
24
+ await message.reply("## Results\n**Done.** See [the report](https://example.com).")
25
+ ```
26
+
27
+ Use explicit `blocks=` for interactive layouts, structured `rich_text`, or legacy
28
+ Slack `mrkdwn`. In this case `text` is your accessible fallback and should contain
29
+ all necessary information. Explicit blocks are passed through unchanged; `[]`
30
+ is an intentional opt-out. Raw dictionary returns and the low-level dispatcher
31
+ also remain caller-controlled.
32
+
33
+ `message_payload(text, blocks=...)` exposes the same policy to response layers
34
+ that call Slack directly. Generated Markdown is capped at Slack's cumulative
35
+ 12,000-character limit, with a visible truncation notice. Applications can use
36
+ `truncate_markdown` to reserve room for a link to the full response. Callers
37
+ supplying their own blocks are responsible for block limits and content.
38
+
39
+ Slack's references:
40
+
41
+ - [Markdown blocks for LLM output](https://docs.slack.dev/reference/block-kit/blocks/markdown-block/)
42
+ - [Rich text for structured user-authored content](https://docs.slack.dev/reference/block-kit/blocks/rich-text-block/)
43
+ - [Fallback text and accessibility](https://docs.slack.dev/reference/methods/chat.postMessage/)
44
+ - [Streaming finalization](https://docs.slack.dev/reference/methods/chat.stopStream/)
45
+
46
+ In mo, finalized replies replace the complete message with Markdown blocks after
47
+ stopping a native stream. Blocks passed to `chat.stopStream` would be appended to
48
+ the streamed content, so that method is not used to replace the answer.
@@ -0,0 +1,31 @@
1
+ [project]
2
+ name = "slack-events"
3
+ version = "0.1.0"
4
+ description = "TypedDicts for every Slack event, with optional pydantic validation, FastAPI dispatch, and ergonomic bot handlers"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ dependencies = ["typing-extensions>=4.12"]
8
+
9
+ [project.optional-dependencies]
10
+ pydantic = ["pydantic>=2.0"]
11
+ fastapi = ["fastapi>=0.110", "pydantic>=2.0"]
12
+ # slack-sdk's async client needs aiohttp, which ships under its "optional" extra
13
+ client = ["slack-sdk[optional]>=3.27"]
14
+
15
+ [dependency-groups]
16
+ dev = [
17
+ "fastapi>=0.110",
18
+ "httpx>=0.28",
19
+ "pydantic>=2.0",
20
+ "pytest>=9.0",
21
+ "pytest-asyncio>=1.4",
22
+ "slack-sdk[optional]>=3.27",
23
+ ]
24
+
25
+ [build-system]
26
+ requires = ["uv_build>=0.11,<0.12"]
27
+ build-backend = "uv_build"
28
+
29
+ [tool.pytest.ini_options]
30
+ asyncio_mode = "auto"
31
+ testpaths = ["tests"]
@@ -0,0 +1,90 @@
1
+ """slack_events: TypedDicts for every Slack event, plus dispatch and bot handlers.
2
+
3
+ Core (typing-extensions only): the generated payload TypedDicts (re-exported here),
4
+ the event registry, SlackDispatcher (signature verification + routing), and
5
+ SlackBot (thread subscriptions, mentions, patterns, reactions, commands,
6
+ actions, views). Optional extras: slack-events[pydantic] adds payload
7
+ validation (used automatically when pydantic is installed);
8
+ slack-events[fastapi] adds a mountable endpoint via .as_fastapi_router();
9
+ slack-events[client] enables replying via the official slack_sdk AsyncWebClient.
10
+
11
+ Payload types keep their Slack names — AppMentionEvent, GenericMessageEvent,
12
+ ReactionAddedEvent, ... — with MessageEvent as the union of all message
13
+ subtypes. SlackEvent unions all of them.
14
+ """
15
+
16
+ from slack_events import _models
17
+ from slack_events._models import * # noqa: F403 - generated re-export
18
+ from slack_events._registry import (
19
+ DEFAULT_SUBTYPE_TYPES,
20
+ EVENT_NAMES,
21
+ EVENT_TYPES,
22
+ EVENTS_WITH_SUBTYPES,
23
+ SUBTYPE_TYPES,
24
+ EventName,
25
+ )
26
+ from slack_events.bot import SlackBot
27
+ from slack_events.formatting import message_payload, truncate_markdown
28
+ from slack_events.dispatch import (
29
+ SignatureVerificationError,
30
+ SlackDispatcher,
31
+ SlackError,
32
+ WebhookResult,
33
+ )
34
+ from slack_events.objects import (
35
+ Action,
36
+ Author,
37
+ DeletedMessage,
38
+ Message,
39
+ Reaction,
40
+ SlashCommand,
41
+ Thread,
42
+ ViewSubmission,
43
+ )
44
+ from slack_events.payloads import (
45
+ ActionPayload,
46
+ AppRateLimitedPayload,
47
+ Authorization,
48
+ BlockActionsPayload,
49
+ EventCallbackEnvelope,
50
+ SlashCommandPayload,
51
+ UrlVerificationPayload,
52
+ ViewClosedPayload,
53
+ ViewSubmissionPayload,
54
+ )
55
+ from slack_events.state import InMemoryStateStore, StateStore
56
+
57
+ __all__ = [
58
+ *_models.__all__,
59
+ "DEFAULT_SUBTYPE_TYPES",
60
+ "EVENT_NAMES",
61
+ "EVENT_TYPES",
62
+ "EVENTS_WITH_SUBTYPES",
63
+ "SUBTYPE_TYPES",
64
+ "EventName",
65
+ "Action",
66
+ "ActionPayload",
67
+ "AppRateLimitedPayload",
68
+ "Authorization",
69
+ "Author",
70
+ "BlockActionsPayload",
71
+ "DeletedMessage",
72
+ "EventCallbackEnvelope",
73
+ "InMemoryStateStore",
74
+ "Message",
75
+ "message_payload",
76
+ "truncate_markdown",
77
+ "Reaction",
78
+ "SignatureVerificationError",
79
+ "SlackBot",
80
+ "SlackCommand",
81
+ "SlackDispatcher",
82
+ "SlackError",
83
+ "StateStore",
84
+ "Thread",
85
+ "UrlVerificationPayload",
86
+ "ViewClosedPayload",
87
+ "ViewSubmission",
88
+ "ViewSubmissionPayload",
89
+ "WebhookResult",
90
+ ]