Setting up Slack
First, navigate to https://api.slack.com/apps and click the “Create New App” on the top right. A modal window will pop up giving you a couple of options, select “From scratch”. Fill out the App Name and associate the app with a workspace, finally click “Create App”.
Once that’s done, your app needs an incoming webhook, which will be used to dispatch messages to Slack.
The sidebar contains an item, Incoming Webhooks. Once selected, activate it and then click “Add New Webhook to Workspace”, which will bring up a permission window.
Select the channel you’d like the webhook to aim at and then click “Allow”, which will take you back to the “Incoming Webhook” view. The table at the bottom contains all the information you will need in order to send your Slack messages programmatically. So, let’s move on to code.
Python time
In it’s simplest form, we need a class as a representation of Slack and an exception class. This means that we can use inheritance to make different exceptions implement the Slack messaging facility. I will also include a Pydantic Settings reference for this example and
write up a walkthrough in a later post.
from pydantic_settings import BaseSettings, SettingsConfigDict
class AppSettings(BaseSettings):
slack_webhook_url: str
model_config = SettingsConfigDict(case_sensitive=False)
settings = AppSettings()
In this basic Pydantic Settings class, we can set our Slack URL that we obtained from the table above by way of an environmental variable. Remember to create the environmental variable as
uppercase – SLACK_WEBHOOK_URL = https://hooks.slack.com/services/***/***/***
Next we write up our Slack class. For this, I will be using HTTPX.
import httpx
from httpx import Response
class Slack:
def init(self, app_settings: AppSettings):
self.app_settings = app_settings
def dispatch_message(self, message: str) -> Response:
return httpx.post(
self.app_settings.slack_webhook_url,
json={"text": message},
headers={"content-type": "application/json"}
)
A simple, single method class is all we need for this example. You could do an awful lot more, all of which would be out of scope for this article. All we need to do is translate the cURL example in the Incoming Webhooks table example into a HTTPX request – it’s a POST request and we are sending JSON data. Next, let’s create our exception class.
class SlackableException(Exception):
def init(self, message):
self.message = message
self.slack_response = self.dispatch_to_slack()
def dispatch_to_slack(self):
slack = Slack(app_settings)
return slack.dispatch_message(
message=self.message,
)
By inheriting from the base Exception class, we simply need to add a method to use the Slack class and then everything else will work just as any other exception would. Finally, we write our custom exception that inherits from the SlackableException class.
class MailchimpClientException(SlackableException):
pass
In this example case, we don’t really need our custom exception to do anything other than dispatch to Slack, so pass
is sufficient. Let’s test it out.
raise MailchimpClientException(message="Testing 123")
And there you have it. Custom exceptions that forward to Slack.