Un outil de tableau de bord avec les API d'oiseaux

Zacharie Samuels

24 mars 2022

Email

1 min read

Un outil de tableau de bord avec les API d'oiseaux

Zacharie Samuels

24 mars 2022

Email

1 min read

Un outil de tableau de bord avec les API d'oiseaux

Ce script effleure à peine la surface de ce qui est possible en utilisant Python, Plotly Dash et nos API.

Il y a presque un an, Tom Mairs, directeur du succès client chez Bird, a écrit un outil de publipostage utilisant les API Bird. Dans cet article, je reprends là où il s'est arrêté. Son outil permet la transmission programmée des tâches, mais que faire si nous voulons créer nos propres tableaux de bord et journaux d'événements ?

Peut-être que je veux créer un tableau de bord spécifique pour un groupe commercial ou un tableau de bord orienté client, sans fournir aux utilisateurs un accès complet à l'interface Bird. Ce script ne fait qu'effleurer la surface de ce qui est possible en utilisant Python, Plotly Dash, et nos APIs. Lorsque vous construisez des tableaux de bord qui traitent des données API à haut volume, sachez que des composants d'infrastructure comme le DNS peuvent devenir des goulets d'étranglement - nous avons rencontré des défis de mise à l'échelle DNS AWS qui ont affecté nos capacités de traitement des données. Pour les amateurs de flux de travail visuels, vous pouvez également explorer l'intégration de Flow Builder avec Google Cloud Functions et Vision API pour ajouter une automatisation alimentée par l'IA à vos pipelines de traitement de données.

En commençant mes recherches en ligne, je voulais trouver le chemin de moindre résistance. J'aurais pu créer tous les tableaux de bord et UI moi-même en HTML et python, cependant, après quelques recherches sur Google, je suis tombé sur Plotly’s Dash, qui s'intègre facilement avec python. J'ai choisi Dash pour 2 raisons : 1) c'est open source, et 2) après avoir lu la documentation, il m'a semblé facilement personnalisable pour ce que j'essayais de faire. Dash est une bibliothèque open-source idéale pour créer et déployer des applications de données avec des interfaces utilisateur personnalisées. Cela a rendu la création d'une UI extrêmement simple. La question est alors devenue : à quel point voulais-je complexifier cette application ? Plus je passais de temps, plus je voulais ajouter de fonctionnalités.

Pour le projet initial, je voulais m'assurer d'avoir un tableau de bord avec des métriques personnalisables et une période sélectionnable. Au début, j'ai commencé avec un tableau de bord où vous ne pouviez choisir qu'une seule métrique dans le menu déroulant. Puis, après avoir obtenu des retours de mes collègues, j'ai légèrement affiné le tableau de bord pour ajouter la multi-sélection et les titres d'axe. J'ai également décidé d'ajouter un onglet supplémentaire pour un journal d'événements. J'en suis venu à être satisfait de ce que j'avais comme bon point de départ pour quiconque souhaitant construire ses propres tableaux de bord. Pour les développeurs qui veulent intégrer des données de webhook en temps réel dans leurs tableaux de bord, consultez notre guide sur la création de consommateurs de webhook avec Azure Functions. Bien sûr, j'ai mis le projet sur Github pour que vous puissiez le cloner ou le brancher.

Commencer

Pour accéder à cette application, vous devez vous assurer que vous utilisez python 3.10 ou une version ultérieure et installer les bibliothèques suivantes :

  • requests

  • dash

  • pandas

Ensuite, saisissez votre clé API dans App.py et exécutez l'application. Elle fonctionnera sur http://localhost:8050. Pour plus d'informations sur le déploiement de cette application sur un serveur accessible au public (comme AWS), consultez les ressources suivantes :

Création de la page Dashboard

Tout d'abord, initialisez le cadre de données et le tableau de bord. Sans initialiser le tableau de bord, aucun tableau de bord n'apparaîtra dans l'UI.

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

Ensuite, construisez le premier onglet. Il s'agit d'une combinaison d'un rappel d'application (pour vérifier quel onglet est utilisé) ainsi qu'une fonction conditionnelle pour vérifier quel onglet est actuellement sélectionné. Le code ci-dessous ne construit que le tableau de bord vierge et les éléments de l'UI (nous aborderons l'onglet des événements plus tard). Les éléments dcc sont les Dash Core Components et les HTML Components permettent facilement d'utiliser HTML dans l'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)

Notez avec Dash à quel point il est simple de créer une interface utilisateur de tableau de bord avec un menu déroulant multi-sélection et recherché. Pour désactiver la multi-sélection ou la recherche, les paramètres de création d'un menu déroulant peuvent être facilement modifiés. J'ai trouvé que la partie la plus complexe de ce projet était de construire réellement le cadre de données à partir des entrées, ainsi que de faire fonctionner correctement le HTML + CSS dans l'UI.

Le Time Series Metrics API permet d'extraire 33 métriques individuelles basées sur une plage de dates/horaires. Vous pouvez filtrer plus finement par Domaines, Campagnes, Pools IP, Domaines d'envoi, Sous-comptes, et spécifier la Précision des données de série temporelle. Ces filtres supplémentaires ainsi que les analyses de délivrabilité pourraient être une amélioration future de ce projet (la gestion des erreurs devrait être mise en œuvre pour les clients qui n'ont pas accès aux analyses de délivrabilité).

En utilisant et en appelant le Metrics API, je construis un tableau de bord avec les paramètres sélectionnés par l'utilisateur et la période spécifiée. Le tableau de bord initialisé est ensuite mis à jour.

# 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

Ce qui suit est un exemple de plusieurs métriques sélectionnées et d'une période étendue.


Sparkpost analytics dashboard

Remarque : de nombreux éléments sont intégrés automatiquement dans le graphique Dash (survol, zoom, autoscale).

Tout d'abord, initialisez le cadre de données et le tableau de bord. Sans initialiser le tableau de bord, aucun tableau de bord n'apparaîtra dans l'UI.

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

Ensuite, construisez le premier onglet. Il s'agit d'une combinaison d'un rappel d'application (pour vérifier quel onglet est utilisé) ainsi qu'une fonction conditionnelle pour vérifier quel onglet est actuellement sélectionné. Le code ci-dessous ne construit que le tableau de bord vierge et les éléments de l'UI (nous aborderons l'onglet des événements plus tard). Les éléments dcc sont les Dash Core Components et les HTML Components permettent facilement d'utiliser HTML dans l'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)

Notez avec Dash à quel point il est simple de créer une interface utilisateur de tableau de bord avec un menu déroulant multi-sélection et recherché. Pour désactiver la multi-sélection ou la recherche, les paramètres de création d'un menu déroulant peuvent être facilement modifiés. J'ai trouvé que la partie la plus complexe de ce projet était de construire réellement le cadre de données à partir des entrées, ainsi que de faire fonctionner correctement le HTML + CSS dans l'UI.

Le Time Series Metrics API permet d'extraire 33 métriques individuelles basées sur une plage de dates/horaires. Vous pouvez filtrer plus finement par Domaines, Campagnes, Pools IP, Domaines d'envoi, Sous-comptes, et spécifier la Précision des données de série temporelle. Ces filtres supplémentaires ainsi que les analyses de délivrabilité pourraient être une amélioration future de ce projet (la gestion des erreurs devrait être mise en œuvre pour les clients qui n'ont pas accès aux analyses de délivrabilité).

En utilisant et en appelant le Metrics API, je construis un tableau de bord avec les paramètres sélectionnés par l'utilisateur et la période spécifiée. Le tableau de bord initialisé est ensuite mis à jour.

# 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

Ce qui suit est un exemple de plusieurs métriques sélectionnées et d'une période étendue.


Sparkpost analytics dashboard

Remarque : de nombreux éléments sont intégrés automatiquement dans le graphique Dash (survol, zoom, autoscale).

Tout d'abord, initialisez le cadre de données et le tableau de bord. Sans initialiser le tableau de bord, aucun tableau de bord n'apparaîtra dans l'UI.

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

Ensuite, construisez le premier onglet. Il s'agit d'une combinaison d'un rappel d'application (pour vérifier quel onglet est utilisé) ainsi qu'une fonction conditionnelle pour vérifier quel onglet est actuellement sélectionné. Le code ci-dessous ne construit que le tableau de bord vierge et les éléments de l'UI (nous aborderons l'onglet des événements plus tard). Les éléments dcc sont les Dash Core Components et les HTML Components permettent facilement d'utiliser HTML dans l'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)

Notez avec Dash à quel point il est simple de créer une interface utilisateur de tableau de bord avec un menu déroulant multi-sélection et recherché. Pour désactiver la multi-sélection ou la recherche, les paramètres de création d'un menu déroulant peuvent être facilement modifiés. J'ai trouvé que la partie la plus complexe de ce projet était de construire réellement le cadre de données à partir des entrées, ainsi que de faire fonctionner correctement le HTML + CSS dans l'UI.

Le Time Series Metrics API permet d'extraire 33 métriques individuelles basées sur une plage de dates/horaires. Vous pouvez filtrer plus finement par Domaines, Campagnes, Pools IP, Domaines d'envoi, Sous-comptes, et spécifier la Précision des données de série temporelle. Ces filtres supplémentaires ainsi que les analyses de délivrabilité pourraient être une amélioration future de ce projet (la gestion des erreurs devrait être mise en œuvre pour les clients qui n'ont pas accès aux analyses de délivrabilité).

En utilisant et en appelant le Metrics API, je construis un tableau de bord avec les paramètres sélectionnés par l'utilisateur et la période spécifiée. Le tableau de bord initialisé est ensuite mis à jour.

# 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

Ce qui suit est un exemple de plusieurs métriques sélectionnées et d'une période étendue.


Sparkpost analytics dashboard

Remarque : de nombreux éléments sont intégrés automatiquement dans le graphique Dash (survol, zoom, autoscale).

Création de la page Event Details

La page des détails de l'événement était un peu plus difficile car je ne savais pas la meilleure façon de présenter toutes les métriques des événements de manière facile à lire. J'ai envisagé d'ajouter des paramètres de filtrage à cette page, cependant, j'ai décidé que cela ajouterait un temps considérable à ce projet car le tableau devrait alors être dynamique (en plus d'ajouter les paramètres, les rappels, etc.). J'ai décidé de montrer tous les événements et de placer l'horodatage en premier (car sans mettre l'horodatage en premier, le graphique n'était pas facile à lire). Initialement, j'ai constaté qu'avec juste le HTML brut, le tableau était incroyablement difficile à examiner. Il n'y avait pas de bordures et pas de différences de couleur entre l'en-tête et les lignes. Pour rendre le tableau plus facile à lire, j'ai pu utiliser le CSS dans Dash.

L'idée pour les détails de l'événement est presque la même que pour le tableau de bord, sauf que cette fois, j'appelle le Events API et j'apporte tous les événements. Notez que les détails de l'événement ne montrent que les 10 événements les plus récents (en utilisant le paramètre max_rows et le filtrage API). Cela peut être augmenté, cependant, j'ai décidé de montrer les 10 événements les plus récents car plus d'événements sont montrés, plus l'appel API prend du temps. Une amélioration significative qui pourrait être apportée serait la possibilité de paginer et d'inclure une Page Suivante / Page Précédente dans l'interface utilisateur.

Pour construire l'onglet (page) des événements, d'abord, j'appelle l'Events API et je transforme la réponse JSON en un cadre de données. Ensuite, je trie et réorganise le cadre de données pour mettre l'horodatage en première colonne. Enfin, je construis le tableau HTML en parcourant le cadre de données.

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

Ce qui ressemble à ceci dans l'interface utilisateur.

Sparkpost event details

Étapes suivantes

Pour quelqu'un cherchant à créer son propre tableau de bord ou journal d'événements, c'est un bon début. Avec les possibilités de personnalisation ici, seules votre imagination vous limitera.

Comme discuté ci-dessus, certaines améliorations futures pourraient être apportées :

  • Ajout d'analyses de délivrabilité au tableau de bord

  • Ajout de plus de filtres au tableau de bord

  • Possibles options de mise en cache pour que l'API ne soit pas appelée à chaque fois pour afficher les pages

  • Améliorations de l'UI

  • Ajout de filtres et de pagination à la page des détails des événements

Je serais intéressé d'entendre tout retour ou suggestions pour étendre ce projet.

~ Zach Samuels, Bird Senior Solutions Engineer

Connectons-vous avec un expert Bird.
Découvrez toute la puissance du Bird en 30 minutes.

En soumettant, vous acceptez que Bird puisse vous contacter au sujet de nos produits et services.

Vous pouvez vous désabonner à tout moment. Consultez la Déclaration de confidentialité de Bird pour plus de détails sur le traitement des données.

Company

Newsletter

Restez à jour avec Bird grâce aux mises à jour hebdomadaires dans votre boîte de réception.

Connectons-vous avec un expert Bird.
Découvrez toute la puissance du Bird en 30 minutes.

En soumettant, vous acceptez que Bird puisse vous contacter au sujet de nos produits et services.

Vous pouvez vous désabonner à tout moment. Consultez la Déclaration de confidentialité de Bird pour plus de détails sur le traitement des données.

Company

Newsletter

Restez à jour avec Bird grâce aux mises à jour hebdomadaires dans votre boîte de réception.

Connectons-vous avec un expert Bird.
Découvrez toute la puissance du Bird en 30 minutes.

En soumettant, vous acceptez que Bird puisse vous contacter au sujet de nos produits et services.

Vous pouvez vous désabonner à tout moment. Consultez la Déclaration de confidentialité de Bird pour plus de détails sur le traitement des données.

R

Atteindre

G

Grow

M

Manage

A

Automate

Company

Newsletter

Restez à jour avec Bird grâce aux mises à jour hebdomadaires dans votre boîte de réception.