أداة لوحة المعلومات مع واجهات برمجة تطبيقات Bird

زاكاري صامويلز

24‏/03‏/2022

البريد الإلكتروني

1 min read

أداة لوحة المعلومات مع واجهات برمجة تطبيقات Bird

زاكاري صامويلز

24‏/03‏/2022

البريد الإلكتروني

1 min read

أداة لوحة المعلومات مع واجهات برمجة تطبيقات Bird

هذا النص يلامس السطح فقط لما هو ممكن باستخدام Python, Plotly Dash, وواجهات برمجة التطبيقات الخاصة بنا.

منذ ما يقرب من عام، كتب توم ماييرز، مدير نجاح العملاء في Bird، أداة مرسِل باستخدام واجهات برمجة التطبيقات من Bird. في هذه المقالة، أتابع من حيث توقف. تسمح أداة ماييرز بإرسال الوظائف في وقت محدد، ولكن ماذا لو أردنا إنشاء لوحات بيانات وسجلات أحداث خاصة بنا؟




ربما أرغب في إنشاء لوحة بيانات محددة لمجموعة تجارية أو لوحة بيانات للعميل، ولكن دون منح المستخدمين وصولاً كاملاً إلى واجهة مستخدم Bird. هذه الأداة فقط تلمس سطح المستطاع باستخدام Python، وPlotly Dash، وواجهات برمجية خاصة بنا.




عندما بدأت بحثي عبر الإنترنت، أردت العثور على المسار الذي يواجه أقل مقاومة. كان بإمكاني إنشاء جميع لوحات البيانات وواجهة المستخدم بنفسي باستخدام HTML وPython، ولكن بعد بعض البحث في جوجل، اكتشفت Plotly’s Dash، الذي يتكامل بسهولة مع Python. اخترت Dash لسببين: 1) هو مفتوح المصدر، و2) بعد قراءة الوثائق بدا لي قابلاً للتخصيص بسهولة لما كنت أحاول أن أفعله. Dash هو مكتبة مفتوحة المصدر مثالية لإنشاء ونشر تطبيقات البيانات بواجهات مستخدم مخصصة. هذا جعل إنشاء واجهة المستخدم بسيطة للغاية. ثم أصبح السؤال، ما مدى تعقيد التطبيق الذي أرغب في إنشائه؟ كلما قضيت وقتًا أطول، كلما رغبت في إضافة المزيد من الميزات.




للمشروع الأولي، أردت التأكد من أن لدي لوحة بيانات مع مقاييس قابلة للتخصيص وإطار زمني قابل للتحديد. في البداية، بدأت بلائحة بيانات حيث يمكنك اختيار مقياس واحد فقط من القائمة المنسدلة. ثم، مع تلقي الملاحظات من الزملاء، قمت بتحسين اللوحة قليلاً لإضافة اختيار متعدد وعناوين المحاور. قررت أيضًا إضافة تبويب إضافي لسجل الأحداث. وصلت إلى نقطة كنت راضيًا فيها عما لدي كنقطة انطلاق جيدة لأي شخص يرغب في بناء لوحاته الخاصة. بالطبع، وضعت المشروع على Github لتتمكن من الاستنساخ أو الإنشاء على فرعه.

البدء

للوصول إلى هذا التطبيق، ستحتاج إلى التأكد من أنك تستخدم بايثون 3.10 أو إصدار أعلى وتثبيت المكتبات التالية:

  • requests

  • 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 هي مكونات كور داش الأساسية وعناصر HTML تسمح بسهولة استخدام HTML في واجهة المستخدم.




html.H2('لوحة التحكم التحليلية'),

#قائمة منسدلة متعددة الاختيار

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="اختر المقاييس"),

#منتقي التواريخ (أقصى تاريخ مسموح يتم تحديده كتاريخ اليوم) 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), ),

#جسم الرسم dcc.Graph( id='Emails', figure=fig )




لاحظ مع Dash مدى سهولة إنشاء واجهة المستخدم الخاصة بلوحة القيادة مع قائمة منسدلة متعددة الاختيار وقابلة للبحث. لتعطيل الاختيار المتعدد أو البحث، يمكن تعديل المعلمات لإنشاء قائمة منسدلة بسهولة. لقد وجدت أن الجزء الأكثر تعقيدًا في هذا المشروع كان إنشاء إطار البيانات الفعلي من المدخلات، بالإضافة إلى جعل HTML + CSS يعملان بشكل صحيح في واجهة المستخدم.




يسمح API لمقاييس السلسلة الزمنية بسحب 33 مقياسًا فرديًا بناءً على مدى زمني. يمكنك التصفية بشكل أعمق بمساعدة النطاق، الحملات، تجمعات IP، مجالات الإرسال، الحسابات الفرعية، وتحديد دقة بيانات السلسلة الزمنية. هذه الفلاتر الإضافية مع تحليلات القابلية للإيصال يمكن أن تكون تحسينًا مستقبليًا لهذا المشروع (ستحتاج الأخطاء إلى أن يتم التعامل معها للعملاء الذين ليس لديهم إمكانية الوصول إلى تحليلات القابلية للإيصال).




باستخدام ودعوة API للمقاييس، قمت ببناء لوحة معلومات مع المعلمات المحددة من قبل المستخدم والإطار الزمني المحدد. يتم تحديث لوحة التحكم المنشأة بعد ذلك.




#بناء استدعاء API باستخدام المعلمات المقدمة 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(",") #بناء لوحة قيادة جديدة باستخدام المقاييس والتواريخ الجديدة من استدعاء API المحدث 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 هي مكونات كور داش الأساسية وعناصر HTML تسمح بسهولة استخدام HTML في واجهة المستخدم.




html.H2('لوحة التحكم التحليلية'),

#قائمة منسدلة متعددة الاختيار

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="اختر المقاييس"),

#منتقي التواريخ (أقصى تاريخ مسموح يتم تحديده كتاريخ اليوم) 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), ),

#جسم الرسم dcc.Graph( id='Emails', figure=fig )




لاحظ مع Dash مدى سهولة إنشاء واجهة المستخدم الخاصة بلوحة القيادة مع قائمة منسدلة متعددة الاختيار وقابلة للبحث. لتعطيل الاختيار المتعدد أو البحث، يمكن تعديل المعلمات لإنشاء قائمة منسدلة بسهولة. لقد وجدت أن الجزء الأكثر تعقيدًا في هذا المشروع كان إنشاء إطار البيانات الفعلي من المدخلات، بالإضافة إلى جعل HTML + CSS يعملان بشكل صحيح في واجهة المستخدم.




يسمح API لمقاييس السلسلة الزمنية بسحب 33 مقياسًا فرديًا بناءً على مدى زمني. يمكنك التصفية بشكل أعمق بمساعدة النطاق، الحملات، تجمعات IP، مجالات الإرسال، الحسابات الفرعية، وتحديد دقة بيانات السلسلة الزمنية. هذه الفلاتر الإضافية مع تحليلات القابلية للإيصال يمكن أن تكون تحسينًا مستقبليًا لهذا المشروع (ستحتاج الأخطاء إلى أن يتم التعامل معها للعملاء الذين ليس لديهم إمكانية الوصول إلى تحليلات القابلية للإيصال).




باستخدام ودعوة API للمقاييس، قمت ببناء لوحة معلومات مع المعلمات المحددة من قبل المستخدم والإطار الزمني المحدد. يتم تحديث لوحة التحكم المنشأة بعد ذلك.




#بناء استدعاء API باستخدام المعلمات المقدمة 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(",") #بناء لوحة قيادة جديدة باستخدام المقاييس والتواريخ الجديدة من استدعاء API المحدث 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 هي مكونات كور داش الأساسية وعناصر HTML تسمح بسهولة استخدام HTML في واجهة المستخدم.




html.H2('لوحة التحكم التحليلية'),

#قائمة منسدلة متعددة الاختيار

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="اختر المقاييس"),

#منتقي التواريخ (أقصى تاريخ مسموح يتم تحديده كتاريخ اليوم) 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), ),

#جسم الرسم dcc.Graph( id='Emails', figure=fig )




لاحظ مع Dash مدى سهولة إنشاء واجهة المستخدم الخاصة بلوحة القيادة مع قائمة منسدلة متعددة الاختيار وقابلة للبحث. لتعطيل الاختيار المتعدد أو البحث، يمكن تعديل المعلمات لإنشاء قائمة منسدلة بسهولة. لقد وجدت أن الجزء الأكثر تعقيدًا في هذا المشروع كان إنشاء إطار البيانات الفعلي من المدخلات، بالإضافة إلى جعل HTML + CSS يعملان بشكل صحيح في واجهة المستخدم.




يسمح API لمقاييس السلسلة الزمنية بسحب 33 مقياسًا فرديًا بناءً على مدى زمني. يمكنك التصفية بشكل أعمق بمساعدة النطاق، الحملات، تجمعات IP، مجالات الإرسال، الحسابات الفرعية، وتحديد دقة بيانات السلسلة الزمنية. هذه الفلاتر الإضافية مع تحليلات القابلية للإيصال يمكن أن تكون تحسينًا مستقبليًا لهذا المشروع (ستحتاج الأخطاء إلى أن يتم التعامل معها للعملاء الذين ليس لديهم إمكانية الوصول إلى تحليلات القابلية للإيصال).




باستخدام ودعوة API للمقاييس، قمت ببناء لوحة معلومات مع المعلمات المحددة من قبل المستخدم والإطار الزمني المحدد. يتم تحديث لوحة التحكم المنشأة بعد ذلك.




#بناء استدعاء API باستخدام المعلمات المقدمة 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(",") #بناء لوحة قيادة جديدة باستخدام المقاييس والتواريخ الجديدة من استدعاء API المحدث 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.




فكرة تفاصيل الحدث تشبه تقريبًا لوحة المعلومات، باستثناء هذه المرة، أقوم باستدعاء Events API وجلب جميع الأحداث. لاحظ أن تفاصيل الحدث تعرض فقط أحدث 10 أحداث (باستخدام معايير max_rows وتصفيه API). يمكن زيادة هذا، لكنني استقريت على عرض أحدث 10 أحداث لأنه كلما زادت الأحداث الظاهرة، زاد الوقت الذي يستغرقه استدعاء API. سيكون هناك تحسن كبير يتمثل في القدرة على تقسيم الصفحات والاختيار بين الصفحة التالية والسابقة في واجهة المستخدم.




لبناء علامة أحداث (صفحة)، أولاً، أقوم باستدعاء Events API وتحليل استجابة JSON إلى إطار بيانات. ثم أقوم بفرز وإعادة ترتيب إطار البيانات لوضع الطابع الزمني كأول عمود. أخيرًا، أقوم ببناء الجدول HTML من خلال التجوال عبر إطار البيانات.




#بناء استدعاء لـ 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 = BASE_URL + "/events/message" 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']) max_rows=10 #الحد الأقصى لعدد النتائج المعروضة في جدول الأحداث #وضع الطابع الزمني كأول عمود في الجدول 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]] #عرض HTML الجديد مع جدول الأحداث (لاحظ، هذا الجدول يرجع إلى table.css أيضًا) return html.Div([ html.H2("تفاصيل الحدث"), 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

دعنا نوصلك بخبير من Bird.
رؤية القوة الكاملة لـ Bird في 30 دقيقة.

بتقديمك طلبًا، فإنك توافق على أن تقوم Bird بالاتصال بك بشأن منتجاتنا وخدماتنا.

يمكنك إلغاء الاشتراك في أي وقت. انظر بيان الخصوصية الخاص بـ Bird للتفاصيل حول معالجة البيانات.

دعنا نوصلك بخبير من Bird.
رؤية القوة الكاملة لـ Bird في 30 دقيقة.

بتقديمك طلبًا، فإنك توافق على أن تقوم Bird بالاتصال بك بشأن منتجاتنا وخدماتنا.

يمكنك إلغاء الاشتراك في أي وقت. انظر بيان الخصوصية الخاص بـ Bird للتفاصيل حول معالجة البيانات.

دعنا نوصلك بخبير من Bird.
رؤية القوة الكاملة لـ Bird في 30 دقيقة.

بتقديمك طلبًا، فإنك توافق على أن تقوم Bird بالاتصال بك بشأن منتجاتنا وخدماتنا.

يمكنك إلغاء الاشتراك في أي وقت. انظر بيان الخصوصية الخاص بـ Bird للتفاصيل حول معالجة البيانات.

R

وصول

G

نمو

م

إدارة

A

أتمتة

النشرة الإخبارية

ابقَ على اطلاع مع Bird من خلال التحديثات الأسبوعية إلى بريدك الوارد.