
This script just touches the surface of what is possible utilizing Python, Plotly Dash, and our APIs.
Business in a box.
Discover our solutions.
Talk to our sales team
Almost a year ago, Tom Mairs, Bird’s director of customer success, wrote a mailer tool utilizing Bird APIs. In this post, I pick up where he left off. His tool allows for timed transmission of jobs, but what if we want to create our own dashboards and event logs?
Perhaps I want to create a specific dashboard for a business group or a customer-facing dashboard, but not provide users full access to the Bird UI. This script just touches the surface of what is possible utilizing Python, Plotly Dash, and our APIs.
As I began my search online, I wanted to find the path of least resistance. I could have created all the dashboards and UI myself in HTML and python, however, after some Google searching, I came across Plotly’s Dash, which integrates easily with python. I chose Dash for 2 reasons: 1) it is open source, and 2) after reading the documentation it seemed easily customizable for what I was trying to do. Dash is an open-source library that is ideal for building and deploying data apps with customized user interfaces. This made creating a UI extremely simple. The question then became, how complex did I want to make this app? The more time I spent, the more features I wanted to add.
For the initial project, I wanted to ensure that I had a dashboard with customizable metrics and a selectable timeframe. Initially, I started with a dashboard where you could only pick one metric from the dropdown. Then, as I got feedback from colleagues, I refined the dashboard a little bit to add multi-select and axis titles. I also decided to add an additional tab for an events log. I came to the point where I was satisfied with what I had as a good starting point for anyone wishing to build out their own dashboards. Of course, I put the project in Github for you to clone or branch.
Getting Started
To access this app, you will need to ensure you are running python 3.10 or above and install the following libraries:
requests
dash
pandas
Then, input your API key into App.py and run the app. It will run on http://localhost:8050. For further information on deploying this to a public-facing server (such as AWS), see the following resources:
Creating the Dashboard Page
Creating the Event Details Page
The event details page was a little more difficult because I didn’t know the best way to present all of the events metrics in an easy-to-read manner. I considered adding filtering parameters to this page, however, I decided that would add a significant amount of time to this project as the table would then have to be dynamic (along with adding the parameters, callbacks, etc.). I settled on showing all of the events and placing the timestamp first (as without putting the timestamp first, the chart wasn’t easy to read). Initially, I found that with just the raw HTML, the table was incredibly difficult on the eyes. There were no borders and no color differences for header vs rows. To make the table easier to read, I was able to use CSS within Dash.
The idea for the event details is almost the same as the dashboard, except this time, I call the Events API and bring in all events. Note the event details only shows the 10 most recent events (utilizing the max_rows parameter and API filtering). This can be increased, however, I settled on showing the 10 most recent events because the more events have shown, the longer the API call takes. One significant improvement that could be made would be the ability to paginate and include a Next Page / Previous Page in the UI.
To build out the events tab (page), first, I call the Events API and parse the JSON response into a data frame. Then I sort and reorder the data frame to put timestamp as the first column. Finally, I build out the HTML table by iterating through the data frame.
#Build out and call the events API params = { "events" : "delivery,injection,bounce,delay,policy_rejection,out_of_band,open,click,generation_failure,generation_rejection,spam_complaint,list_unsubscribe,link_unsubscribe", "delimiter" : ",", "page" : "1", "per_page" : "10" } api_url = BASE_URL + "/events/message" response_API = requests.get(api_url, headers = {"Authorization" : API_KEY}, params=params) response_info = json.loads(response_API.text) new_df = pd.json_normalize(response_info, record_path=['results']) max_rows=10 #Max number of results show in the events table #Place timestamp as the first column in the table new_df = new_df.reindex(sorted(new_df.columns), axis=1) cols = ['timestamp'] new_df = new_df[cols + [c for c in new_df.columns if c not in cols]] #Show the new HTML with the events table (note, this table also references table.css) return html.Div([ html.H2("Event Details"), html.Table([ html.Thead( html.Tr([html.Th(col) for col in new_df.columns],className="table_css") ), html.Tbody([ html.Tr([ html.Td(new_df.iloc[i][col],className="table_css") for col in new_df.columns ]) for i in range(min(len(new_df), max_rows)) ]) ]) ])
Which looks like this in the UI.

Next Steps
For someone looking to create their own dashboard or event log, this is a good start. With the customizability here, the sky’s the limit.
As discussed above, some future improvements that could be made are:
Adding deliverability analytics to the dashboard
Adding more filters to the dashboard
Possible caching options so the API isn’t being called every time to display the pages
UI Improvements
Adding filtering and pagination to the event details page
I’d be interested in hearing any feedback or suggestions for expanding this project.
~ Zach Samuels, Bird Senior Solutions Engineer