أداة لوحة المعلومات مع واجهات برمجة تطبيقات Bird
زاكاري صامويلز
24/03/2022
البريد الإلكتروني
1 min read

النقاط الرئيسية
يمكن دمج Bird APIs مع Python و Plotly Dash لإنشاء لوحات تفاعلية وقوية دون الحاجة إلى واجهة Bird الكاملة.
يظهر المشروع كيفية تخيل المقاييس والأحداث باستخدام Bird’s Metrics API و Events API داخل تطبيق ويب مخصص.
Plotly Dash يوفر إطار عمل مفتوح المصدر وسريعاً لإنشاء عناصر واجهة المستخدم مثل القوائم المنسدلة والرسوم البيانية والجداول.
يمكن للمطورين توسيع الأداة باستخدام تحليلات التسليم والتصفية والصفحة لإثراء لوحات التحكم.
تشمل التحسينات المستقبلية التخزين المؤقت وتحسين واجهة المستخدم وتكاملها مع منتجات Bird الأخرى أو APIs الخاصة بأطراف ثالثة.
يوفر الكود (المتوفر على GitHub) نقطة انطلاق قوية لأي شخص يرغب في بناء لوحات تحكم تعمل بBird أو بوابات موجهة للعملاء.
أبرز الأسئلة والأجوبة
ما هو الهدف من مشروع إعداد هذه اللوحة؟
يوضح كيف يمكن للمطورين استخدام Bird APIs مع Python وPlotly Dash لإنشاء لوحات معلومات تعتمد على البيانات تصور مقاييس الحملات والأحداث الأخيرة.
لماذا استخدام Plotly Dash لواجهات برمجة التطبيقات الخاصة بـ Bird؟
داش مفتوح المصدر، وسهل التخصيص، ومثالي لإنشاء واجهات مستخدم تفاعلية دون الحاجة إلى خبرة في الواجهة الأمامية.
ماذا يعرض لوحة التحكم؟
يقوم بعرض مقاييس السلسلة الزمنية من Bird’s Metrics API وبيانات الأحداث الأخيرة من Events API، مع خيارات لتصفية واختيار المقاييس عبر نطاقات زمنية مخصصة.
كيف يمكن توسيع الأداة بشكل أكبر؟
من خلال إضافة تحليلات قابلية التسليم، ومرشحات متقدمة، وتخزين مؤقت للبيانات، وتجزئة للبيانات الكبيرة لتحسين الأداء وسهولة الاستخدام.
ما هي المهارات أو الأدوات المطلوبة لتشغيله؟
معرفة أساسية ببايثون وتثبيت requests، dash، وpandas. يلزم مفتاح API من Bird لاستخراج البيانات.
كيف يتناسب هذا المشروع مع نظام Bird البيئي؟
يوضح كيفية استخدام واجهات برمجة التطبيقات المفتوحة لـ Bird لإنشاء لوحات تحكم مخصصة وأدوات تقرير للفرق أو العملاء الذين ليس لديهم وصول إلى المنصة الكاملة.
هذا النص يلامس السطح فقط لما هو ممكن باستخدام Python, Plotly Dash, وواجهات برمجة التطبيقات الخاصة بنا.
Bird Metrics API + إنشاء لوحات معلومات باستخدام Python
تقريباً منذ عام، كتب توم مايرز، مدير نجاح العملاء في Bird، أداة إرسال رسائل بريدية باستخدام واجهات برمجة تطبيقات Bird. في هذا المنشور، أبدأ من حيث توقف. تتيح أداته الانتقال المنظم للعمل، ولكن ماذا لو أردنا إنشاء لوحات المعلومات وسجلات الأحداث الخاصة بنا؟
ربما أريد إنشاء لوحة معلومات محددة لمجموعة عمل أو لوحة معلومات تواجه العملاء، ولكن دون توفير وصول كامل للمستخدمين إلى واجهة Bird. هذا النص البرمجي يلمس السطح فقط لما هو ممكن باستخدام Python، Plotly Dash، وواجهات برمجة تطبيقاتنا. عند بناء لوحات المعلومات التي تعالج بيانات واجهات برمجة التطبيقات ذات الحجم الكبير، كن واعيًا بأن مكونات البنية التحتية مثل DNS يمكن أن تصبح عنق الزجاجة - فقد واجهنا تحديات توسيع نطاق DNS في AWS التي أثرت على قدراتنا في معالجة البيانات. لعشاق سير العمل المرئي، يمكنك أيضًا استكشاف دمج Flow Builder مع Google Cloud Functions وVision API لإضافة الأتمتة المدعومة بالذكاء الاصطناعي إلى خطوط معالجة البيانات الخاصة بك.
عندما بدأت بحثي عبر الإنترنت، كنت أرغب في العثور على الطريق الأسرع. كان بإمكاني أنشئ جميع لوحات المعلومات وواجهة المستخدم بنفسي باستخدام HTML وPython، ولكن بعد بعض عمليات البحث في Google، وجدت Plotly’s Dash، الذي يتكامل بسهولة مع Python. اخترت Dash لسببين: 1) لأنه مفتوح المصدر، و2) بعد قراءة الوثائق، بدا سهل التخصيص لما كنت أحاول القيام به. Dash هو مكتبة مفتوحة المصدر مثالية لبناء ونشر التطبيقات البيانية بواجهات مستخدم مخصصة. هذا جعل إنشاء واجهة المستخدم بسيطًا للغاية. أصبح السؤال بعد ذلك، مدى تعقيد التطبيق الذي أريد إنشاؤه؟ كلما قضيت وقتًا أكثر، أردت إضافة المزيد من الميزات.
للمشروع الأولي، أردت التأكد من أن لدي لوحة معلومات تحتوي على قياسات قابلة للتخصيص وإطار زمني قابل للاختيار. في البداية، بدأت بلوحة معلومات حيث يمكنك اختيار مقياس واحد فقط من القائمة المنسدلة. ثم، عندما حصلت على ملاحظات من الزملاء، قمت بتحسين لوحة المعلومات قليلاً لإضافة اختيار متعدد وعناوين المحاور. كما قررت إضافة تبويب إضافي لسجل الأحداث. وصلت إلى نقطة كنت فيها راضياً عما لدي كنقطة انطلاق جيدة لأي شخص يرغب في بناء لوحاته الخاصة. للمطورين الذين يرغبون في تغذية لوحات معلوماتهم ببيانات Webhook في الوقت الفعلي، تحقق من دليلنا حول بناء مستهلكين Webhook باستخدام Azure Functions. بالطبع، وضعت المشروع في Github لتقوم بالاستنساخ أو إنشاء فرع منه.
Bird Metrics API + إنشاء لوحات معلومات باستخدام Python
تقريباً منذ عام، كتب توم مايرز، مدير نجاح العملاء في Bird، أداة إرسال رسائل بريدية باستخدام واجهات برمجة تطبيقات Bird. في هذا المنشور، أبدأ من حيث توقف. تتيح أداته الانتقال المنظم للعمل، ولكن ماذا لو أردنا إنشاء لوحات المعلومات وسجلات الأحداث الخاصة بنا؟
ربما أريد إنشاء لوحة معلومات محددة لمجموعة عمل أو لوحة معلومات تواجه العملاء، ولكن دون توفير وصول كامل للمستخدمين إلى واجهة Bird. هذا النص البرمجي يلمس السطح فقط لما هو ممكن باستخدام Python، Plotly Dash، وواجهات برمجة تطبيقاتنا. عند بناء لوحات المعلومات التي تعالج بيانات واجهات برمجة التطبيقات ذات الحجم الكبير، كن واعيًا بأن مكونات البنية التحتية مثل DNS يمكن أن تصبح عنق الزجاجة - فقد واجهنا تحديات توسيع نطاق DNS في AWS التي أثرت على قدراتنا في معالجة البيانات. لعشاق سير العمل المرئي، يمكنك أيضًا استكشاف دمج Flow Builder مع Google Cloud Functions وVision API لإضافة الأتمتة المدعومة بالذكاء الاصطناعي إلى خطوط معالجة البيانات الخاصة بك.
عندما بدأت بحثي عبر الإنترنت، كنت أرغب في العثور على الطريق الأسرع. كان بإمكاني أنشئ جميع لوحات المعلومات وواجهة المستخدم بنفسي باستخدام HTML وPython، ولكن بعد بعض عمليات البحث في Google، وجدت Plotly’s Dash، الذي يتكامل بسهولة مع Python. اخترت Dash لسببين: 1) لأنه مفتوح المصدر، و2) بعد قراءة الوثائق، بدا سهل التخصيص لما كنت أحاول القيام به. Dash هو مكتبة مفتوحة المصدر مثالية لبناء ونشر التطبيقات البيانية بواجهات مستخدم مخصصة. هذا جعل إنشاء واجهة المستخدم بسيطًا للغاية. أصبح السؤال بعد ذلك، مدى تعقيد التطبيق الذي أريد إنشاؤه؟ كلما قضيت وقتًا أكثر، أردت إضافة المزيد من الميزات.
للمشروع الأولي، أردت التأكد من أن لدي لوحة معلومات تحتوي على قياسات قابلة للتخصيص وإطار زمني قابل للاختيار. في البداية، بدأت بلوحة معلومات حيث يمكنك اختيار مقياس واحد فقط من القائمة المنسدلة. ثم، عندما حصلت على ملاحظات من الزملاء، قمت بتحسين لوحة المعلومات قليلاً لإضافة اختيار متعدد وعناوين المحاور. كما قررت إضافة تبويب إضافي لسجل الأحداث. وصلت إلى نقطة كنت فيها راضياً عما لدي كنقطة انطلاق جيدة لأي شخص يرغب في بناء لوحاته الخاصة. للمطورين الذين يرغبون في تغذية لوحات معلوماتهم ببيانات Webhook في الوقت الفعلي، تحقق من دليلنا حول بناء مستهلكين Webhook باستخدام Azure Functions. بالطبع، وضعت المشروع في Github لتقوم بالاستنساخ أو إنشاء فرع منه.
Bird Metrics API + إنشاء لوحات معلومات باستخدام Python
تقريباً منذ عام، كتب توم مايرز، مدير نجاح العملاء في Bird، أداة إرسال رسائل بريدية باستخدام واجهات برمجة تطبيقات Bird. في هذا المنشور، أبدأ من حيث توقف. تتيح أداته الانتقال المنظم للعمل، ولكن ماذا لو أردنا إنشاء لوحات المعلومات وسجلات الأحداث الخاصة بنا؟
ربما أريد إنشاء لوحة معلومات محددة لمجموعة عمل أو لوحة معلومات تواجه العملاء، ولكن دون توفير وصول كامل للمستخدمين إلى واجهة Bird. هذا النص البرمجي يلمس السطح فقط لما هو ممكن باستخدام Python، Plotly Dash، وواجهات برمجة تطبيقاتنا. عند بناء لوحات المعلومات التي تعالج بيانات واجهات برمجة التطبيقات ذات الحجم الكبير، كن واعيًا بأن مكونات البنية التحتية مثل DNS يمكن أن تصبح عنق الزجاجة - فقد واجهنا تحديات توسيع نطاق DNS في AWS التي أثرت على قدراتنا في معالجة البيانات. لعشاق سير العمل المرئي، يمكنك أيضًا استكشاف دمج Flow Builder مع Google Cloud Functions وVision API لإضافة الأتمتة المدعومة بالذكاء الاصطناعي إلى خطوط معالجة البيانات الخاصة بك.
عندما بدأت بحثي عبر الإنترنت، كنت أرغب في العثور على الطريق الأسرع. كان بإمكاني أنشئ جميع لوحات المعلومات وواجهة المستخدم بنفسي باستخدام HTML وPython، ولكن بعد بعض عمليات البحث في Google، وجدت Plotly’s Dash، الذي يتكامل بسهولة مع Python. اخترت Dash لسببين: 1) لأنه مفتوح المصدر، و2) بعد قراءة الوثائق، بدا سهل التخصيص لما كنت أحاول القيام به. Dash هو مكتبة مفتوحة المصدر مثالية لبناء ونشر التطبيقات البيانية بواجهات مستخدم مخصصة. هذا جعل إنشاء واجهة المستخدم بسيطًا للغاية. أصبح السؤال بعد ذلك، مدى تعقيد التطبيق الذي أريد إنشاؤه؟ كلما قضيت وقتًا أكثر، أردت إضافة المزيد من الميزات.
للمشروع الأولي، أردت التأكد من أن لدي لوحة معلومات تحتوي على قياسات قابلة للتخصيص وإطار زمني قابل للاختيار. في البداية، بدأت بلوحة معلومات حيث يمكنك اختيار مقياس واحد فقط من القائمة المنسدلة. ثم، عندما حصلت على ملاحظات من الزملاء، قمت بتحسين لوحة المعلومات قليلاً لإضافة اختيار متعدد وعناوين المحاور. كما قررت إضافة تبويب إضافي لسجل الأحداث. وصلت إلى نقطة كنت فيها راضياً عما لدي كنقطة انطلاق جيدة لأي شخص يرغب في بناء لوحاته الخاصة. للمطورين الذين يرغبون في تغذية لوحات معلوماتهم ببيانات Webhook في الوقت الفعلي، تحقق من دليلنا حول بناء مستهلكين Webhook باستخدام Azure Functions. بالطبع، وضعت المشروع في Github لتقوم بالاستنساخ أو إنشاء فرع منه.
البدء
للوصول إلى هذا التطبيق، ستحتاج إلى التأكد من أنك تستخدم Python 3.10 أو أعلى وتثبيت المكتبات التالية:
مكتبة Python | الغرض |
|---|---|
requests | التواصل مع خدمات Bird عبر API |
dash | عرض واجهة المستخدم ولوحة التحكم |
pandas | معالجة البيانات وإنشاء الجداول |
ثم قم بإدخال مفتاح API الخاص بك في App.py وتشغيل التطبيق. سيعمل على http://localhost:8050. لمزيد من المعلومات حول نشر هذا على خادم عام (مثل AWS)، راجع الموارد التالية:
للوصول إلى هذا التطبيق، ستحتاج إلى التأكد من أنك تستخدم Python 3.10 أو أعلى وتثبيت المكتبات التالية:
مكتبة Python | الغرض |
|---|---|
requests | التواصل مع خدمات Bird عبر API |
dash | عرض واجهة المستخدم ولوحة التحكم |
pandas | معالجة البيانات وإنشاء الجداول |
ثم قم بإدخال مفتاح API الخاص بك في App.py وتشغيل التطبيق. سيعمل على http://localhost:8050. لمزيد من المعلومات حول نشر هذا على خادم عام (مثل AWS)، راجع الموارد التالية:
للوصول إلى هذا التطبيق، ستحتاج إلى التأكد من أنك تستخدم Python 3.10 أو أعلى وتثبيت المكتبات التالية:
مكتبة Python | الغرض |
|---|---|
requests | التواصل مع خدمات Bird عبر API |
dash | عرض واجهة المستخدم ولوحة التحكم |
pandas | معالجة البيانات وإنشاء الجداول |
ثم قم بإدخال مفتاح API الخاص بك في App.py وتشغيل التطبيق. سيعمل على http://localhost:8050. لمزيد من المعلومات حول نشر هذا على خادم عام (مثل AWS)، راجع الموارد التالية:
إنشاء صفحة لوحة التحكم
أولاً، قم بتهيئة إطار البيانات ولوحة المعلومات. بدون تهيئة لوحة المعلومات، لن تظهر أي لوحة معلومات في واجهة المستخدم.
df = pd.DataFrame({ "Count": [0, 0], "Time": [0, 0] }) fig = px.line(df, x="Time", y="Count")
ثم، قم ببناء علامة التبويب الأولى. هذا مزيج من استدعاء تطبيق (للتحقق من علامة التبويب التي يتم استخدامها)؛ مع وظيفة شرطية للتحقق من علامة التبويب المختارة حاليًا. الكود أدناه يبني فقط لوحة المعلومات الفارغة وعناصر واجهة المستخدم (سننتقل إلى علامة تبويب الأحداث لاحقًا). دلالات dcc هي مكونات Dash الأساسية
و< a id="6">مكونات HTML< و> تسمح بسهولة باستخدام HTML في واجهة المستخدم.
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)
لاحظ أنه مع Dash، من السهل إنشاء واجهة مستخدم لوحة معلومات مع قائمة منسدلة متعددة التحديد ويمكن البحث فيها. لتعطيل التحديد المتعدد أو البحث، يمكن تعديل المعلمات لإنشاء قائمة منسدلة بسهولة. وجدت أن الجزء الأكثر تعقيدًا في هذا المشروع كان بناء إطار البيانات الفعلي من المدخلات وكذلك الحصول على HTML + CSS للعمل بشكل صحيح في واجهة المستخدم.
يسمح Time Series Metrics API بسحب 33 مؤشرات فردية بناءً على نطاق التاريخ/الوقت. يمكنك التصفية بعمق حسب النطاقات، والحملات، ومجمعات IP، والنطاقات المرسلة، والحسابات الفرعية، وتحديد دقة بيانات السلاسل الزمنية. يمكن أن تكون هذه المرشحات الإضافية مع تحليلات القابلة للتوصيل تحسينًا مستقبليًا لهذا المشروع (ستحتاج إلى تنفيذ مسك الأخطاء للعملاء الذين ليس لديهم وصول إلى تحليلات قابلية التوصيل).
باستخدام واستدعاء Metrics API، أقوم ببناء لوحة معلومات مع المعلمات المختارة للمستخدم والإطار الزمني المحدد. ثم يتم تحديث لوحة المعلومات..
عرض لوحة المعلومات (Time Series Metrics API)
# 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
المثال التالي يوضح اختيار مقاييس متعددة وإطار زمني واسع.

ملاحظة: هناك العديد من العناصر المدمجة في الرسم البياني داخل Dash تلقائيًا (مثل التحويم، التكبير، التقليب التلقائي).
أولاً، قم بتهيئة إطار البيانات ولوحة المعلومات. بدون تهيئة لوحة المعلومات، لن تظهر أي لوحة معلومات في واجهة المستخدم.
df = pd.DataFrame({ "Count": [0, 0], "Time": [0, 0] }) fig = px.line(df, x="Time", y="Count")
ثم، قم ببناء علامة التبويب الأولى. هذا مزيج من استدعاء تطبيق (للتحقق من علامة التبويب التي يتم استخدامها)؛ مع وظيفة شرطية للتحقق من علامة التبويب المختارة حاليًا. الكود أدناه يبني فقط لوحة المعلومات الفارغة وعناصر واجهة المستخدم (سننتقل إلى علامة تبويب الأحداث لاحقًا). دلالات dcc هي مكونات Dash الأساسية
و< a id="6">مكونات HTML< و> تسمح بسهولة باستخدام HTML في واجهة المستخدم.
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)
لاحظ أنه مع Dash، من السهل إنشاء واجهة مستخدم لوحة معلومات مع قائمة منسدلة متعددة التحديد ويمكن البحث فيها. لتعطيل التحديد المتعدد أو البحث، يمكن تعديل المعلمات لإنشاء قائمة منسدلة بسهولة. وجدت أن الجزء الأكثر تعقيدًا في هذا المشروع كان بناء إطار البيانات الفعلي من المدخلات وكذلك الحصول على HTML + CSS للعمل بشكل صحيح في واجهة المستخدم.
يسمح Time Series Metrics API بسحب 33 مؤشرات فردية بناءً على نطاق التاريخ/الوقت. يمكنك التصفية بعمق حسب النطاقات، والحملات، ومجمعات IP، والنطاقات المرسلة، والحسابات الفرعية، وتحديد دقة بيانات السلاسل الزمنية. يمكن أن تكون هذه المرشحات الإضافية مع تحليلات القابلة للتوصيل تحسينًا مستقبليًا لهذا المشروع (ستحتاج إلى تنفيذ مسك الأخطاء للعملاء الذين ليس لديهم وصول إلى تحليلات قابلية التوصيل).
باستخدام واستدعاء Metrics API، أقوم ببناء لوحة معلومات مع المعلمات المختارة للمستخدم والإطار الزمني المحدد. ثم يتم تحديث لوحة المعلومات..
عرض لوحة المعلومات (Time Series Metrics API)
# 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
المثال التالي يوضح اختيار مقاييس متعددة وإطار زمني واسع.

ملاحظة: هناك العديد من العناصر المدمجة في الرسم البياني داخل Dash تلقائيًا (مثل التحويم، التكبير، التقليب التلقائي).
أولاً، قم بتهيئة إطار البيانات ولوحة المعلومات. بدون تهيئة لوحة المعلومات، لن تظهر أي لوحة معلومات في واجهة المستخدم.
df = pd.DataFrame({ "Count": [0, 0], "Time": [0, 0] }) fig = px.line(df, x="Time", y="Count")
ثم، قم ببناء علامة التبويب الأولى. هذا مزيج من استدعاء تطبيق (للتحقق من علامة التبويب التي يتم استخدامها)؛ مع وظيفة شرطية للتحقق من علامة التبويب المختارة حاليًا. الكود أدناه يبني فقط لوحة المعلومات الفارغة وعناصر واجهة المستخدم (سننتقل إلى علامة تبويب الأحداث لاحقًا). دلالات dcc هي مكونات Dash الأساسية
و< a id="6">مكونات HTML< و> تسمح بسهولة باستخدام HTML في واجهة المستخدم.
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)
لاحظ أنه مع Dash، من السهل إنشاء واجهة مستخدم لوحة معلومات مع قائمة منسدلة متعددة التحديد ويمكن البحث فيها. لتعطيل التحديد المتعدد أو البحث، يمكن تعديل المعلمات لإنشاء قائمة منسدلة بسهولة. وجدت أن الجزء الأكثر تعقيدًا في هذا المشروع كان بناء إطار البيانات الفعلي من المدخلات وكذلك الحصول على HTML + CSS للعمل بشكل صحيح في واجهة المستخدم.
يسمح Time Series Metrics API بسحب 33 مؤشرات فردية بناءً على نطاق التاريخ/الوقت. يمكنك التصفية بعمق حسب النطاقات، والحملات، ومجمعات IP، والنطاقات المرسلة، والحسابات الفرعية، وتحديد دقة بيانات السلاسل الزمنية. يمكن أن تكون هذه المرشحات الإضافية مع تحليلات القابلة للتوصيل تحسينًا مستقبليًا لهذا المشروع (ستحتاج إلى تنفيذ مسك الأخطاء للعملاء الذين ليس لديهم وصول إلى تحليلات قابلية التوصيل).
باستخدام واستدعاء Metrics API، أقوم ببناء لوحة معلومات مع المعلمات المختارة للمستخدم والإطار الزمني المحدد. ثم يتم تحديث لوحة المعلومات..
عرض لوحة المعلومات (Time Series Metrics API)
# 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
المثال التالي يوضح اختيار مقاييس متعددة وإطار زمني واسع.

ملاحظة: هناك العديد من العناصر المدمجة في الرسم البياني داخل Dash تلقائيًا (مثل التحويم، التكبير، التقليب التلقائي).
إنشاء صفحة تفاصيل الحدث
كانت صفحة تفاصيل الحدث أكثر صعوبة لأنني لم أكن أعرف أفضل طريقة لعرض جميع مقاييس الأحداث بطريقة سهلة للقراءة. فكرت في إضافة معلمات فلترة لهذه الصفحة، لكنني قررت أن ذلك سيضيف وقتًا كبيرًا لهذا المشروع حيث أن الجدول سيحتاج إلى أن يكون ديناميكيًا (جنبًا إلى جنب مع إضافة المعلمات، والاستدعاءات، إلخ.). قررت عرض جميع الأحداث ووضع الطابع الزمني أولاً (كما أن بدون وضع الطابع الزمني أولاً، لم يكن الرسم البياني سهلاً للقراءة). في البداية، وجدت أن الجدول كان صعبًا للغاية على العيون باستخدام HTML الخام فقط. لم تكن هناك حدود ولا اختلافات في اللون بين الرأس والصفوف. لتسهيل قراءة الجدول، تمكنت من استخدام CSS داخل Dash.
عرض تفاصيل الحدث (API الأحداث)
الفكرة لتفاصيل الحدث تكاد تكون نفس فكرة لوحة التحكم، باستثناء هذه المرة، أقوم بتنفيذ API الأحداث وجلب جميع الأحداث. لاحظ أن تفاصيل الحدث تظهر فقط أحدث 10 أحداث (باستخدام معلمة max_rows وفلترة API). يمكن زيادة هذا العدد، لكنني قررت عرض أحدث 10 أحداث لأن كلما زاد عرض الأحداث، زادت مدة استدعاء API. يمكن إجراء تحسين هام وهو القدرة على تقسيم الصفحات وإدراج صفحة تالية / صفحة سابقة في واجهة المستخدم.
لبناء علامة الأحداث (الصفحة)، أولاً، أدعو API الأحداث وأحول استجابة JSON إلى إطار بيانات. ثم أقوم بترتيب وإعادة ترتيب إطار البيانات لوضع الطابع الزمني كأول عمود. أخيرًا، أقوم ببناء جدول HTML عن طريق التكرار عبر إطار البيانات.
# 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)) ]) ]) ])
الذي يبدو هكذا في واجهة المستخدم.

كانت صفحة تفاصيل الحدث أكثر صعوبة لأنني لم أكن أعرف أفضل طريقة لعرض جميع مقاييس الأحداث بطريقة سهلة للقراءة. فكرت في إضافة معلمات فلترة لهذه الصفحة، لكنني قررت أن ذلك سيضيف وقتًا كبيرًا لهذا المشروع حيث أن الجدول سيحتاج إلى أن يكون ديناميكيًا (جنبًا إلى جنب مع إضافة المعلمات، والاستدعاءات، إلخ.). قررت عرض جميع الأحداث ووضع الطابع الزمني أولاً (كما أن بدون وضع الطابع الزمني أولاً، لم يكن الرسم البياني سهلاً للقراءة). في البداية، وجدت أن الجدول كان صعبًا للغاية على العيون باستخدام HTML الخام فقط. لم تكن هناك حدود ولا اختلافات في اللون بين الرأس والصفوف. لتسهيل قراءة الجدول، تمكنت من استخدام CSS داخل Dash.
عرض تفاصيل الحدث (API الأحداث)
الفكرة لتفاصيل الحدث تكاد تكون نفس فكرة لوحة التحكم، باستثناء هذه المرة، أقوم بتنفيذ API الأحداث وجلب جميع الأحداث. لاحظ أن تفاصيل الحدث تظهر فقط أحدث 10 أحداث (باستخدام معلمة max_rows وفلترة API). يمكن زيادة هذا العدد، لكنني قررت عرض أحدث 10 أحداث لأن كلما زاد عرض الأحداث، زادت مدة استدعاء API. يمكن إجراء تحسين هام وهو القدرة على تقسيم الصفحات وإدراج صفحة تالية / صفحة سابقة في واجهة المستخدم.
لبناء علامة الأحداث (الصفحة)، أولاً، أدعو API الأحداث وأحول استجابة JSON إلى إطار بيانات. ثم أقوم بترتيب وإعادة ترتيب إطار البيانات لوضع الطابع الزمني كأول عمود. أخيرًا، أقوم ببناء جدول HTML عن طريق التكرار عبر إطار البيانات.
# 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)) ]) ]) ])
الذي يبدو هكذا في واجهة المستخدم.

كانت صفحة تفاصيل الحدث أكثر صعوبة لأنني لم أكن أعرف أفضل طريقة لعرض جميع مقاييس الأحداث بطريقة سهلة للقراءة. فكرت في إضافة معلمات فلترة لهذه الصفحة، لكنني قررت أن ذلك سيضيف وقتًا كبيرًا لهذا المشروع حيث أن الجدول سيحتاج إلى أن يكون ديناميكيًا (جنبًا إلى جنب مع إضافة المعلمات، والاستدعاءات، إلخ.). قررت عرض جميع الأحداث ووضع الطابع الزمني أولاً (كما أن بدون وضع الطابع الزمني أولاً، لم يكن الرسم البياني سهلاً للقراءة). في البداية، وجدت أن الجدول كان صعبًا للغاية على العيون باستخدام HTML الخام فقط. لم تكن هناك حدود ولا اختلافات في اللون بين الرأس والصفوف. لتسهيل قراءة الجدول، تمكنت من استخدام CSS داخل Dash.
عرض تفاصيل الحدث (API الأحداث)
الفكرة لتفاصيل الحدث تكاد تكون نفس فكرة لوحة التحكم، باستثناء هذه المرة، أقوم بتنفيذ API الأحداث وجلب جميع الأحداث. لاحظ أن تفاصيل الحدث تظهر فقط أحدث 10 أحداث (باستخدام معلمة max_rows وفلترة API). يمكن زيادة هذا العدد، لكنني قررت عرض أحدث 10 أحداث لأن كلما زاد عرض الأحداث، زادت مدة استدعاء API. يمكن إجراء تحسين هام وهو القدرة على تقسيم الصفحات وإدراج صفحة تالية / صفحة سابقة في واجهة المستخدم.
لبناء علامة الأحداث (الصفحة)، أولاً، أدعو API الأحداث وأحول استجابة JSON إلى إطار بيانات. ثم أقوم بترتيب وإعادة ترتيب إطار البيانات لوضع الطابع الزمني كأول عمود. أخيرًا، أقوم ببناء جدول HTML عن طريق التكرار عبر إطار البيانات.
# 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)) ]) ]) ])
الذي يبدو هكذا في واجهة المستخدم.

الخطوات التالية
بالنسبة لشخص مهتم بإنشاء لوحة تحكم أو سجل أحداث خاص به، فهذا يُعتبر بداية جيدة. مع قابلية التخصيص هنا، السماء هي الحد.
كما نوقش أعلاه، بعض التحسينات المستقبلية التي يمكن القيام بها هي:
إضافة تحليلات التسليم إلى لوحة التحكم
إضافة المزيد من الفلاتر إلى لوحة التحكم
خيارات التخزين المؤقت الممكنة بحيث لا يتم استدعاء API في كل مرة لعرض الصفحات
تحسينات واجهة المستخدم
إضافة التصفية ورقم الصفحة إلى صفحة تفاصيل الأحداث
أود سماع أي تعليقات أو اقتراحات لتوسيع هذا المشروع.
~ زاك صامويلز، مهندس حلول أول في Bird
بالنسبة لشخص مهتم بإنشاء لوحة تحكم أو سجل أحداث خاص به، فهذا يُعتبر بداية جيدة. مع قابلية التخصيص هنا، السماء هي الحد.
كما نوقش أعلاه، بعض التحسينات المستقبلية التي يمكن القيام بها هي:
إضافة تحليلات التسليم إلى لوحة التحكم
إضافة المزيد من الفلاتر إلى لوحة التحكم
خيارات التخزين المؤقت الممكنة بحيث لا يتم استدعاء API في كل مرة لعرض الصفحات
تحسينات واجهة المستخدم
إضافة التصفية ورقم الصفحة إلى صفحة تفاصيل الأحداث
أود سماع أي تعليقات أو اقتراحات لتوسيع هذا المشروع.
~ زاك صامويلز، مهندس حلول أول في Bird
بالنسبة لشخص مهتم بإنشاء لوحة تحكم أو سجل أحداث خاص به، فهذا يُعتبر بداية جيدة. مع قابلية التخصيص هنا، السماء هي الحد.
كما نوقش أعلاه، بعض التحسينات المستقبلية التي يمكن القيام بها هي:
إضافة تحليلات التسليم إلى لوحة التحكم
إضافة المزيد من الفلاتر إلى لوحة التحكم
خيارات التخزين المؤقت الممكنة بحيث لا يتم استدعاء API في كل مرة لعرض الصفحات
تحسينات واجهة المستخدم
إضافة التصفية ورقم الصفحة إلى صفحة تفاصيل الأحداث
أود سماع أي تعليقات أو اقتراحات لتوسيع هذا المشروع.
~ زاك صامويلز، مهندس حلول أول في Bird



