
هذا النص يلامس السطح فقط لما هو ممكن باستخدام Python, Plotly Dash, وواجهات برمجة التطبيقات الخاصة بنا.
قبل حوالي عام، كتب توم ميرز، مدير نجاح العملاء في Bird، أداة مراسلة باستخدام واجهات برمجة التطبيقات (APIs) الخاصة بـ Bird. في هذه المقالة، ألتقط الأمر من حيث تركه. تسمح أداته بالنقل الزمني للوظائف، ولكن ماذا لو أردنا إنشاء لوحات معلومات خاصة بنا وسجلات أحداث؟
ربما أرغب في إنشاء لوحة معلومات مخصصة لمجموعة أعمال أو لوحة معلومات مواجهة للعملاء، ولكن دون توفير وصول كامل للمستخدمين إلى واجهة مستخدم Bird. هذا النص البرمجي يلمس فقط السطح لما هو ممكن باستخدام Python، Plotly Dash، وAPIs الخاصة بنا. عند بناء لوحات معلومات تعالج بيانات API ذات حجم كبير، كن واعيًا بأن المكونات التحتية مثل DNS يمكن أن تصبح مراكز اختناق - لقد عانينا من تحديات توسيع نطاق DNS لـ AWS أثرت على قدرات معالجة البيانات لدينا. لمحبي سير العمل المرئي، يمكنك أيضًا استكشاف دمج Flow Builder مع وظائف Google Cloud وVision API لإضافة أتمتة تعتمد على الذكاء الاصطناعي لخطوط معالجة البيانات الخاصة بك.
عندما بدأت بحثي على الإنترنت، كنت أرغب في إيجاد المسار الأقل مقاومة. كان يمكنني إنشاء جميع لوحات المعلومات وواجهة المستخدم بنفسي في HTML وpython، ومع ذلك، بعد بعض البحث عبر Google، توصلت إلى Dash الخاص بـ Plotly، الذي يتكامل بسهولة مع python. اخترت Dash لسببين: 1) إنه مفتوح المصدر، و2) بعد قراءة الوثائق تبين أنه يمكن تخصيصه بسهولة لما كنت أحاول فعله. Dash هو مكتبة مفتوحة المصدر مثالية لبناء ونشر تطبيقات البيانات بواجهات مستخدم مخصصة. جعل ذلك إنشاء واجهة المستخدم أمرًا بسيطًا للغاية. ثم أصبحت المسألة كيف يمكنني جعل هذا التطبيق معقدًا؟ كلما قضيت وقتًا أكبر، زادت الميزات التي أردت إضافتها.
بالنسبة للمشروع الأولي، أردت التأكد من أن لدي لوحة معلومات بمقاييس قابلة للتخصيص وإطار زمني قابل للاختيار. في البداية، بدأت بلوحة معلومات حيث يمكنك اختيار مقياس واحد فقط من القائمة المسندلة. ثم، بعد تلقي تعليقات من الزملاء، قمت بصقل لوحة المعلومات قليلاً لإضافة خيارات متعددة وعناوين محاور. كما قررت إضافة علامة تبويب إضافية لسجل الأحداث. وصلت إلى نقطة شعرت فيها بالرضا عن ما كان لدي كنقطة انطلاق جيدة لأي شخص يرغب في بناء لوحات معلومات خاصة به. للمطورين الذين يريدون تغذية البيانات في الوقت الفعلي إلى لوحات المعلومات الخاصة بهم، تحقق من دليلنا على بناء مستهلكي webhook بـ Azure Functions. بالطبع، وضعت المشروع في Github لتتمكن من نسخه أو تقسيمه.
البدء
للوصول إلى هذا التطبيق، ستحتاج إلى التأكد من أنك تقوم بتشغيل python 3.10 أو أحدث وتثبيت المكتبات التالية:
requests
dash
pandas
ثم، أدخل مفتاح API الخاص بك في App.py وشغل التطبيق. سوف يعمل على http://localhost:8050. لمزيد من المعلومات حول نشر هذا على خادم عام (مثل AWS)، انظر الموارد التالية:
إنشاء صفحة لوحة التحكم
إنشاء صفحة تفاصيل الحدث
كانت صفحة تفاصيل الحدث أكثر صعوبة قليلاً لأنني لم أكن أعرف أفضل طريقة لتقديم جميع مقاييس الأحداث بطريقة سهلة القراءة. فكرت في إضافة معلمات تصفية إلى هذه الصفحة، لكني قررت أن ذلك سيضيف قدراً كبيراً من الوقت إلى هذا المشروع حيث سيصبح الجدول ديناميكياً (إلى جانب إضافة المعلمات واسترجاعات البيانات، وما إلى ذلك). استقرت على عرض جميع الأحداث ووضع الطابع الزمني أولاً (لأنه بدون وضع الطابع الزمني أولاً، لم يكن المخطط سهلاً للقراءة). في البداية، وجدت أنه مع مجرد HTML الخام، كان الجدول صعبًا للغاية بالنسبة للعينين. لم تكن هناك حدود ولم تكن هناك اختلافات في الألوان بين الرأس والصفوف. لجعل الجدول أسهل في القراءة، كنت قادرًا على استخدام CSS داخل Dash.
الفكرة لتفاصيل الحدث تشبه تقريبًا لوحة التحكم، باستثناء هذه المرة، أنني أدعو Events API وجلب جميع الأحداث. لاحظ أن تفاصيل الحدث تعرض فقط أحدث 10 أحداث (باستخدام معلمة max_rows وتصفية API). يمكن زيادتها، لكن استقرت على عرض أحدث 10 أحداث لأن المزيد من الأحداث تم عرضها، كلما استغرق وقت استدعاء API أطول. قد يكون التحسين الكبير الذي يمكن إجراؤه هو القدرة على تقسيم الصفحات وتضمين صفحة التالية / صفحة السابقة في واجهة المستخدم.
لبناء علامة التبويب الأحداث (الصفحة)، أولاً أدعو Events API وأقوم بتحليل استجابة JSON إلى إطار بيانات. ثم أقوم بفرز وإعادة ترتيب إطار البيانات لوضع الطابع الزمني كأول عمود. وأخيرًا، أقوم ببناء جدول HTML عن طريق تشغيل البيانات عبر إطار البيانات.
#بناء واستدعاء معلمات API الأحداث params = { "events" : "التسليم، لحقن، ارتداد، تأخير، رفض السياسات، خارج النطاق، فتح، نقر، فشل التكوين، رفض التكوين، شكوى البريد العشوائي، إلغاء الاشتراك في القائمة، إلغاء الاشتراك في الرابط", "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