Bereik

Grow

Manage

Automate

Bereik

Grow

Manage

Automate

Een dashboardtool met Bird API's

Zachary Samuels

24 mrt 2022

E-mail

1 min read

Een dashboardtool met Bird API's

Zachary Samuels

24 mrt 2022

E-mail

1 min read

Een dashboardtool met Bird API's

Dit script raakt slechts de oppervlakte van wat mogelijk is met behulp van Python, Plotly Dash en onze API's.

Bijna een jaar geleden schreef Tom Mairs, Director Customer Success van Bird, een mailer tool met behulp van Bird APIs. In dit bericht pak ik de draad op waar hij was gestopt. Zijn tool maakt tijdige verzending van taken mogelijk, maar wat als we onze eigen dashboards en gebeurtenislogboeken willen maken?

Misschien wil ik een specifiek dashboard maken voor een zakelijke groep of een klantgericht dashboard, maar niet volledige toegang geven tot de Bird UI. Dit script raakt slechts het oppervlak van wat mogelijk is met behulp van Python, Plotly Dash en onze APIs. Bij het bouwen van dashboards die hoge volumina API-gegevens verwerken, moet je je ervan bewust zijn dat infrastructuurcomponenten zoals DNS knelpunten kunnen worden - we hebben AWS DNS schaaluitdagingen ervaren die invloed hadden op onze dataverwerkingsmogelijkheden. Voor liefhebbers van visuele workflows kun je ook Flow Builder integreren met Google Cloud Functions en Vision API om AI-gestuurde automatisering toe te voegen aan je dataverwerkingspijplijnen.

Toen ik mijn zoektocht online begon, wilde ik de weg van de minste weerstand vinden. Ik had alle dashboards en UI zelf kunnen maken in HTML en python, maar na wat Googelen kwam ik Plotly's Dash tegen, dat gemakkelijk integreert met python. Ik koos voor Dash om 2 redenen: 1) het is open source, en 2) na het lezen van de documentatie leek het gemakkelijk aanpasbaar voor wat ik probeerde te doen. Dash is een open-sourcebibliotheek die ideaal is voor het bouwen en implementeren van data-apps met aangepaste gebruikersinterfaces. Dit maakte het creëren van een UI uiterst eenvoudig. De vraag was toen hoe complex ik deze app wilde maken. Hoe meer tijd ik besteedde, hoe meer functies ik wilde toevoegen.

Voor het initiële project wilde ik ervoor zorgen dat ik een dashboard had met aanpasbare statistieken en een selecteerbaar tijdsframe. Aanvankelijk begon ik met een dashboard waar je slechts één statistiek uit de dropdown kon kiezen. Vervolgens, na feedback van collega's, verfijnde ik het dashboard een beetje om multi-select en as-titels toe te voegen. Ik besloot ook een extra tabblad toe te voegen voor een gebeurtenislogboek. Ik kwam op het punt dat ik tevreden was met wat ik had als een goed startpunt voor iedereen die zijn eigen dashboards wilde opzetten. Voor ontwikkelaars die real-time webhook gegevens in hun dashboards willen voeren, bekijk onze gids over het bouwen van webhookconsumenten met Azure Functions. Uiteraard heb ik het project in Github gezet zodat je het kunt klonen of forken.

Aan de slag

Om toegang te krijgen tot deze app, moet je ervoor zorgen dat je python 3.10 of hoger draait en de volgende bibliotheken installeert:

  • requests

  • dash

  • pandas

Voer vervolgens je API-sleutel in App.py in en voer de app uit. Het zal draaien op http://localhost:8050. Voor meer informatie over het implementeren hiervan op een openbaar server (zoals AWS), zie de volgende bronnen:

De Dashboard Pagina Creëren

Eerst initialiseer je het data frame en dashboard. Zonder het dashboard te initialiseren, zal er geen dashboard in de UI verschijnen.

df = pd.DataFrame({
    "Count": [0, 0],
    "Time": [0, 0]
})
fig = px.line(df, x="Time", y="Count")

Bouw vervolgens het eerste tabblad uit. Dit is een combinatie van een app-callback (om te controleren welk tabblad wordt gebruikt); samen met een voorwaardelijke functie om te controleren welk tabblad momenteel is geselecteerd. De onderstaande code bouwt alleen het lege dashboard en UI-elementen op (we komen later op het evenemententabblad terug). De dcc-elementen zijn de Dash Core Components en de HTML Components maken het eenvoudig mogelijk om HTML in de UI te gebruiken.

html.H2("Analytics Dashboard"),
# Multi-select dropdown
dcc.Dropdown(
    [
        "Count Accepted",
        "Count Admin Bounce",
        "Count Block Bounce",
        "Count Bounce",
        "Count Clicked",
        "Count Delayed",
        "Count Delayed First",
        "Count Delivered",
        "Count Delivered First",
        "Count Delivered Subsequent",
        "Count Generation Failed",
        "Count Generation Rejection",
        "Count Hard Bounce",
        "Count Inband Bounce",
        "Count Initial Rendered",
        "Count Injected",
        "Count Out of Band Bounce",
        "Count Policy Rejection",
        "Count Rejected",
        "Count Rendered",
        "Count Sent",
        "Count Soft Bounce",
        "Count Spam Complaint",
        "Count Targeted",
        "Count Undetermined Bounce",
        "Count Unique Clicked",
        "Count Unique Confirmed Opened",
        "Count Unique Initial Rendered",
        "Count Unique Rendered",
        "Count Unsubscribe",
        "Total Delivery Time First",
        "Total Delivery Time Subsequent",
        "Total Message Volume",
    ],
    id="y-axis",
    multi=True,
    searchable=True,
    placeholder="Select metrics(s)",
),
# Date selector (max date allowed is set to today's date)
dcc.DatePickerRange(
    id="date-picker-range",
    start_date=date(2022, 1, 1),
    end_date=date(2022, 2, 1),
    max_date_allowed=date(
        datetime.today().year,
        datetime.today().month,
        datetime.today().day,
    ),
),
# Graph object
dcc.Graph(id="Emails", figure=fig)

Let op hoe eenvoudig het is om met Dash een dashboard-UI te maken met een multi-select, doorzoekbare dropdown. Om multi-select of zoeken uit te schakelen, kunnen de parameters voor het maken van een dropdown eenvoudig worden aangepast. Ik vond dat het meest complexe deel van dit project was om het daadwerkelijke data frame op te bouwen vanuit inputs, evenals het correct laten werken van de HTML + CSS in de UI.

De Time Series Metrics API maakt het mogelijk om 33 individuele statistieken op te halen op basis van een datum/tijd bereik. Je kunt verder filteren op Domeinen, Campagnes, IP Pools, Verzending Domeinen, Subaccounts en de Precisie van tijdreeksgegevens specificeren. Deze extra filters samen met leverbaarheidsanalyses kunnen een toekomstige verbetering van dit project zijn (foutafhandeling zou moeten worden geïmplementeerd voor klanten die geen toegang hebben tot leverbaarheidsanalyses).

Door gebruik te maken van en aan te roepen de Metrics API, bouw ik een dashboard op met de door de gebruiker geselecteerde parameters en gespecificeerde tijdsperiode. Het geïnitialiseerde dashboard wordt vervolgens bijgewerkt.

# Build the API call utilizing the parameters provided
params = {
    "from": start_date + "T00:00",
    "to": end_date + "T00:00",
    "delimiter": ",",
    "precision": "day",
    "metrics": joined_values
}
api_url = BASE_URL + "/metrics/deliverability/time-series"
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'])
value_array = joined_values.split(",")
# Build out a new dashboard utilizing the new metrics and dates from the updated API call
fig = px.line(
    new_df,
    x=new_df['ts'],
    y=value_array,
    labels={"value": "Count", "variable": "Metric", "ts": "Date"}
)
fig.update_xaxes(title_text="Time")
fig.update_yaxes(title_text="Count")
return fig

Het volgende is een voorbeeld van meerdere geselecteerde statistieken en een uitgebreide tijdsperiode.


Sparkpost analytics dashboard

Opmerking: er zijn veel items die automatisch in de dash-grafiek zijn ingebouwd (hover, zoom, autoscale).

Eerst initialiseer je het data frame en dashboard. Zonder het dashboard te initialiseren, zal er geen dashboard in de UI verschijnen.

df = pd.DataFrame({
    "Count": [0, 0],
    "Time": [0, 0]
})
fig = px.line(df, x="Time", y="Count")

Bouw vervolgens het eerste tabblad uit. Dit is een combinatie van een app-callback (om te controleren welk tabblad wordt gebruikt); samen met een voorwaardelijke functie om te controleren welk tabblad momenteel is geselecteerd. De onderstaande code bouwt alleen het lege dashboard en UI-elementen op (we komen later op het evenemententabblad terug). De dcc-elementen zijn de Dash Core Components en de HTML Components maken het eenvoudig mogelijk om HTML in de UI te gebruiken.

html.H2("Analytics Dashboard"),
# Multi-select dropdown
dcc.Dropdown(
    [
        "Count Accepted",
        "Count Admin Bounce",
        "Count Block Bounce",
        "Count Bounce",
        "Count Clicked",
        "Count Delayed",
        "Count Delayed First",
        "Count Delivered",
        "Count Delivered First",
        "Count Delivered Subsequent",
        "Count Generation Failed",
        "Count Generation Rejection",
        "Count Hard Bounce",
        "Count Inband Bounce",
        "Count Initial Rendered",
        "Count Injected",
        "Count Out of Band Bounce",
        "Count Policy Rejection",
        "Count Rejected",
        "Count Rendered",
        "Count Sent",
        "Count Soft Bounce",
        "Count Spam Complaint",
        "Count Targeted",
        "Count Undetermined Bounce",
        "Count Unique Clicked",
        "Count Unique Confirmed Opened",
        "Count Unique Initial Rendered",
        "Count Unique Rendered",
        "Count Unsubscribe",
        "Total Delivery Time First",
        "Total Delivery Time Subsequent",
        "Total Message Volume",
    ],
    id="y-axis",
    multi=True,
    searchable=True,
    placeholder="Select metrics(s)",
),
# Date selector (max date allowed is set to today's date)
dcc.DatePickerRange(
    id="date-picker-range",
    start_date=date(2022, 1, 1),
    end_date=date(2022, 2, 1),
    max_date_allowed=date(
        datetime.today().year,
        datetime.today().month,
        datetime.today().day,
    ),
),
# Graph object
dcc.Graph(id="Emails", figure=fig)

Let op hoe eenvoudig het is om met Dash een dashboard-UI te maken met een multi-select, doorzoekbare dropdown. Om multi-select of zoeken uit te schakelen, kunnen de parameters voor het maken van een dropdown eenvoudig worden aangepast. Ik vond dat het meest complexe deel van dit project was om het daadwerkelijke data frame op te bouwen vanuit inputs, evenals het correct laten werken van de HTML + CSS in de UI.

De Time Series Metrics API maakt het mogelijk om 33 individuele statistieken op te halen op basis van een datum/tijd bereik. Je kunt verder filteren op Domeinen, Campagnes, IP Pools, Verzending Domeinen, Subaccounts en de Precisie van tijdreeksgegevens specificeren. Deze extra filters samen met leverbaarheidsanalyses kunnen een toekomstige verbetering van dit project zijn (foutafhandeling zou moeten worden geïmplementeerd voor klanten die geen toegang hebben tot leverbaarheidsanalyses).

Door gebruik te maken van en aan te roepen de Metrics API, bouw ik een dashboard op met de door de gebruiker geselecteerde parameters en gespecificeerde tijdsperiode. Het geïnitialiseerde dashboard wordt vervolgens bijgewerkt.

# Build the API call utilizing the parameters provided
params = {
    "from": start_date + "T00:00",
    "to": end_date + "T00:00",
    "delimiter": ",",
    "precision": "day",
    "metrics": joined_values
}
api_url = BASE_URL + "/metrics/deliverability/time-series"
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'])
value_array = joined_values.split(",")
# Build out a new dashboard utilizing the new metrics and dates from the updated API call
fig = px.line(
    new_df,
    x=new_df['ts'],
    y=value_array,
    labels={"value": "Count", "variable": "Metric", "ts": "Date"}
)
fig.update_xaxes(title_text="Time")
fig.update_yaxes(title_text="Count")
return fig

Het volgende is een voorbeeld van meerdere geselecteerde statistieken en een uitgebreide tijdsperiode.


Sparkpost analytics dashboard

Opmerking: er zijn veel items die automatisch in de dash-grafiek zijn ingebouwd (hover, zoom, autoscale).

Eerst initialiseer je het data frame en dashboard. Zonder het dashboard te initialiseren, zal er geen dashboard in de UI verschijnen.

df = pd.DataFrame({
    "Count": [0, 0],
    "Time": [0, 0]
})
fig = px.line(df, x="Time", y="Count")

Bouw vervolgens het eerste tabblad uit. Dit is een combinatie van een app-callback (om te controleren welk tabblad wordt gebruikt); samen met een voorwaardelijke functie om te controleren welk tabblad momenteel is geselecteerd. De onderstaande code bouwt alleen het lege dashboard en UI-elementen op (we komen later op het evenemententabblad terug). De dcc-elementen zijn de Dash Core Components en de HTML Components maken het eenvoudig mogelijk om HTML in de UI te gebruiken.

html.H2("Analytics Dashboard"),
# Multi-select dropdown
dcc.Dropdown(
    [
        "Count Accepted",
        "Count Admin Bounce",
        "Count Block Bounce",
        "Count Bounce",
        "Count Clicked",
        "Count Delayed",
        "Count Delayed First",
        "Count Delivered",
        "Count Delivered First",
        "Count Delivered Subsequent",
        "Count Generation Failed",
        "Count Generation Rejection",
        "Count Hard Bounce",
        "Count Inband Bounce",
        "Count Initial Rendered",
        "Count Injected",
        "Count Out of Band Bounce",
        "Count Policy Rejection",
        "Count Rejected",
        "Count Rendered",
        "Count Sent",
        "Count Soft Bounce",
        "Count Spam Complaint",
        "Count Targeted",
        "Count Undetermined Bounce",
        "Count Unique Clicked",
        "Count Unique Confirmed Opened",
        "Count Unique Initial Rendered",
        "Count Unique Rendered",
        "Count Unsubscribe",
        "Total Delivery Time First",
        "Total Delivery Time Subsequent",
        "Total Message Volume",
    ],
    id="y-axis",
    multi=True,
    searchable=True,
    placeholder="Select metrics(s)",
),
# Date selector (max date allowed is set to today's date)
dcc.DatePickerRange(
    id="date-picker-range",
    start_date=date(2022, 1, 1),
    end_date=date(2022, 2, 1),
    max_date_allowed=date(
        datetime.today().year,
        datetime.today().month,
        datetime.today().day,
    ),
),
# Graph object
dcc.Graph(id="Emails", figure=fig)

Let op hoe eenvoudig het is om met Dash een dashboard-UI te maken met een multi-select, doorzoekbare dropdown. Om multi-select of zoeken uit te schakelen, kunnen de parameters voor het maken van een dropdown eenvoudig worden aangepast. Ik vond dat het meest complexe deel van dit project was om het daadwerkelijke data frame op te bouwen vanuit inputs, evenals het correct laten werken van de HTML + CSS in de UI.

De Time Series Metrics API maakt het mogelijk om 33 individuele statistieken op te halen op basis van een datum/tijd bereik. Je kunt verder filteren op Domeinen, Campagnes, IP Pools, Verzending Domeinen, Subaccounts en de Precisie van tijdreeksgegevens specificeren. Deze extra filters samen met leverbaarheidsanalyses kunnen een toekomstige verbetering van dit project zijn (foutafhandeling zou moeten worden geïmplementeerd voor klanten die geen toegang hebben tot leverbaarheidsanalyses).

Door gebruik te maken van en aan te roepen de Metrics API, bouw ik een dashboard op met de door de gebruiker geselecteerde parameters en gespecificeerde tijdsperiode. Het geïnitialiseerde dashboard wordt vervolgens bijgewerkt.

# Build the API call utilizing the parameters provided
params = {
    "from": start_date + "T00:00",
    "to": end_date + "T00:00",
    "delimiter": ",",
    "precision": "day",
    "metrics": joined_values
}
api_url = BASE_URL + "/metrics/deliverability/time-series"
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'])
value_array = joined_values.split(",")
# Build out a new dashboard utilizing the new metrics and dates from the updated API call
fig = px.line(
    new_df,
    x=new_df['ts'],
    y=value_array,
    labels={"value": "Count", "variable": "Metric", "ts": "Date"}
)
fig.update_xaxes(title_text="Time")
fig.update_yaxes(title_text="Count")
return fig

Het volgende is een voorbeeld van meerdere geselecteerde statistieken en een uitgebreide tijdsperiode.


Sparkpost analytics dashboard

Opmerking: er zijn veel items die automatisch in de dash-grafiek zijn ingebouwd (hover, zoom, autoscale).

Het maken van de Event Details-pagina

De evenementen detailpagina was een beetje moeilijker omdat ik niet wist hoe ik alle meetwaarden van de evenementen op een gemakkelijk leesbare manier kon presenteren. Ik overwoog om filterparameters aan deze pagina toe te voegen, maar ik besloot dat dit veel tijd aan dit project zou toevoegen omdat de tabel dan dynamisch zou moeten zijn (samen met het toevoegen van de parameters, callbacks, enz.). Ik koos ervoor om alle evenementen te tonen en de tijdstempel eerst te plaatsen (aangezien zonder de tijdstempel eerst te plaatsen, de grafiek moeilijk leesbaar was). Aanvankelijk vond ik dat alleen met de ruwe HTML de tabel ongelooflijk moeilijk voor de ogen was. Er waren geen randen en geen kleurverschillen voor koptekst versus rijen. Om de tabel gemakkelijker leesbaar te maken, kon ik CSS gebruiken binnen Dash.

Het idee voor de evenementendetails is bijna hetzelfde als het dashboard, behalve dat ik deze keer de Events API aanroep en alle evenementen binnenhaal. Let op dat de evenementendetails alleen de 10 meest recente evenementen tonen (met behulp van de max_rows parameter en API filtering). Dit kan worden verhoogd, maar ik koos ervoor om de 10 meest recente evenementen te tonen omdat hoe meer evenementen worden getoond, hoe langer het API-verzoek duurt. Een significante verbetering die kan worden gemaakt, is de mogelijkheid om te pagineren en een Volgende Pagina / Vorige Pagina in de UI op te nemen.

Om het evenemententabblad (pagina) uit te bouwen, roep ik eerst de Events API aan en parse ik de JSON-reactie in een data frame. Vervolgens sorteer en herorder ik het data frame om de tijdstempel als eerste kolom te plaatsen. Ten slotte bouw ik de HTML-tabel door het data frame te itereren.

# 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 = f"{BASE_URL}/events/message"
response_API = requests.get(api_url, headers={"Authorization": API_KEY}, params=params)
response_info = response_API.json()
new_df = pd.json_normalize(response_info, record_path=["results"])
max_rows = 10  # Max number of results to show in the events table
# Sort columns and 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))
        ])
    ])
])

Wat er zo uitziet in de UI.

Sparkpost event details

Volgende Stappen

Voor iemand die zijn eigen dashboard of eventlog wil maken, is dit een goed begin. Met de aanpasbaarheid hier is de lucht de limiet.

Zoals hierboven besproken, kunnen enkele toekomstige verbeteringen zijn:

  • Het toevoegen van verzendbaarheidsanalyses aan het dashboard

  • Het toevoegen van meer filters aan het dashboard

  • Mogelijke cache-opties zodat de API niet elke keer wordt aangeroepen om de pagina's weer te geven

  • UI-verbeteringen

  • Het toevoegen van filteren en paginering aan de event detailpagina

Ik zou geïnteresseerd zijn in het horen van feedback of suggesties om dit project uit te breiden.

~ Zach Samuels, Bird Senior Solutions Engineer

Laten we je in contact brengen met een Bird-expert.
Bekijk de volledige kracht van de Bird in 30 minuten.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

Nieuwsbrief

Blijf op de hoogte met Bird via wekelijkse updates in je inbox.

Laten we je in contact brengen met een Bird-expert.
Bekijk de volledige kracht van de Bird in 30 minuten.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

Nieuwsbrief

Blijf op de hoogte met Bird via wekelijkse updates in je inbox.

Laten we je in contact brengen met een Bird-expert.
Bekijk de volledige kracht van de Bird in 30 minuten.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

R

Bereik

G

Grow

M

Manage

A

Automate

Nieuwsbrief

Blijf op de hoogte met Bird via wekelijkse updates in je inbox.