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, 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 dei lavori, ma cosa succede se vogliamo creare i nostri cruscotti e log di eventi?

Potrei voler creare un cruscotto specifico per un gruppo aziendale o un cruscotto per i clienti, ma non fornire agli utenti l'accesso completo all'interfaccia utente di Bird. Questo script tocca solo la superficie di ciò che è possibile utilizzando Python, Plotly Dash e le nostre API. Quando si costruiscono cruscotti che elaborano dati API ad alto volume, è importante essere consapevoli che componenti di infrastruttura come il DNS possono diventare dei colli di bottiglia - abbiamo affrontato sfide di scalabilità del DNS di AWS che hanno influenzato le nostre capacità di elaborazione dei dati. Per gli appassionati di workflow visivi, potete anche esplorare l'integrazione di Flow Builder con Google Cloud Functions e Vision API per aggiungere automazione potenziata dall'IA ai vostri pipeline di elaborazione dati.

Quando ho iniziato la mia ricerca online, volevo trovare il percorso di minor resistenza. Avrei potuto creare tutti i cruscotti e l'interfaccia utente da solo in HTML e python, tuttavia, dopo alcune ricerche su Google, mi sono imbattuto in Plotly’s Dash, che si integra facilmente con python. Ho scelto Dash per 2 ragioni: 1) è open source e 2) dopo aver letto la documentazione sembrava facilmente personalizzabile per ciò che cercavo di fare. Dash è una libreria open source ideale per creare e distribuire applicazioni dati con interfacce utente personalizzate. Questo ha reso la creazione di un'interfaccia utente estremamente semplice. La domanda è diventata poi, quanto complessa volevo rendere quest'app? Più tempo ho passato, più funzionalità volevo aggiungere.

Per il progetto iniziale, volevo assicurarmi di avere un cruscotto con metriche personalizzabili e un intervallo di tempo selezionabile. Inizialmente, ho cominciato con un cruscotto dove potevi scegliere solo una metrica dal menu a tendina. Poi, mentre ricevevo feedback dai colleghi, ho affinato un po' il cruscotto per aggiungere la selezione multipla e i titoli degli assi. Ho anche deciso di aggiungere una scheda aggiuntiva per un log degli eventi. Sono arrivato al punto in cui ero soddisfatto di ciò che avevo come buon punto di partenza per chiunque desideri sviluppare i propri cruscotti. Per gli sviluppatori che vogliono alimentare in tempo reale i dati webhook nei loro cruscotti, date un'occhiata alla nostra guida su come costruire consumatori webhook con Azure Functions. Ovviamente, ho messo il progetto su Github per far sì che possiate clonarlo o crearne una derivazione.

Iniziare

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

  • requests

  • dash

  • pandas

Quindi, inserisci la tua API key in App.py ed esegui l'app. Sarà disponibile su http://localhost:8050. Per ulteriori informazioni sul deployment di questa su un server accessibile al pubblico (come AWS), vedere le seguenti risorse:

Creazione della Dashboard Page

Prima, inizializzare il data frame e il dashboard. Senza inizializzare il dashboard, nessun dashboard apparirà nell'UI.

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 app callback (per verificare quale scheda viene utilizzata); insieme a una funzione condizionale per controllare quale scheda è attualmente selezionata. Il codice seguente costruisce solo il dashboard vuoto e gli elementi UI (ci occuperemo della scheda eventi più avanti). Gli elementi dcc sono i Dash Core Components e gli HTML Components consentono facilmente l'uso dell'HTML nell'UI.

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 come con dash sia semplice creare un'UI 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 trovato che la parte più complessa di questo progetto era costruire effettivamente il data frame dai dati di input, così come far funzionare correttamente l'HTML + CSS nell'UI.

L'Time Series Metrics API consente di estrarre 33 metriche individuali basate su un intervallo di date/tempo. È possibile filtrare ulteriormente per Domini, Campagne, Pool di IP, Domini di Invio, Subaccount e specificare la Precisione dei dati delle serie temporali. Questi ulteriori filtri insieme alle analisi di deliverability potrebbero essere un miglioramento futuro per questo progetto (la gestione degli errori dovrebbe essere implementata per i clienti che non hanno accesso alle analisi di deliverability).

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

# 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

Di seguito è riportato un esempio di selezione multipla di metriche e di un periodo di tempo ampliato.


Sparkpost analytics dashboard

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

Prima, inizializzare il data frame e il dashboard. Senza inizializzare il dashboard, nessun dashboard apparirà nell'UI.

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 app callback (per verificare quale scheda viene utilizzata); insieme a una funzione condizionale per controllare quale scheda è attualmente selezionata. Il codice seguente costruisce solo il dashboard vuoto e gli elementi UI (ci occuperemo della scheda eventi più avanti). Gli elementi dcc sono i Dash Core Components e gli HTML Components consentono facilmente l'uso dell'HTML nell'UI.

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 come con dash sia semplice creare un'UI 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 trovato che la parte più complessa di questo progetto era costruire effettivamente il data frame dai dati di input, così come far funzionare correttamente l'HTML + CSS nell'UI.

L'Time Series Metrics API consente di estrarre 33 metriche individuali basate su un intervallo di date/tempo. È possibile filtrare ulteriormente per Domini, Campagne, Pool di IP, Domini di Invio, Subaccount e specificare la Precisione dei dati delle serie temporali. Questi ulteriori filtri insieme alle analisi di deliverability potrebbero essere un miglioramento futuro per questo progetto (la gestione degli errori dovrebbe essere implementata per i clienti che non hanno accesso alle analisi di deliverability).

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

# 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

Di seguito è riportato un esempio di selezione multipla di metriche e di un periodo di tempo ampliato.


Sparkpost analytics dashboard

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

Prima, inizializzare il data frame e il dashboard. Senza inizializzare il dashboard, nessun dashboard apparirà nell'UI.

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 app callback (per verificare quale scheda viene utilizzata); insieme a una funzione condizionale per controllare quale scheda è attualmente selezionata. Il codice seguente costruisce solo il dashboard vuoto e gli elementi UI (ci occuperemo della scheda eventi più avanti). Gli elementi dcc sono i Dash Core Components e gli HTML Components consentono facilmente l'uso dell'HTML nell'UI.

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 come con dash sia semplice creare un'UI 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 trovato che la parte più complessa di questo progetto era costruire effettivamente il data frame dai dati di input, così come far funzionare correttamente l'HTML + CSS nell'UI.

L'Time Series Metrics API consente di estrarre 33 metriche individuali basate su un intervallo di date/tempo. È possibile filtrare ulteriormente per Domini, Campagne, Pool di IP, Domini di Invio, Subaccount e specificare la Precisione dei dati delle serie temporali. Questi ulteriori filtri insieme alle analisi di deliverability potrebbero essere un miglioramento futuro per questo progetto (la gestione degli errori dovrebbe essere implementata per i clienti che non hanno accesso alle analisi di deliverability).

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

# 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

Di seguito è riportato un esempio di selezione multipla di metriche e di un periodo di tempo ampliato.


Sparkpost analytics dashboard

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

Creazione della pagina Event Details

La pagina dei dettagli dell'evento era un po' più difficile perché non sapevo il modo migliore per presentare tutti i metri degli eventi in modo facile da leggere. Ho considerato di aggiungere parametri di filtro a questa pagina, tuttavia, ho deciso che ciò 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 con solo 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 stato in grado di utilizzare CSS all'interno di Dash.

L'idea per i dettagli dell'evento è quasi la stessa del cruscotto, 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 filtraggio 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 che potrebbe essere fatto sarebbe la capacità di paginare e includere una Pagina Successiva/Pagina Precedente nell'interfaccia utente.

Per costruire la scheda (pagina) degli eventi, 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 attraverso il 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 = 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

Passi successivi

Per chi cerca di creare il proprio dashboard o registro eventi, questo è un buon punto di partenza. Con la personalizzazione qui, il cielo è il limite.

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

  • Aggiungere analisi di deliverability al dashboard

  • Aggiungere più filtri al dashboard

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

  • Miglioramenti UI

  • Aggiungere filtraggio e paginazione alla pagina dei dettagli degli eventi

Sarei interessato a sentire qualsiasi feedback o suggerimento 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.