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

Email

·

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

Najważniejsze informacje

    • Interfejsy API ptaków można połączyć z Pythonem i Plotly Dash, aby zbudować potężne, interaktywne pulpity nawigacyjne bez potrzeby korzystania z pełnego interfejsu użytkownika Bird.

    • Projekt pokazuje, jak wizualizować metryki i wydarzenia za pomocą interfejsu API metryk i interfejsu API zdarzeń Bird w niestandardowej aplikacji internetowej.

    • Plotly Dash zapewnia szybkie, otwarte źródło do budowania elementów interfejsu użytkownika, takich jak rozwijane listy, wykresy i tabele.

    • Deweloperzy mogą rozszerzać narzędzie o analizę dostarczalności, filtrowanie i paginację, aby uzyskać bogatsze pulpity nawigacyjne.

    • Przyszłe ulepszenia obejmują buforowanie, ulepszony interfejs użytkownika oraz integrację z innymi produktami Bird lub interfejsami API stron trzecich.

    • Baza kodu (dostępna na GitHub) stanowi mocny punkt wyjścia dla każdego, kto chce zbudować pulpity nawigacyjne oparte na Bird lub portale dla klientów.

Podsumowanie pytań i odpowiedzi

  • Jaki jest cel tego projektu dashboardowego?

    Pokazuje, jak deweloperzy mogą korzystać z Bird APIs w Pythonie i Plotly Dash, aby tworzyć oparte na danych pulpitowe, które wizualizują metryki kampanii i ostatnie wydarzenia.

  • Dlaczego używać Plotly Dash do interfejsów API ptaków?

    Dash jest open source, łatwy do dostosowania i idealny do tworzenia interaktywnych interfejsów użytkownika bez potrzeby posiadania wiedzy w zakresie front-endu.

  • Co wyświetla panel kontrolny?

    Wizualizuje metryki czasowe z API Metryki Bird oraz dane o recentnych zdarzeniach z API Zdarzeń, z opcjami filtrowania i wybierania metryk w niestandardowych zakresach czasowych.

  • Jak można jeszcze bardziej rozszerzyć to narzędzie?

    Poprzez dodanie analityki dostarczalności, zaawansowanych filtrów, cachowania danych oraz paginacji dla dużych zbiorów danych w celu poprawy wydajności i użyteczności.

  • Jakie umiejętności lub narzędzia są potrzebne do jej uruchomienia?

    Podstawowa wiedza o Pythonie i instalacja bibliotek requests, dash oraz pandas. Klucz API z Bird jest wymagany, aby pobrać dane.

  • Jak ten projekt wpisuje się w ekosystem Birds?

    Ilustruje, w jaki sposób otwarte interfejsy API Bird mogą być wykorzystywane do tworzenia niestandardowych pulpitów nawigacyjnych i narzędzi raportowych dla zespołów lub klientów, którzy nie mają dostępu do pełnej platformy.

Ten skrypt jedynie dotyka powierzchni tego, co jest możliwe dzięki wykorzystaniu Pythona, Plotly Dash i naszych interfejsów API.

API i pulpit nawigacyjny Bird Metrics z Pythonem

Prawie rok temu Tom Mairs, dyrektor ds. sukcesu klienta w firmie Bird, napisał narzędzie do przesyłania wiadomości wykorzystujące API Bird. W tym poście kontynuuję to, co on zaczął. Jego narzędzie umożliwia zdalne przesyłanie zadań w określonych odstępach czasu, ale co jeśli chcemy stworzyć nasze własne pulpity nawigacyjne i dzienniki zdarzeń?

Może chcę stworzyć konkretny pulpit nawigacyjny dla grupy biznesowej lub pulpit przyjazny dla klienta, ale nie chcę dawać użytkownikom pełnego dostępu do interfejsu UI Bird. Ten skrypt tylko dotyka powierzchni możliwości wykorzystania Pythona, Plotly Dash i naszych API. Tworząc pulpity, które przetwarzają dane API o dużym wolumenie, należy być świadomym, że komponenty infrastruktury, takie jak DNS, mogą stać się wąskimi gardłami - doświadczyliśmy wyzwań związanych ze skalowaniem DNS AWS, które wpłynęły na nasze możliwości przetwarzania danych. Dla entuzjastów wizualnych przepływów pracy, można również zbadać integrację Flow Buildera z Google Cloud Functions i Vision API, aby dodać automatyzację wspieraną przez AI do swoich przepływów przetwarzania danych.

Kiedy rozpocząłem moje poszukiwania w sieci, chciałem znaleźć drogę o jak najmniejszym oporze. Mógłbym stworzyć wszystkie pulpity i UI samodzielnie w HTML i Pythonie, jednak po kilku wyszukiwaniach w Google natknąłem się na Dash Plotly, który łatwo integruje się z Pythonem. Wybrałem Dash z dwóch powodów: 1) jest open source, a 2) po przeczytaniu dokumentacji wydawało się łatwo dostosowywać do tego, co próbowałem zrobić. Dash to biblioteka open-source, która jest idealna do budowania i wdrażania aplikacji danych z dostosowanymi interfejsami użytkownika. Dzięki temu stworzenie UI stało się niezwykle proste. Pytanie brzmiało więc, jak skomplikowaną chciałem uczynić tę aplikację? Im więcej czasu spędzałem, tym więcej funkcji chciałem dodać.

Dla wstępnego projektu chciałem upewnić się, że mam pulpit nawigacyjny z konfigurowalnymi metrykami i wybieranym zakresem czasowym. Na początku zacząłem od pulpitu, na którym można było wybrać tylko jedną metrykę z rozwijanej listy. Następnie, gdy otrzymałem opinie od kolegów, nieco dopracowałem pulpit, aby dodać możliwość wielokrotnego wyboru i tytuły osi. Postanowiłem także dodać dodatkową zakładkę na dziennik zdarzeń. Doszedłem do momentu, w którym byłem zadowolony z tego, co miałem jako dobry punkt wyjścia dla każdego, kto chciałby zbudować własne pulpity. Dla programistów, którzy chcą wprowadzać dane webhooków w czasie rzeczywistym do swoich pulpitów, zapoznaj się z naszym przewodnikiem po budowaniu konsumentów webhooków z Azure Functions. Oczywiście umieściłem projekt na Githubie, abyś mógł go sklonować lub utworzyć gałąź.

Pierwsze kroki

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

Biblioteka Pythona

Cel

requests

Komunikacja API z usługami Bird

dash

Renderowanie interfejsu użytkownika i pulpitu nawigacyjnego

pandas

Przetwarzanie danych i generowanie tabeli

Następnie wprowadź swój klucz API do App.py i uruchom aplikację. Będzie działać pod adresem http://localhost:8050. Aby uzyskać więcej informacji na temat wdrażania tego na serwerze dostępnym publicznie (np. AWS), zobacz poniższe źródła:

Tworzenie strony pulpitu

Najpierw zainicjuj ramkę danych i pulpit nawigacyjny. Bez zainicjowania pulpit 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ą zakładkę. Jest to kombinacja wywołania aplikacji (aby sprawdzić, która zakładka jest używana); wraz z warunkową funkcją do sprawdzenia, która zakładka jest aktualnie wybrana. Poniższy kod buduje jedynie pusty pulpit i elementy interfejsu użytkownika (do zakładki zdarzeń wrócimy później). Elementy dcc to Komponenty Główne Dash, a Komponenty HTML łatwo umożliwiają używanie 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)

Zauważ, jak proste jest tworzenie interfejsu pulpitu z wielokrotnym wyborem i wyszukiwaną listą rozwijaną. Aby wyłączyć wybór wielokrotny lub wyszukiwanie, parametry do tworzenia listy rozwijanej można łatwo zmodyfikować. Udało mi się ustalić, że najbardziej skomplikowaną częścią tego projektu było zbudowanie rzeczywistej ramki danych z wejść, a także uzyskanie poprawnej pracy HTML + CSS w interfejsie użytkownika.

API Metryki serii czasowej pozwala na pobranie 33 indywidualnych metryk na podstawie zakresu dat/czasu. Możesz głębiej filtrować według domen, kampanii, pul zasobów, domen wysyłkowych, subkont i określić precyzję danych szeregów czasowych. Te dodatkowe filtry wraz z analizami dostarczalności mogą być przyszłym ulepszeniem tego projektu (należy wdrożyć obsługę błędów dla klientów, którzy nie mają dostępu do analiz dostarczalności).

Korzystając z API metryk, buduję pulpit z wybranymi przez użytkownika parametrami oraz określonym przedziałem czasowym. Zainicjowany pulpit jest następnie aktualizowany.

Widok pulpitu (API Metryki serii czasowej)

# 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 wybranych wielu metryk i rozszerzonego zakresu czasowego.


Sparkpost analytics dashboard

Uwaga: w wykresie dash automatycznie wbudowanych jest wiele elementów (najazd, powiększenie, automatyczne skalowanie).

Najpierw zainicjuj ramkę danych i pulpit nawigacyjny. Bez zainicjowania pulpit 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ą zakładkę. Jest to kombinacja wywołania aplikacji (aby sprawdzić, która zakładka jest używana); wraz z warunkową funkcją do sprawdzenia, która zakładka jest aktualnie wybrana. Poniższy kod buduje jedynie pusty pulpit i elementy interfejsu użytkownika (do zakładki zdarzeń wrócimy później). Elementy dcc to Komponenty Główne Dash, a Komponenty HTML łatwo umożliwiają używanie 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)

Zauważ, jak proste jest tworzenie interfejsu pulpitu z wielokrotnym wyborem i wyszukiwaną listą rozwijaną. Aby wyłączyć wybór wielokrotny lub wyszukiwanie, parametry do tworzenia listy rozwijanej można łatwo zmodyfikować. Udało mi się ustalić, że najbardziej skomplikowaną częścią tego projektu było zbudowanie rzeczywistej ramki danych z wejść, a także uzyskanie poprawnej pracy HTML + CSS w interfejsie użytkownika.

API Metryki serii czasowej pozwala na pobranie 33 indywidualnych metryk na podstawie zakresu dat/czasu. Możesz głębiej filtrować według domen, kampanii, pul zasobów, domen wysyłkowych, subkont i określić precyzję danych szeregów czasowych. Te dodatkowe filtry wraz z analizami dostarczalności mogą być przyszłym ulepszeniem tego projektu (należy wdrożyć obsługę błędów dla klientów, którzy nie mają dostępu do analiz dostarczalności).

Korzystając z API metryk, buduję pulpit z wybranymi przez użytkownika parametrami oraz określonym przedziałem czasowym. Zainicjowany pulpit jest następnie aktualizowany.

Widok pulpitu (API Metryki serii czasowej)

# 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 wybranych wielu metryk i rozszerzonego zakresu czasowego.


Sparkpost analytics dashboard

Uwaga: w wykresie dash automatycznie wbudowanych jest wiele elementów (najazd, powiększenie, automatyczne skalowanie).

Najpierw zainicjuj ramkę danych i pulpit nawigacyjny. Bez zainicjowania pulpit 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ą zakładkę. Jest to kombinacja wywołania aplikacji (aby sprawdzić, która zakładka jest używana); wraz z warunkową funkcją do sprawdzenia, która zakładka jest aktualnie wybrana. Poniższy kod buduje jedynie pusty pulpit i elementy interfejsu użytkownika (do zakładki zdarzeń wrócimy później). Elementy dcc to Komponenty Główne Dash, a Komponenty HTML łatwo umożliwiają używanie 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)

Zauważ, jak proste jest tworzenie interfejsu pulpitu z wielokrotnym wyborem i wyszukiwaną listą rozwijaną. Aby wyłączyć wybór wielokrotny lub wyszukiwanie, parametry do tworzenia listy rozwijanej można łatwo zmodyfikować. Udało mi się ustalić, że najbardziej skomplikowaną częścią tego projektu było zbudowanie rzeczywistej ramki danych z wejść, a także uzyskanie poprawnej pracy HTML + CSS w interfejsie użytkownika.

API Metryki serii czasowej pozwala na pobranie 33 indywidualnych metryk na podstawie zakresu dat/czasu. Możesz głębiej filtrować według domen, kampanii, pul zasobów, domen wysyłkowych, subkont i określić precyzję danych szeregów czasowych. Te dodatkowe filtry wraz z analizami dostarczalności mogą być przyszłym ulepszeniem tego projektu (należy wdrożyć obsługę błędów dla klientów, którzy nie mają dostępu do analiz dostarczalności).

Korzystając z API metryk, buduję pulpit z wybranymi przez użytkownika parametrami oraz określonym przedziałem czasowym. Zainicjowany pulpit jest następnie aktualizowany.

Widok pulpitu (API Metryki serii czasowej)

# 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 wybranych wielu metryk i rozszerzonego zakresu czasowego.


Sparkpost analytics dashboard

Uwaga: w wykresie dash automatycznie wbudowanych jest wiele elementów (najazd, powiększenie, automatyczne skalowanie).

Tworzenie strony szczegółów wydarzenia

Strona szczegółów wydarzenia była trochę trudniejsza, ponieważ nie wiedziałem, jak najlepiej przedstawić wszystkie metryki wydarzeń w sposób łatwy do odczytania. Rozważałem dodanie parametrów filtrujących do tej strony, jednak zdecydowałem, że dodałoby to znaczną ilość czasu do tego projektu, ponieważ tabela musiałaby być wtedy dynamiczna (wraz z dodawaniem parametrów, callbacków itp.). Postanowiłem pokazać wszystkie wydarzenia i umieścić znacznik czasu na pierwszym miejscu (ponieważ bez umieszczania znacznika czasu na pierwszym miejscu wykres nie był łatwy do odczytania). Początkowo stwierdziłem, że w przypadku samego surowego HTML tabela była niewiarygodnie trudna dla oczu. Nie było żadnych ram oraz różnic kolorystycznych między nagłówkiem a wierszami. Aby ułatwić odczyt tabeli, mogłem użyć CSS w Dash.

Widok szczegółów wydarzenia (API wydarzeń)

Pomysł na szczegóły wydarzenia jest prawie taki sam jak na pulpicie, z tą różnicą, że tym razem wywołuję API wydarzeń i przynoszę wszystkie wydarzenia. Zauważ, że szczegóły wydarzenia pokazują tylko 10 najnowszych wydarzeń (wykorzystując parametr max_rows i filtrację API). Można to zwiększyć, jednak postanowiłem pokazać 10 najnowszych wydarzeń, ponieważ im więcej wydarzeń zostało pokazanych, tym dłużej trwa wywołanie API. Jedno istotne ulepszenie, które można wprowadzić, to możliwość paginacji i dodanie następną stronę / poprzednią stronę w interfejsie użytkownika.

Aby zbudować zakładkę wydarzeń (stronę), najpierw wywołuję API wydarzeń i przetwarzam odpowiedź JSON na ramkę danych. Następnie sortuję i reorganizuję ramkę danych, aby umieścić znacznik czasu jako pierwszą kolumnę. W końcu buduję 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))
        ])
    ])
])

Co wygląda tak w interfejsie użytkownika.

Sparkpost event details

Strona szczegółów wydarzenia była trochę trudniejsza, ponieważ nie wiedziałem, jak najlepiej przedstawić wszystkie metryki wydarzeń w sposób łatwy do odczytania. Rozważałem dodanie parametrów filtrujących do tej strony, jednak zdecydowałem, że dodałoby to znaczną ilość czasu do tego projektu, ponieważ tabela musiałaby być wtedy dynamiczna (wraz z dodawaniem parametrów, callbacków itp.). Postanowiłem pokazać wszystkie wydarzenia i umieścić znacznik czasu na pierwszym miejscu (ponieważ bez umieszczania znacznika czasu na pierwszym miejscu wykres nie był łatwy do odczytania). Początkowo stwierdziłem, że w przypadku samego surowego HTML tabela była niewiarygodnie trudna dla oczu. Nie było żadnych ram oraz różnic kolorystycznych między nagłówkiem a wierszami. Aby ułatwić odczyt tabeli, mogłem użyć CSS w Dash.

Widok szczegółów wydarzenia (API wydarzeń)

Pomysł na szczegóły wydarzenia jest prawie taki sam jak na pulpicie, z tą różnicą, że tym razem wywołuję API wydarzeń i przynoszę wszystkie wydarzenia. Zauważ, że szczegóły wydarzenia pokazują tylko 10 najnowszych wydarzeń (wykorzystując parametr max_rows i filtrację API). Można to zwiększyć, jednak postanowiłem pokazać 10 najnowszych wydarzeń, ponieważ im więcej wydarzeń zostało pokazanych, tym dłużej trwa wywołanie API. Jedno istotne ulepszenie, które można wprowadzić, to możliwość paginacji i dodanie następną stronę / poprzednią stronę w interfejsie użytkownika.

Aby zbudować zakładkę wydarzeń (stronę), najpierw wywołuję API wydarzeń i przetwarzam odpowiedź JSON na ramkę danych. Następnie sortuję i reorganizuję ramkę danych, aby umieścić znacznik czasu jako pierwszą kolumnę. W końcu buduję 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))
        ])
    ])
])

Co wygląda tak w interfejsie użytkownika.

Sparkpost event details

Strona szczegółów wydarzenia była trochę trudniejsza, ponieważ nie wiedziałem, jak najlepiej przedstawić wszystkie metryki wydarzeń w sposób łatwy do odczytania. Rozważałem dodanie parametrów filtrujących do tej strony, jednak zdecydowałem, że dodałoby to znaczną ilość czasu do tego projektu, ponieważ tabela musiałaby być wtedy dynamiczna (wraz z dodawaniem parametrów, callbacków itp.). Postanowiłem pokazać wszystkie wydarzenia i umieścić znacznik czasu na pierwszym miejscu (ponieważ bez umieszczania znacznika czasu na pierwszym miejscu wykres nie był łatwy do odczytania). Początkowo stwierdziłem, że w przypadku samego surowego HTML tabela była niewiarygodnie trudna dla oczu. Nie było żadnych ram oraz różnic kolorystycznych między nagłówkiem a wierszami. Aby ułatwić odczyt tabeli, mogłem użyć CSS w Dash.

Widok szczegółów wydarzenia (API wydarzeń)

Pomysł na szczegóły wydarzenia jest prawie taki sam jak na pulpicie, z tą różnicą, że tym razem wywołuję API wydarzeń i przynoszę wszystkie wydarzenia. Zauważ, że szczegóły wydarzenia pokazują tylko 10 najnowszych wydarzeń (wykorzystując parametr max_rows i filtrację API). Można to zwiększyć, jednak postanowiłem pokazać 10 najnowszych wydarzeń, ponieważ im więcej wydarzeń zostało pokazanych, tym dłużej trwa wywołanie API. Jedno istotne ulepszenie, które można wprowadzić, to możliwość paginacji i dodanie następną stronę / poprzednią stronę w interfejsie użytkownika.

Aby zbudować zakładkę wydarzeń (stronę), najpierw wywołuję API wydarzeń i przetwarzam odpowiedź JSON na ramkę danych. Następnie sortuję i reorganizuję ramkę danych, aby umieścić znacznik czasu jako pierwszą kolumnę. W końcu buduję 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))
        ])
    ])
])

Co wygląda tak w interfejsie użytkownika.

Sparkpost event details

Następne kroki

Dla kogoś, kto chce stworzyć własny pulpit nawigacyjny lub dziennik zdarzeń, to dobry początek. Dzięki tej personalizacji, niebo jest limitem.

Jak wspomniano powyżej, niektóre przyszłe usprawnienia, 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 przy wyświetlaniu stron

  • Ulepszenia interfejsu użytkownika

  • Dodanie filtrowania i paginacji na stronie szczegółów zdarzeń

Byłbym zainteresowany usłyszeniem wszelkich opinii lub sugestii dotyczących rozszerzenia tego projektu.

~ Zach Samuels, Starszy inżynier ds. rozwiązań w Bird

Inne wiadomości

Przeczytaj więcej z tej kategorii

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

Kompletna platforma oparta na sztucznej inteligencji, która rośnie wraz z Twoim biznesem.

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

Kompletna platforma oparta na sztucznej inteligencji, która rośnie wraz z Twoim biznesem.