Uno strumento di dashboarding con le API di Bird

Email

·

24 mar 2022

Uno strumento di dashboarding con le API di Bird

Punti Chiave

    • Le API di Bird possono essere combinate con Python e Plotly Dash per costruire dashboard potenti e interattive senza bisogno dell'interfaccia utente completa di Bird.

    • Il progetto dimostra come visualizzare metriche ed eventi utilizzando l'API delle metriche di Bird e l'API degli eventi all'interno di un'app web personalizzata.

    • Plotly Dash fornisce un framework rapido e open-source per costruire elementi UI come menu a discesa, grafici e tabelle.

    • Gli sviluppatori possono estendere lo strumento con analisi di deliverability, filtri e paginazione per dashboard più ricche.

    • I futuri miglioramenti includono caching, interfaccia utente migliorata e integrazione con altri prodotti Bird o API di terze parti.

    • Il codice sorgente (disponibile su GitHub) offre un forte punto di partenza per chiunque voglia costruire dashboard alimentate da Bird o portali per i clienti.

Punti salienti del Q&A

  • Qual è l'obiettivo di questo progetto di dashboard?

    Dimostra come gli sviluppatori possono utilizzare le API di Bird con Python e Plotly Dash per creare dashboard basate sui dati che visualizzano le metriche delle campagne e gli eventi recenti.

  • Perché utilizzare Plotly Dash per le API degli uccelli?

    Dash è open source, facile da personalizzare e ideale per creare interfacce utente interattive senza richiedere competenze di front-end.

  • Cosa mostra il pannello di controllo?

    Visualizza le metriche delle serie temporali dall'API di Metrics di Bird e i dati sugli eventi recenti dall'API degli eventi, con opzioni per filtrare e selezionare metriche su intervalli di tempo personalizzati.

  • Come può essere ulteriormente ampliato lo strumento?

    Aggiungendo analisi di deliverabilità, filtri avanzati, caching dei dati e paginazione per grandi set di dati per migliorare le prestazioni e l'usabilità.

  • Quali competenze o strumenti sono necessari per gestirlo?

    Conoscenze di base di Python e installazione di requests, dash e pandas. È necessaria una chiave API di Bird per estrarre i dati.

  • Come si inserisce questo progetto nell'ecosistema di Bird?

    Illustra come le API aperte di Bird possono essere sfruttate per creare dashboard personalizzate e strumenti di reporting per team o clienti senza accesso all'intera piattaforma.

Questo script tocca solo la superficie di ciò che è possibile utilizzare Python, Plotly Dash e le nostre API.

API di Bird Metrics + Dashboarding con Python

Quasi un anno fa, Tom Mairs, direttore del successo clienti di Bird, ha scritto uno strumento di mailer utilizzando le API di Bird. In questo post, riprendo da dove aveva lasciato. Il suo strumento consente la trasmissione temporizzata di lavori, ma cosa succede se vogliamo creare i nostri dashboard e registri eventi?

Forse voglio creare un dashboard specifico per un gruppo aziendale o un dashboard rivolto ai clienti, ma non fornire agli utenti accesso completo all'interfaccia utente di Bird. Questo script tocca solo la superficie di ciò che è possibile utilizzare Python, Plotly Dash, e le nostre API. Quando si costruiscono dashboard che elaborano dati API ad alto volume, è importante essere consapevoli che componenti infrastrutturali come il DNS possono diventare colli di bottiglia - abbiamo sperimentato sfide di scalabilità DNS su AWS che hanno influenzato le nostre capacità di elaborazione dei dati. Per gli appassionati di flussi di lavoro visivi, puoi anche esplorare l'integrazione di Flow Builder con Google Cloud Functions e Vision API per aggiungere automazione potenziata dall'IA alle tue pipeline di elaborazione dei dati.

Quando ho iniziato la mia ricerca online, volevo trovare il percorso di minor resistenza. Avrei potuto creare tutti gli dashboard e l'UI da solo in HTML e python, tuttavia, dopo alcune ricerche su Google, ho trovato Dash di Plotly, che si integra facilmente con python. Ho scelto Dash per 2 motivi: 1) è open source, e 2) dopo aver letto la documentazione sembrava facilmente personalizzabile per ciò che stavo cercando di fare. Dash è una libreria open-source che è ideale per costruire e distribuire app di dati con interfacce utente personalizzate. Questo ha reso la creazione di un'interfaccia utente estremamente semplice. La domanda è quindi diventata, quanto complesso volevo rendere quest'app? Più tempo spendevo, più funzionalità volevo aggiungere.

Per il progetto iniziale, volevo assicurarmi di avere un dashboard con metriche personalizzabili e un intervallo di tempo selezionabile. Inizialmente, ho iniziato con un dashboard in cui potevi scegliere solo una metrica dal menu a discesa. Poi, mentre ricevevo feedback dai colleghi, ho affinato un po' il dashboard per aggiungere la selezione multipla e i titoli degli assi. Ho anche deciso di aggiungere una scheda aggiuntiva per un registro eventi. Sono arrivato al punto in cui ero soddisfatto di avere un buon punto di partenza per chiunque desiderasse costruire i propri dashboard. Per gli sviluppatori che vogliono alimentare dati webhook in tempo reale nei loro dashboard, dai un'occhiata alla nostra guida su come costruire consumatori webhook con Azure Functions. Naturalmente, ho messo il progetto su Github per te da clonare o ramificare.

Iniziare

Per accedere a questa app, devi assicurarti di eseguire python 3.10 o superiore e installare le seguenti librerie:

Libri Python

Scopo

requests

Comunicazione API con i servizi di Bird

dash

Rendering UI e dashboard

pandas

Elaborazione dei dati e generazione di tabelle

Quindi, inserisci la tua chiave API in App.py e avvia l'app. Essa verrà eseguita su http://localhost:8050. Per ulteriori informazioni su come distribuirlo su un server accessibile al pubblico (come AWS), consulta le seguenti risorse:

Creando la pagina del cruscotto

Prima, inizializza il data frame e il dashboard. Senza inizializzare il dashboard, nessun dashboard apparirà nell'interfaccia utente.

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

Poi, costruisci il primo tab. Questa è una combinazione di un callback dell'app (per controllare quale tab viene utilizzato); insieme a una funzione condizionale per controllare quale tab è attualmente selezionato. Il codice sottostante costruisce solo il dashboard vuoto e gli elementi dell'interfaccia utente (ci arriveremo al tab degli eventi più tardi). Gli elementi dcc sono i Dash Core Components e gli HTML Components consentono facilmente di utilizzare HTML nell'interfaccia utente.

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)

Nota con dash quanto sia semplice creare un'interfaccia utente del dashboard con un dropdown multi-selezione e ricercabile. Per disabilitare la multi-selezione o la ricerca, i parametri per creare un dropdown possono essere facilmente modificati. Ho scoperto che la parte più complessa di questo progetto era costruire il data frame effettivo dagli input, così come far funzionare correttamente HTML + CSS nell'interfaccia utente.

L'API di Metriche delle Serie Temporali consente di estrarre 33 metriche individuali basate su un intervallo di date/orari. Puoi filtrare più a fondo per Domini, Campagne, Pool IP, Domini di Invio, Sottoaccount e specificare la Precisione dei dati delle serie temporali. Questi filtri aggiuntivi insieme all'analisi della deliverabilità potrebbero essere un miglioramento futuro di questo progetto (la cattura degli errori dovrebbe essere implementata per i clienti che non hanno accesso all'analisi della deliverabilità).

Utilizzando e richiamando l'API delle Metriche, costruisco un dashboard con i parametri selezionati dall'utente e il periodo di tempo specificato. Il dashboard inizializzato viene quindi aggiornato.

Visualizzazione del Dashboard (API Metriche delle Serie Temporali)

# 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

Il seguente è un esempio di più metriche selezionate e un intervallo di tempo espanso.


Sparkpost analytics dashboard

Nota: ci sono molti elementi integrati nel grafico dash automaticamente (hover, zoom, autoscale).

Prima, inizializza il data frame e il dashboard. Senza inizializzare il dashboard, nessun dashboard apparirà nell'interfaccia utente.

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

Poi, costruisci il primo tab. Questa è una combinazione di un callback dell'app (per controllare quale tab viene utilizzato); insieme a una funzione condizionale per controllare quale tab è attualmente selezionato. Il codice sottostante costruisce solo il dashboard vuoto e gli elementi dell'interfaccia utente (ci arriveremo al tab degli eventi più tardi). Gli elementi dcc sono i Dash Core Components e gli HTML Components consentono facilmente di utilizzare HTML nell'interfaccia utente.

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)

Nota con dash quanto sia semplice creare un'interfaccia utente del dashboard con un dropdown multi-selezione e ricercabile. Per disabilitare la multi-selezione o la ricerca, i parametri per creare un dropdown possono essere facilmente modificati. Ho scoperto che la parte più complessa di questo progetto era costruire il data frame effettivo dagli input, così come far funzionare correttamente HTML + CSS nell'interfaccia utente.

L'API di Metriche delle Serie Temporali consente di estrarre 33 metriche individuali basate su un intervallo di date/orari. Puoi filtrare più a fondo per Domini, Campagne, Pool IP, Domini di Invio, Sottoaccount e specificare la Precisione dei dati delle serie temporali. Questi filtri aggiuntivi insieme all'analisi della deliverabilità potrebbero essere un miglioramento futuro di questo progetto (la cattura degli errori dovrebbe essere implementata per i clienti che non hanno accesso all'analisi della deliverabilità).

Utilizzando e richiamando l'API delle Metriche, costruisco un dashboard con i parametri selezionati dall'utente e il periodo di tempo specificato. Il dashboard inizializzato viene quindi aggiornato.

Visualizzazione del Dashboard (API Metriche delle Serie Temporali)

# 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

Il seguente è un esempio di più metriche selezionate e un intervallo di tempo espanso.


Sparkpost analytics dashboard

Nota: ci sono molti elementi integrati nel grafico dash automaticamente (hover, zoom, autoscale).

Prima, inizializza il data frame e il dashboard. Senza inizializzare il dashboard, nessun dashboard apparirà nell'interfaccia utente.

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

Poi, costruisci il primo tab. Questa è una combinazione di un callback dell'app (per controllare quale tab viene utilizzato); insieme a una funzione condizionale per controllare quale tab è attualmente selezionato. Il codice sottostante costruisce solo il dashboard vuoto e gli elementi dell'interfaccia utente (ci arriveremo al tab degli eventi più tardi). Gli elementi dcc sono i Dash Core Components e gli HTML Components consentono facilmente di utilizzare HTML nell'interfaccia utente.

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)

Nota con dash quanto sia semplice creare un'interfaccia utente del dashboard con un dropdown multi-selezione e ricercabile. Per disabilitare la multi-selezione o la ricerca, i parametri per creare un dropdown possono essere facilmente modificati. Ho scoperto che la parte più complessa di questo progetto era costruire il data frame effettivo dagli input, così come far funzionare correttamente HTML + CSS nell'interfaccia utente.

L'API di Metriche delle Serie Temporali consente di estrarre 33 metriche individuali basate su un intervallo di date/orari. Puoi filtrare più a fondo per Domini, Campagne, Pool IP, Domini di Invio, Sottoaccount e specificare la Precisione dei dati delle serie temporali. Questi filtri aggiuntivi insieme all'analisi della deliverabilità potrebbero essere un miglioramento futuro di questo progetto (la cattura degli errori dovrebbe essere implementata per i clienti che non hanno accesso all'analisi della deliverabilità).

Utilizzando e richiamando l'API delle Metriche, costruisco un dashboard con i parametri selezionati dall'utente e il periodo di tempo specificato. Il dashboard inizializzato viene quindi aggiornato.

Visualizzazione del Dashboard (API Metriche delle Serie Temporali)

# 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

Il seguente è un esempio di più metriche selezionate e un intervallo di tempo espanso.


Sparkpost analytics dashboard

Nota: ci sono molti elementi integrati nel grafico dash automaticamente (hover, zoom, autoscale).

Creazione della pagina dei dettagli dell'evento

La pagina dei dettagli dell'evento è stata un po' più difficile perché non sapevo il modo migliore per presentare tutte le metriche degli eventi in modo facile da leggere. Ho considerato di aggiungere parametri di filtraggio a questa pagina, tuttavia, ho deciso che ciò avrebbe aggiunto un notevole tempo a questo progetto poiché la tabella avrebbe dovuto essere dinamica (insieme all'aggiunta dei parametri, callback, ecc.). Ho deciso di mostrare tutti gli eventi e di posizionare il timestamp per primo (poiché senza mettere il timestamp per primo, il grafico non era facile da leggere). Inizialmente, ho scoperto che con solo l'HTML grezzo, la tabella era incredibilmente difficile da guardare. Non c'erano bordi e nessuna differenza di colore per l'intestazione rispetto alle righe. Per rendere la tabella più facile da leggere, sono stato in grado di utilizzare CSS all'interno di Dash.

Visualizzazione dettagli evento (API eventi)

L'idea per i dettagli dell'evento è quasi la stessa del cruscotto, eccetto per il fatto che questa volta chiamo l' API eventi e introduco tutti gli eventi. Nota che i dettagli dell'evento mostrano solo gli 10 eventi più recenti (utilizzando il parametro max_rows e il filtraggio API). Questo può essere aumentato, comunque, ho deciso di mostrare i 10 eventi più recenti perché più eventi vengono mostrati, più a lungo impiega la chiamata API. Un miglioramento significativo che potrebbe essere apportato sarebbe la possibilità di paginare e includere una Pagina successiva / Pagina precedente nell'interfaccia utente.

Per costruire la scheda degli eventi (pagina), prima chiamo l'API eventi e analizzo la risposta JSON in un DataFrame. Poi ordino e riordino il DataFrame per mettere il timestamp come prima colonna. Infine, costruisco la tabella HTML iterando attraverso il DataFrame.

# 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))
        ])
    ])
])

Che appare così nell'interfaccia utente.

Sparkpost event details

La pagina dei dettagli dell'evento è stata un po' più difficile perché non sapevo il modo migliore per presentare tutte le metriche degli eventi in modo facile da leggere. Ho considerato di aggiungere parametri di filtraggio a questa pagina, tuttavia, ho deciso che ciò avrebbe aggiunto un notevole tempo a questo progetto poiché la tabella avrebbe dovuto essere dinamica (insieme all'aggiunta dei parametri, callback, ecc.). Ho deciso di mostrare tutti gli eventi e di posizionare il timestamp per primo (poiché senza mettere il timestamp per primo, il grafico non era facile da leggere). Inizialmente, ho scoperto che con solo l'HTML grezzo, la tabella era incredibilmente difficile da guardare. Non c'erano bordi e nessuna differenza di colore per l'intestazione rispetto alle righe. Per rendere la tabella più facile da leggere, sono stato in grado di utilizzare CSS all'interno di Dash.

Visualizzazione dettagli evento (API eventi)

L'idea per i dettagli dell'evento è quasi la stessa del cruscotto, eccetto per il fatto che questa volta chiamo l' API eventi e introduco tutti gli eventi. Nota che i dettagli dell'evento mostrano solo gli 10 eventi più recenti (utilizzando il parametro max_rows e il filtraggio API). Questo può essere aumentato, comunque, ho deciso di mostrare i 10 eventi più recenti perché più eventi vengono mostrati, più a lungo impiega la chiamata API. Un miglioramento significativo che potrebbe essere apportato sarebbe la possibilità di paginare e includere una Pagina successiva / Pagina precedente nell'interfaccia utente.

Per costruire la scheda degli eventi (pagina), prima chiamo l'API eventi e analizzo la risposta JSON in un DataFrame. Poi ordino e riordino il DataFrame per mettere il timestamp come prima colonna. Infine, costruisco la tabella HTML iterando attraverso il DataFrame.

# 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))
        ])
    ])
])

Che appare così nell'interfaccia utente.

Sparkpost event details

La pagina dei dettagli dell'evento è stata un po' più difficile perché non sapevo il modo migliore per presentare tutte le metriche degli eventi in modo facile da leggere. Ho considerato di aggiungere parametri di filtraggio a questa pagina, tuttavia, ho deciso che ciò avrebbe aggiunto un notevole tempo a questo progetto poiché la tabella avrebbe dovuto essere dinamica (insieme all'aggiunta dei parametri, callback, ecc.). Ho deciso di mostrare tutti gli eventi e di posizionare il timestamp per primo (poiché senza mettere il timestamp per primo, il grafico non era facile da leggere). Inizialmente, ho scoperto che con solo l'HTML grezzo, la tabella era incredibilmente difficile da guardare. Non c'erano bordi e nessuna differenza di colore per l'intestazione rispetto alle righe. Per rendere la tabella più facile da leggere, sono stato in grado di utilizzare CSS all'interno di Dash.

Visualizzazione dettagli evento (API eventi)

L'idea per i dettagli dell'evento è quasi la stessa del cruscotto, eccetto per il fatto che questa volta chiamo l' API eventi e introduco tutti gli eventi. Nota che i dettagli dell'evento mostrano solo gli 10 eventi più recenti (utilizzando il parametro max_rows e il filtraggio API). Questo può essere aumentato, comunque, ho deciso di mostrare i 10 eventi più recenti perché più eventi vengono mostrati, più a lungo impiega la chiamata API. Un miglioramento significativo che potrebbe essere apportato sarebbe la possibilità di paginare e includere una Pagina successiva / Pagina precedente nell'interfaccia utente.

Per costruire la scheda degli eventi (pagina), prima chiamo l'API eventi e analizzo la risposta JSON in un DataFrame. Poi ordino e riordino il DataFrame per mettere il timestamp come prima colonna. Infine, costruisco la tabella HTML iterando attraverso il DataFrame.

# 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))
        ])
    ])
])

Che appare così nell'interfaccia utente.

Sparkpost event details

Prossimi passi

Per qualcuno che cerca di creare il proprio dashboard o registro eventi, questo è un buon inizio. Con la personalizzazione qui, il cielo è il limite.

Come discusso sopra, alcuni miglioramenti futuri che potrebbero essere apportati sono:

  • Aggiungere analisi della deliverability al dashboard

  • Aggiungere più filtri al dashboard

  • Possibili opzioni di caching in modo che l'API non venga chiamata ogni volta per visualizzare le pagine

  • Miglioramenti dell'interfaccia utente

  • Aggiungere filtri e paginazione alla pagina dei dettagli degli eventi

Sarei interessato a ascoltare eventuali feedback o suggerimenti per espandere questo progetto.

~ Zach Samuels, Bird Senior Solutions Engineer

Altre notizie

Leggi di più da questa categoria

A person is standing at a desk while typing on a laptop.

La piattaforma completa nativa dell'IA che si espande con la tua azienda.

© 2026 Uccello

A person is standing at a desk while typing on a laptop.

La piattaforma completa nativa dell'IA che si espande con la tua azienda.

© 2026 Uccello