Reach

Grow

Manage

Automate

Reach

Grow

Manage

Automate

Uno strumento di dashboarding con API di uccelli

Zachary Samuels

24 mar 2022

Email

1 min read

Uno strumento di dashboarding con API di uccelli

Zachary Samuels

24 mar 2022

Email

1 min read

Uno strumento di dashboarding con API di uccelli

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

Quasi un anno fa, Tom Mairs, direttore del successo clienti di Bird, scrisse uno strumento di mailing utilizzando le API di Bird. In questo post, riprendo da dove si era fermato. Il suo strumento consente la trasmissione programmata di lavori, ma cosa succede se vogliamo creare i nostri dashboard e registri di eventi?




Forse voglio creare un dashboard specifico per un gruppo aziendale o un dashboard rivolto ai clienti, ma senza fornire agli utenti l'accesso completo all'UI di Bird. Questo script esplora solo la superficie di ciò che è possibile utilizzare con Python, Plotly Dash e le nostre API.




Quando ho iniziato la mia ricerca online, volevo trovare il percorso di minor resistenza. Avrei potuto creare tutti i dashboard e l'UI da solo in HTML e python, tuttavia, dopo alcune ricerche su Google, ho scoperto Plotly’s Dash, 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 quello che stavo cercando di fare. Dash è una libreria open source ideale per costruire e distribuire app di dati con interfacce utente personalizzate. Questo ha reso estremamente semplice creare un'UI. La domanda è diventata, quanto complessa volevo rendere questa app? Più tempo dedicavo, 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 tendina. Poi, mentre ricevevo feedback dai colleghi, ho raffinato 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 quello che avevo come buon punto di partenza per chiunque volesse creare i propri dashboard. Naturalmente, ho messo il progetto su Github per farti clonare o creare un ramo.

Iniziare

Per accedere a questa app, è necessario assicurarsi di eseguire python 3.10 o superiore e installare le seguenti librerie:

  • requests

  • dash

  • pandas




Quindi, inserisci la tua chiave API in App.py ed esegui l'app. Verrà eseguita su http://localhost:8050. Per ulteriori informazioni sul deployment su un server pubblico (come AWS), consulta le seguenti risorse:

Creazione della Dashboard Page

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




df = pd.DataFrame({

"Count": [0,0],

"Time": [0,0]

})

fig = px.line(df,x="Time",y="Count")




Quindi, costruisci la prima scheda. Questa è una combinazione di un callback dell'app (per verificare quale scheda viene utilizzata); insieme a una funzione condizionale per verificare quale scheda è attualmente selezionata. Il codice qui sotto costruisce solo il cruscotto vuoto e gli elementi dell'interfaccia utente (ci arriveremo alla scheda degli eventi più avanti). Gli elementi dcc sono i Dash Core Components e i HTML Components permettono facilmente l'uso di HTML nell'interfaccia utente.




html.H2('Analytics Dashboard'),

#Dropdown multi-selezione

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)"),

#Selettore di data (la data massima consentita è impostata sulla data odierna) 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), ),

#Oggetto Grafico dcc.Graph( id='Emails', figure=fig )




Nota come con Dash sia semplice creare un'interfaccia utente del cruscotto 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 trovato che la parte più complessa di questo progetto è stata costruire il quadro di dati effettivo dagli input, nonché ottenere che HTML + CSS funzionassero correttamente nell'interfaccia utente.




L'API dei Time Series Metrics consente di ottenere 33 metriche individuali basate su un intervallo date/ora. È possibile filtrare ulteriormente per Domini, Campagne, IP Pools, Domini di Invio, Sottoaccount e specificare la Precisione dei dati delle serie temporali. Questi filtri aggiuntivi insieme alle analisi di deliverabilità potrebbero essere un miglioramento futuro di questo progetto (in caso di errori, sarebbe necessario implementare una cattura degli errori per i clienti che non hanno accesso alle analisi di deliverabilità).




Utilizzando e chiamando il Metrics API, costruisco un cruscotto con i parametri selezionati dall'utente e il periodo di tempo specificato. Il cruscotto inizializzato viene quindi aggiornato.




#Costruisci la chiamata API utilizzando i parametri forniti 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(",") #Costruisci un nuovo cruscotto utilizzando le nuove metriche e date dall'aggiornata chiamata API 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




Segue un esempio di più metriche selezionate e un periodo di tempo esteso.







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

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




df = pd.DataFrame({

"Count": [0,0],

"Time": [0,0]

})

fig = px.line(df,x="Time",y="Count")




Quindi, costruisci la prima scheda. Questa è una combinazione di un callback dell'app (per verificare quale scheda viene utilizzata); insieme a una funzione condizionale per verificare quale scheda è attualmente selezionata. Il codice qui sotto costruisce solo il cruscotto vuoto e gli elementi dell'interfaccia utente (ci arriveremo alla scheda degli eventi più avanti). Gli elementi dcc sono i Dash Core Components e i HTML Components permettono facilmente l'uso di HTML nell'interfaccia utente.




html.H2('Analytics Dashboard'),

#Dropdown multi-selezione

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)"),

#Selettore di data (la data massima consentita è impostata sulla data odierna) 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), ),

#Oggetto Grafico dcc.Graph( id='Emails', figure=fig )




Nota come con Dash sia semplice creare un'interfaccia utente del cruscotto 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 trovato che la parte più complessa di questo progetto è stata costruire il quadro di dati effettivo dagli input, nonché ottenere che HTML + CSS funzionassero correttamente nell'interfaccia utente.




L'API dei Time Series Metrics consente di ottenere 33 metriche individuali basate su un intervallo date/ora. È possibile filtrare ulteriormente per Domini, Campagne, IP Pools, Domini di Invio, Sottoaccount e specificare la Precisione dei dati delle serie temporali. Questi filtri aggiuntivi insieme alle analisi di deliverabilità potrebbero essere un miglioramento futuro di questo progetto (in caso di errori, sarebbe necessario implementare una cattura degli errori per i clienti che non hanno accesso alle analisi di deliverabilità).




Utilizzando e chiamando il Metrics API, costruisco un cruscotto con i parametri selezionati dall'utente e il periodo di tempo specificato. Il cruscotto inizializzato viene quindi aggiornato.




#Costruisci la chiamata API utilizzando i parametri forniti 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(",") #Costruisci un nuovo cruscotto utilizzando le nuove metriche e date dall'aggiornata chiamata API 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




Segue un esempio di più metriche selezionate e un periodo di tempo esteso.







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

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




df = pd.DataFrame({

"Count": [0,0],

"Time": [0,0]

})

fig = px.line(df,x="Time",y="Count")




Quindi, costruisci la prima scheda. Questa è una combinazione di un callback dell'app (per verificare quale scheda viene utilizzata); insieme a una funzione condizionale per verificare quale scheda è attualmente selezionata. Il codice qui sotto costruisce solo il cruscotto vuoto e gli elementi dell'interfaccia utente (ci arriveremo alla scheda degli eventi più avanti). Gli elementi dcc sono i Dash Core Components e i HTML Components permettono facilmente l'uso di HTML nell'interfaccia utente.




html.H2('Analytics Dashboard'),

#Dropdown multi-selezione

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)"),

#Selettore di data (la data massima consentita è impostata sulla data odierna) 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), ),

#Oggetto Grafico dcc.Graph( id='Emails', figure=fig )




Nota come con Dash sia semplice creare un'interfaccia utente del cruscotto 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 trovato che la parte più complessa di questo progetto è stata costruire il quadro di dati effettivo dagli input, nonché ottenere che HTML + CSS funzionassero correttamente nell'interfaccia utente.




L'API dei Time Series Metrics consente di ottenere 33 metriche individuali basate su un intervallo date/ora. È possibile filtrare ulteriormente per Domini, Campagne, IP Pools, Domini di Invio, Sottoaccount e specificare la Precisione dei dati delle serie temporali. Questi filtri aggiuntivi insieme alle analisi di deliverabilità potrebbero essere un miglioramento futuro di questo progetto (in caso di errori, sarebbe necessario implementare una cattura degli errori per i clienti che non hanno accesso alle analisi di deliverabilità).




Utilizzando e chiamando il Metrics API, costruisco un cruscotto con i parametri selezionati dall'utente e il periodo di tempo specificato. Il cruscotto inizializzato viene quindi aggiornato.




#Costruisci la chiamata API utilizzando i parametri forniti 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(",") #Costruisci un nuovo cruscotto utilizzando le nuove metriche e date dall'aggiornata chiamata API 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




Segue un esempio di più metriche selezionate e un periodo di tempo esteso.







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

Creazione della pagina Event Details

La pagina dei dettagli dell'evento era un po' più difficile perché non sapevo qual era 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 avrebbe aggiunto un tempo significativo 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 solo con l'HTML grezzo, la tabella era incredibilmente difficile da leggere. Non c'erano bordi e nessuna differenza di colore tra intestazione e righe. Per rendere la tabella più facile da leggere, sono riuscito a usare CSS all'interno di Dash.




L'idea per i dettagli dell'evento è quasi la stessa del dashboard, tranne che questa volta chiamo l'Events API e porto tutti gli eventi. Nota che i dettagli dell'evento mostrano solo i 10 eventi più recenti (utilizzando il parametro max_rows e il filtro API). Questo può essere aumentato, tuttavia, ho deciso di mostrare i 10 eventi più recenti perché più eventi vengono mostrati, più tempo impiega la chiamata API. Un miglioramento significativo potrebbe essere la possibilità di paginare e includere una Pagina Successiva / Pagina Precedente nell'UI.




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




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




Che appare in questo modo nell'UI.










Passi successivi

Per qualcuno che desidera creare il proprio dashboard o registro degli 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 l'analisi della consegna al dashboard

  • Aggiungere più filtri al dashboard

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

  • Miglioramenti dell'interfaccia utente

  • Aggiungere filtraggio e paginazione alla pagina dei dettagli degli eventi




Sarei interessato a ricevere qualsiasi feedback o suggerimenti per espandere questo progetto.

~ Zach Samuels, Bird Senior Solutions Engineer

Connettiamoci con un esperto di Bird.
Scopri tutta la potenza del Bird in 30 minuti.

Inviando, accetti che Bird possa contattarti riguardo ai nostri prodotti e servizi.

Puoi annullare l'iscrizione in qualsiasi momento. Consulta la Informativa sulla Privacy di Bird per i dettagli sul trattamento dei dati.

Azienda

Newsletter

Rimani aggiornato con Bird attraverso aggiornamenti settimanali nella tua inbox.

Connettiamoci con un esperto di Bird.
Scopri tutta la potenza del Bird in 30 minuti.

Inviando, accetti che Bird possa contattarti riguardo ai nostri prodotti e servizi.

Puoi annullare l'iscrizione in qualsiasi momento. Consulta la Informativa sulla Privacy di Bird per i dettagli sul trattamento dei dati.

Azienda

Newsletter

Rimani aggiornato con Bird attraverso aggiornamenti settimanali nella tua inbox.

Connettiamoci con un esperto di Bird.
Scopri tutta la potenza del Bird in 30 minuti.

Inviando, accetti che Bird possa contattarti riguardo ai nostri prodotti e servizi.

Puoi annullare l'iscrizione in qualsiasi momento. Consulta la Informativa sulla Privacy di Bird per i dettagli sul trattamento dei dati.

R

Raggiungi

G

Grow

M

Manage

A

Automate

Azienda

Newsletter

Rimani aggiornato con Bird attraverso aggiornamenti settimanali nella tua inbox.