Zasięg

Grow

Manage

Automate

Zasięg

Grow

Manage

Automate

Narzędzie do tworzenia pulpitów z interfejsami API ptaków

Zachary Samuels

24 mar 2022

Email

1 min read

Narzędzie do tworzenia pulpitów z interfejsami API ptaków

Zachary Samuels

24 mar 2022

Email

1 min read

Narzędzie do tworzenia pulpitów z interfejsami API ptaków

Ten skrypt jedynie dotyka powierzchni tego, co jest możliwe przy użyciu Pythona, Plotly Dash i naszych interfejsów API.

Prawie rok temu Tom Mairs, dyrektor ds. sukcesu klienta Bird, stworzył narzędzie do rozsyłania maili wykorzystujące Bird APIs. W tym poście kontynuuję tam, gdzie on skończył. Jego narzędzie umożliwia czasowe przesyłanie zadań, ale co jeśli chcemy stworzyć własne pulpity i dzienniki zdarzeń?

Może chcę stworzyć konkretny pulpit dla grupy biznesowej lub pulpit skierowany do klientów, ale nie dawać użytkownikom pełnego dostępu do interfejsu Bird. Ten skrypt dotyka jedynie powierzchni tego, co jest możliwe przy użyciu Python, Plotly Dash oraz naszych APIs. Podczas tworzenia pulpitów przetwarzających dane API o dużej objętości, należy pamiętać, że komponenty infrastruktury, takie jak DNS, mogą stać się wąskimi gardłami - doświadczyliśmy wyzwań skalowania AWS DNS, które wpłynęły na nasze możliwości przetwarzania danych. Dla entuzjastów wizualnych przepływów pracy można również rozważyć integrację Flow Builder z Google Cloud Functions i Vision API w celu dodania automatyzacji zasilanej przez AI do swoich rurociągów przetwarzania danych.

Rozpoczynając moje poszukiwania online, chciałem znaleźć ścieżkę najmniejszego oporu. Mogłem sam stworzyć wszystkie pulpity i interfejsy użytkownika w HTML i pythonie, jednak po pewnym wyszukiwaniu w Google natknąłem się na Plotly’s Dash, który łatwo integruje się z pythonem. Wybrałem Dash z dwóch powodów: 1) jest open source, i 2) po przeczytaniu dokumentacji wydawał się łatwo dostosowywalny do tego, co chciałem zrobić. Dash jest otwartoźródłową biblioteką, która jest idealna do budowania i wdrażania aplikacji danych z dostosowanymi interfejsami użytkownika. To sprawiło, że tworzenie interfejsu użytkownika było niezwykle proste. Pytanie brzmiało wtedy, jak skomplikowane chcę, aby to było? Im więcej czasu poświęcałem, tym więcej funkcji chciałem dodać.

W początkowym projekcie chciałem upewnić się, że mam pulpit z dostosowywalnymi metrykami i wybieranym czasookresem. Początkowo zacząłem od pulpitu, na którym można było wybrać tylko jedną metrykę z rozwijanej listy. Następnie, po otrzymaniu opinii od kolegów, nieco udoskonaliłem pulpit, aby dodać funkcję multi-wyboru i tytuły osi. Również zdecydowałem się dodać dodatkową kartę do dziennika zdarzeń. Doszedłem do punktu, w którym byłem zadowolony z tego, co miałem jako dobry punkt wyjścia dla każdego, kto chciałby rozbudować własne pulpity. Dla deweloperów, którzy chcą wprowadzić dane w czasie rzeczywistym z webhooków do swoich pulpitów, zapoznaj się z naszym przewodnikiem na temat budowania konsumentów webhooków z Azure Functions. Oczywiście umieściłem projekt w Github do klonowania lub rozwijania.

Pierwsze kroki

Aby uzyskać dostęp do tej app, musisz upewnić się, że używasz python 3.10 lub nowszego i zainstalować następujące biblioteki:

  • requests

  • dash

  • pandas

Następnie wprowadź swój klucz API do App.py i uruchom aplikację. Będzie działać na http://localhost:8050. Aby uzyskać więcej informacji na temat wdrażania na serwer publiczny (takie jak AWS), zobacz następujące zasoby:

Tworzenie strony Dashboard

Najpierw zainicjuj ramkę danych i pulpit nawigacyjny. Bez inicjalizacji pulpitu nawigacyjnego, żaden pulpit nawigacyjny nie pojawi się w interfejsie użytkownika.

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

Następnie zbuduj pierwszą kartę. To jest połączenie wywołania zwrotnego aplikacji (aby sprawdzić, która karta jest używana); wraz z funkcją warunkową do sprawdzenia, która karta jest obecnie wybrana. Kod poniżej generuje tylko pusty pulpit nawigacyjny i elementy interfejsu użytkownika (nad wydarzeniami zajmiemy się później). Elementy dcc to Dash Core Components i HTML Components, które łatwo umożliwiają korzystanie z HTML w interfejsie użytkownika.

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)

Zwróć uwagę, jak proste jest tworzenie interfejsu użytkownika pulpitu nawigacyjnego z możliwością wielokrotnego wyboru oraz wyszukiwania przy użyciu dash. Aby wyłączyć funkcję wielokrotnego wyboru lub wyszukiwania, parametry tworzenia dropdown można łatwo zmodyfikować. Uważam, że najbardziej skomplikowaną częścią tego projektu było budowanie rzeczywistej ramki danych z danych wejściowych oraz uzyskanie poprawnego działania HTML + CSS w interfejsie użytkownika.

Time Series Metrics API umożliwia wyciąganie 33 indywidualnych metryk na podstawie zakresu dat/czasu. Możesz filtrować głębiej według Domen, Kampanie, IP Pools, Sending Domains, Subconta i określić Precyzję danych szeregów czasowych. Te dodatkowe filtry wraz z analizą dostarczalności mogą być przyszłym ulepszeniem tego projektu (należy zaimplementować przechwytywanie błędów dla klientów, którzy nie mają dostępu do analizy dostarczalności).

Wykorzystując i wywołując Metrics API, tworzę pulpit nawigacyjny z wybranymi przez użytkownika parametrami i określonym przedziałem czasowym. Zainicjowany pulpit nawigacyjny jest następnie aktualizowany.

# 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

Poniżej znajduje się przykład wielu wybranych metryk i rozszerzonego przedziału czasowego.


Sparkpost analytics dashboard

Uwaga: w wykresie dash automatycznie wbudowanych jest wiele elementów (np. hover, zoom, autoscale).

Najpierw zainicjuj ramkę danych i pulpit nawigacyjny. Bez inicjalizacji pulpitu nawigacyjnego, żaden pulpit nawigacyjny nie pojawi się w interfejsie użytkownika.

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

Następnie zbuduj pierwszą kartę. To jest połączenie wywołania zwrotnego aplikacji (aby sprawdzić, która karta jest używana); wraz z funkcją warunkową do sprawdzenia, która karta jest obecnie wybrana. Kod poniżej generuje tylko pusty pulpit nawigacyjny i elementy interfejsu użytkownika (nad wydarzeniami zajmiemy się później). Elementy dcc to Dash Core Components i HTML Components, które łatwo umożliwiają korzystanie z HTML w interfejsie użytkownika.

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)

Zwróć uwagę, jak proste jest tworzenie interfejsu użytkownika pulpitu nawigacyjnego z możliwością wielokrotnego wyboru oraz wyszukiwania przy użyciu dash. Aby wyłączyć funkcję wielokrotnego wyboru lub wyszukiwania, parametry tworzenia dropdown można łatwo zmodyfikować. Uważam, że najbardziej skomplikowaną częścią tego projektu było budowanie rzeczywistej ramki danych z danych wejściowych oraz uzyskanie poprawnego działania HTML + CSS w interfejsie użytkownika.

Time Series Metrics API umożliwia wyciąganie 33 indywidualnych metryk na podstawie zakresu dat/czasu. Możesz filtrować głębiej według Domen, Kampanie, IP Pools, Sending Domains, Subconta i określić Precyzję danych szeregów czasowych. Te dodatkowe filtry wraz z analizą dostarczalności mogą być przyszłym ulepszeniem tego projektu (należy zaimplementować przechwytywanie błędów dla klientów, którzy nie mają dostępu do analizy dostarczalności).

Wykorzystując i wywołując Metrics API, tworzę pulpit nawigacyjny z wybranymi przez użytkownika parametrami i określonym przedziałem czasowym. Zainicjowany pulpit nawigacyjny jest następnie aktualizowany.

# 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

Poniżej znajduje się przykład wielu wybranych metryk i rozszerzonego przedziału czasowego.


Sparkpost analytics dashboard

Uwaga: w wykresie dash automatycznie wbudowanych jest wiele elementów (np. hover, zoom, autoscale).

Najpierw zainicjuj ramkę danych i pulpit nawigacyjny. Bez inicjalizacji pulpitu nawigacyjnego, żaden pulpit nawigacyjny nie pojawi się w interfejsie użytkownika.

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

Następnie zbuduj pierwszą kartę. To jest połączenie wywołania zwrotnego aplikacji (aby sprawdzić, która karta jest używana); wraz z funkcją warunkową do sprawdzenia, która karta jest obecnie wybrana. Kod poniżej generuje tylko pusty pulpit nawigacyjny i elementy interfejsu użytkownika (nad wydarzeniami zajmiemy się później). Elementy dcc to Dash Core Components i HTML Components, które łatwo umożliwiają korzystanie z HTML w interfejsie użytkownika.

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)

Zwróć uwagę, jak proste jest tworzenie interfejsu użytkownika pulpitu nawigacyjnego z możliwością wielokrotnego wyboru oraz wyszukiwania przy użyciu dash. Aby wyłączyć funkcję wielokrotnego wyboru lub wyszukiwania, parametry tworzenia dropdown można łatwo zmodyfikować. Uważam, że najbardziej skomplikowaną częścią tego projektu było budowanie rzeczywistej ramki danych z danych wejściowych oraz uzyskanie poprawnego działania HTML + CSS w interfejsie użytkownika.

Time Series Metrics API umożliwia wyciąganie 33 indywidualnych metryk na podstawie zakresu dat/czasu. Możesz filtrować głębiej według Domen, Kampanie, IP Pools, Sending Domains, Subconta i określić Precyzję danych szeregów czasowych. Te dodatkowe filtry wraz z analizą dostarczalności mogą być przyszłym ulepszeniem tego projektu (należy zaimplementować przechwytywanie błędów dla klientów, którzy nie mają dostępu do analizy dostarczalności).

Wykorzystując i wywołując Metrics API, tworzę pulpit nawigacyjny z wybranymi przez użytkownika parametrami i określonym przedziałem czasowym. Zainicjowany pulpit nawigacyjny jest następnie aktualizowany.

# 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

Poniżej znajduje się przykład wielu wybranych metryk i rozszerzonego przedziału czasowego.


Sparkpost analytics dashboard

Uwaga: w wykresie dash automatycznie wbudowanych jest wiele elementów (np. hover, zoom, autoscale).

Tworzenie strony Event Details

Strona szczegółów wydarzenia była nieco trudniejsza, ponieważ nie wiedziałem, jak najlepiej przedstawić wszystkie metryki wydarzeń w łatwy do odczytania sposób. Rozważałem dodanie parametrów filtrowania do tej strony, jednak zdecydowałem, że dodałoby to znaczny czas do tego projektu, ponieważ tabela musiałaby być wtedy dynamiczna (wraz z dodaniem parametrów, wywołań zwrotnych itp.). Zdecydowałem się pokazać wszystkie wydarzenia i umieścić znacznik czasu na początku (ponieważ bez umieszczenia znacznika czasu na początku, wykres nie był łatwy do odczytania). Początkowo stwierdziłem, że z samym surowym HTML, tabela była wyjątkowo niewygodna dla oczu. Nie było żadnych obramowań ani różnic kolorów między nagłówkiem a wierszami. Aby tabela była łatwiejsza do odczytania, mogłem użyć CSS w Dash.

Pomysł na szczegóły wydarzenia jest prawie taki sam jak na pulpicie, z tą różnicą, że tym razem wywołuję Events API i pobieram wszystkie wydarzenia. Zauważ, że szczegóły wydarzenia pokazują tylko 10 najnowszych wydarzeń (korzystając z parametru max_rows i filtrowania API). Można to zwiększyć, jednak zdecydowałem się pokazywać 10 najnowszych wydarzeń, ponieważ im więcej wydarzeń jest pokazywanych, tym dłużej trwa wywołanie API. Jednym ze znaczących ulepszeń, które można wprowadzić, byłaby możliwość paginacji i włączenia opcji Następna strona / Poprzednia strona w interfejsie użytkownika.

Aby zbudować zakładkę (stronę) wydarzeń, najpierw wywołuję Events API i analizuję odpowiedź JSON na ramkę danych. Następnie sortuję i porządkuję ramkę danych, aby umieścić znacznik czasu jako pierwszą kolumnę. Na koniec tworzę tabelę HTML, iterując przez ramkę danych.

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

Która wygląda tak w interfejsie użytkownika.

Sparkpost event details

Następne Kroki

Dla kogoś, kto chce stworzyć własny pulpit nawigacyjny lub dziennik wydarzeń, jest to dobry początek. Dzięki możliwości dostosowywania, jedynym ograniczeniem jest wyobraźnia.

Jak omówiono powyżej, niektóre przyszłe ulepszenia, które można wprowadzić, to:

  • Dodanie analizy dostarczalności do pulpitu nawigacyjnego

  • Dodanie większej liczby filtrów do pulpitu nawigacyjnego

  • Możliwe opcje buforowania, aby API nie było wywoływane za każdym razem w celu wyświetlenia stron

  • Ulepszenia UI

  • Dodanie filtrowania i stronicowania do strony szczegółów wydarzenia

Byłbym zainteresowany usłyszeniem jakichkolwiek uwag lub sugestii dotyczących rozszerzenia tego projektu.

~ Zach Samuels, Bird Senior Solutions Engineer

Połączmy Cię z ekspertem Bird.
Zobacz pełną moc Bird w 30 minut.

Przesyłając, zgadzasz się, że Bird może kontaktować się z Tobą w sprawie naszych produktów i usług.

Możesz zrezygnować z subskrypcji w dowolnym momencie. Zobacz Privacy Statement firmy Bird, aby uzyskać szczegóły dotyczące przetwarzania danych.

Company

Biuletyn

Bądź na bieżąco z Bird dzięki cotygodniowym aktualizacjom do Twojej skrzynki odbiorczej.

Połączmy Cię z ekspertem Bird.
Zobacz pełną moc Bird w 30 minut.

Przesyłając, zgadzasz się, że Bird może kontaktować się z Tobą w sprawie naszych produktów i usług.

Możesz zrezygnować z subskrypcji w dowolnym momencie. Zobacz Privacy Statement firmy Bird, aby uzyskać szczegóły dotyczące przetwarzania danych.

Company

Biuletyn

Bądź na bieżąco z Bird dzięki cotygodniowym aktualizacjom do Twojej skrzynki odbiorczej.

Połączmy Cię z ekspertem Bird.
Zobacz pełną moc Bird w 30 minut.

Przesyłając, zgadzasz się, że Bird może kontaktować się z Tobą w sprawie naszych produktów i usług.

Możesz zrezygnować z subskrypcji w dowolnym momencie. Zobacz Privacy Statement firmy Bird, aby uzyskać szczegóły dotyczące przetwarzania danych.

R

Reach

G

Grow

M

Manage

A

Automate

Company

Biuletyn

Bądź na bieżąco z Bird dzięki cotygodniowym aktualizacjom do Twojej skrzynki odbiorczej.