interloper-slack
Slack notifications for interloper runs: a SlackHook that posts a run
outcome to a channel, and the SlackConnection that holds the bot token.
The hook is the notification counterpart to core's WebhookHook — same
events, but the payload is a message a human reads rather than a document a
service parses.
Setup
- Create a Slack app (From scratch) at api.slack.com/apps.
- Under OAuth & Permissions, add these bot token scopes:
chat:write— post the notificationchannels:read,groups:read— populate the channel picker
- Install to Workspace and copy the bot user token (
xoxb-…). - Invite the bot to each channel it posts to (
/invite @your-app). Slack rejectschat.postMessagewithnot_in_channelotherwise.
One connection serves the whole workspace; each hook picks its own channel.
Usage
import interloper as il
from interloper_slack import SlackConnection, SlackHook
hook = SlackHook(
connection=SlackConnection(bot_token="xoxb-..."),
channel="C0123456789",
watches=[my_source],
events=["run_failed"],
)
The token also loads from the environment (SLACK_BOT_TOKEN), so
SlackConnection() works with no arguments.
events defaults to ["run_failed"] like every hook — the alert most teams
want. Add "run_completed" for a full-chatter channel.
In a deployed instance you configure this through the UI instead: add a Slack connection, then a Slack hook watching the source or job you care about. The scheduler's hook evaluator fires it on terminal runs.
Message shape
❌ *Facebook Ads* failed
Run `9f3c…` · partition `2026-07-30`
HTTPStatusError: 429 Too Many Requests
The headline also travels as the message's text, so notification previews
and screen readers get the outcome without parsing blocks.
Notes
Every Slack call goes through the connection's client — a cached_property
il.RESTClient with il.HTTPBearerAuth, like every other connection in the
workspace. That client owns the base URL, the token, and the connection pool,
so callers name a path and nothing else; the channel picker paginates with
il.JSONCursorPaginator over Slack's response_metadata.next_cursor.
The client is sync, where most connections' are async. The two consumers are a hook firing (sync by contract) and a form lookup — neither has independent requests to overlap, and the API process runs sync providers in a thread, so it never blocks the event loop.
The one thing the framework can't cover is that Slack answers a rejected
call with HTTP 200 and {"ok": false, "error": "..."}, so raise_for_status()
alone lets failures pass silently. Each call site checks ok itself and raises
RuntimeError with Slack's own error code — the same shape as the other
connections that face an in-body error flag. For the paginated picker that
check lives in the data_selector, since paginate only raises for HTTP
status.
A failed firing is recorded on the hook's firing claim (as hook_failed) and
is not retried.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file interloper_slack-0.58.0.tar.gz.
File metadata
- Download URL: interloper_slack-0.58.0.tar.gz
- Upload date:
- Size: 5.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6794c7c3c5b2fc7faf2a4bdcc8cc67f1139df6383f79e80710e53e08e17f659b
|
|
| MD5 |
94248424526b355d6ac9a313415fcd35
|
|
| BLAKE2b-256 |
600669fe1edf2144508507871459f9c7461d12b1e4e6d8e1db8ca1c62f565d75
|
File details
Details for the file interloper_slack-0.58.0-py3-none-any.whl.
File metadata
- Download URL: interloper_slack-0.58.0-py3-none-any.whl
- Upload date:
- Size: 7.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
847bb7b762c9d8f6925ea45b99b6f24a58d5ab0854474a557dc748bb56d655a0
|
|
| MD5 |
09179ea0a64d7f776ad5851401a578be
|
|
| BLAKE2b-256 |
2716d64b1bd1edc8d3b8e4869751203c5b2222d6b83563212293be7e753a358b
|