أهلاً بك مجدداً في رحلتنا نحو بناء وكلاء الذكاء الاصطناعي.
في الدرس السابق، تعلمنا كيفية تحليل استجابات JSON المعقدة، واستخراج البيانات التي نحتاجها سواء كانت في قائمة أو داخل هياكل متداخلة. لقد أصبحت الآن قادراً على "قراءة" المعلومات التي ترسلها واجهات برمجة التطبيقات (APIs).
حتى الآن، كانت جميع الواجهات التي تعاملنا معها عامة ومفتوحة للجميع، مثل مكتبة عامة يمكن لأي شخص الدخول إليها. لكن معظم واجهات برمجة التطبيقات القوية، وخصوصاً تلك التي سنستخدمها لبناء وكلائنا (مثل واجهات نماذج اللغة الكبيرة)، تشبه نادياً خاصاً يتطلب بطاقة عضوية للدخول. "بطاقة العضوية" هذه في عالم الـ APIs هي ما نسميه مفتاح API (API Key).
اليوم، سنتعلم كيف نقدم "بطاقة العضوية" هذه بشكل صحيح. هدف هذا الدرس هو استخدام مفاتيح API في ترويسات الطلب (Request Headers) للمصادقة، أي للتحقق من هويتنا والسماح لنا بالوصول إلى الخدمات المحمية. هذه خطوة أساسية ستمكننا من التفاعل مع أي API تقريباً في العالم.
1. ما هو مفتاح API ولماذا نحتاجه؟
مفتاح الـ API هو ببساطة سلسلة فريدة من الحروف والأرقام (مثل sk-abc123def456) تحصل عليها من مزود الخدمة (مثل OpenAI أو Google). إنه بمثابة هوية رقمية لتطبيقك. عندما ترسل طلباً إلى الـ API، فإنك ترفق هذا المفتاح لإثبات هويتك.
لماذا هو ضروري؟
- المصادقة (Authentication): للتحقق من أنك مستخدم مصرح له باستخدام الخدمة.
- التفويض (Authorization): لتحديد الصلاحيات الممنوحة لك. بعض المفاتيح قد تسمح بالقراءة فقط، بينما تسمح أخرى بالكتابة أو الحذف.
- تتبع الاستخدام (Usage Tracking): يستخدم مزود الخدمة المفتاح ليحسب عدد الطلبات التي أرسلتها، وهو أمر مهم بشكل خاص في الخدمات التي لديها باقات مجانية محدودة أو التي تحاسبك بناءً على الاستخدام.
بينما تعتبر مفاتيح API بسيطة وسهلة الاستخدام، فإنها تأتي مع مسؤولية كبيرة. إذا حصل شخص آخر على مفتاحك، فيمكنه استخدامه وكأنه أنت، مما قد يؤدي إلى استهلاك باقتك أو الوصول غير المصرح به إلى بياناتك.
2. الترويسات (Headers): المكان الصحيح لوضع المفتاح
عندما نرسل طلباً عبر بروتوكول HTTP (وهو ما تفعله مكتبة requests)، يتكون الطلب من جزأين رئيسيين: الجسم (Body) الذي يحتوي على البيانات التي نرسلها (مثل بيانات المستخدم في طلب POST)، والترويسات (Headers).
يمكنك التفكير في الترويسات كمعلومات إضافية مكتوبة على ظرف الرسالة. بينما تحتوي الرسالة نفسها على المحتوى (الجسم)، يحتوي الظرف (الترويسات) على معلومات حول الرسالة، مثل عنوان المرسل والمستلم، ونوع المحتوى، ومعلومات المصادقة.

على الرغم من وجود طرق أخرى لإرسال مفتاح الـ API (مثل إضافته إلى الرابط مباشرة)، إلا أن إرساله في الترويسات هو الطريقة المعتمدة والأكثر أماناً.
API Keys: API Authentication Methods & Examples
لفهم الطرق المختلفة لتمرير مفاتيح API وأيها أفضل، ألقِ نظرة على المقال التالي من Stoplight. سيركز شرحي على الأفكار الرئيسية التي تحتاجها.
اقرأ قسم "How to Pass API Keys in Headers" ثم القسم الذي يليه "Other API Key Locations". لاحظ الطرق المختلفة في الترويسات، والسبب الذي يجعل وضع المفتاح في الرابط (Query String) أقل أماناً.
كما قرأت، هناك طريقتان شائعتان لإرسال المفتاح في الترويسات، ويعتمد الاختيار بينهما على تصميم الـ API نفسها (يجب عليك دائماً قراءة توثيق الـ API لمعرفة الطريقة الصحيحة):
- ترويسة مخصصة (Custom Header): يستخدم اسم ترويسة غير قياسي، وغالباً ما يكون شيئاً مثل
X-Api-Key. - ترويسة التفويض (Authorization Header): وهي الطريقة الأكثر شيوعاً في الواجهات الحديثة. عادة ما تأخذ الشكل
Authorization: Bearer YOUR_API_KEY. كلمةBearerتعني "حامل"، أي "الشخص الذي يحمل هذا الرمز (token) مسموح له بالوصول".
3. التطبيق العملي في بايثون
إرسال الترويسات باستخدام مكتبة requests أمر بسيط للغاية. كل ما عليك فعله هو إنشاء قاموس بايثون dict يحتوي على الترويسات، ثم تمرير هذا القاموس إلى المعلمة headers في دالة الطلب (.get() أو .post()).
هيكل الكود العام:
import requests
# عنوان URL للـ API
url = "https://api.example.com/data"
# مفتاح الـ API الخاص بك
api_key = "abcdef12345"
# 1. إنشاء قاموس الترويسات
# المفتاح في القاموس هو اسم الترويسة، والقيمة هي محتوى الترويسة
headers = {
"Authorization": f"Bearer {api_key}"
}
# 2. تمرير القاموس إلى معلمة 'headers'
response = requests.get(url, headers=headers)
# 3. التعامل مع الاستجابة كالمعتاد
if response.status_code == 200:
print("نجح الطلب!")
print(response.json())
else:
print(f"فشل الطلب، رمز الحالة: {response.status_code}")
print(response.text) # طباعة نص الخطأ قد يعطيك تلميحاً
دعنا نرى أمثلة حقيقية توضح الطريقتين الشائعتين.
المثال الأول: نمط Authorization: Bearer
هذا النمط شائع جداً وستصادفه كثيراً. المقال التالي من Apidog باللغة العربية يوفر مثالاً ممتازاً على ذلك.
إطلاق العنان للإمكانات: إجراء استدعاءات API باستخدام بايثون
يوضح هذا المقال كيفية إجراء استدعاءات API في بايثون. سنركز على المثال البرمجي الذي يوضح استخدام 'Bearer Token' في الترويسات.
اقرأ المثال البرمجي تحت عنوان "عينة كود لاستدعاء واجهة برمجة تطبيقات REST في بايثون" والشرح الذي يليه. لاحظ كيف تم بناء قاموس headers.
كما رأيت في المقال، تم تعريف القاموس كالتالي:headers = {"Authorization": f"Bearer {api_token}"}
هذه هي الطريقة القياسية لاستخدام مفاتيح من نوع "Bearer".
المثال الثاني: نمط الترويسة المخصصة (Custom Header)
في بعض الأحيان، تطلب منك الـ API استخدام اسم ترويسة خاص بها، مثل x-api-key أو x-authentication-token. المبدأ لا يتغير، كل ما عليك هو تغيير المفتاح في قاموس headers.

الفيديو التالي يعطي مثالاً عملياً على هذا النوع من المصادقة.
Python Requests Authentication Examples - Basic Auth, Custom Headers w/ Code
يشرح هذا الفيديو طرقاً مختلفة للمصادقة في مكتبة requests. سنركز على الجزء الذي يستخدم ترويسة مخصصة.
شاهد من الدقيقة 03:23 إلى 06:05. ركز على النقاط التالية: كيف يذكر أن التوثيق (documentation) يطلب ترويسة خاصة اسمها x-authentication-token. كيف أنشأ قاموس headers بهذا الاسم. كيف مرر هذا القاموس إلى requests.get().
النقطة الأهم التي نستخلصها من هذين المثالين هي: اقرأ دائماً توثيق الـ API! هو الذي سيخبرك باسم الترويسة الصحيح والشكل الدقيق الذي يجب أن يكون عليه محتواها.
اختبر فهمك!
لنفترض أنك تريد استخدام واجهة برمجة تطبيقات للطقس. يخبرك التوثيق أن عليك إرسال طلب GET إلى الرابط https://api.weather.com/v1/current?city=Riyadh، ويجب أن يتضمن الطلب ترويسة x-api-key وقيمتها هي مفتاحك السري وليكن "my-secret-weather-key".
اكتب الكود اللازم في بايثون لإرسال هذا الطلب باستخدام مكتبة requests. (لا تقلق بشأن تشغيل الكود، فقط اكتب الهيكل الصحيح).
أظهر الإجابة
import requests
url = "https://api.weather.com/v1/current?city=Riyadh"
api_key = "my-secret-weather-key"
# إنشاء قاموس الترويسات بالاسم الصحيح
headers = {
"x-api-key": api_key
}
# إرسال الطلب مع الترويسات
response = requests.get(url, headers=headers)
# طباعة رمز الحالة للتحقق (افتراضياً)
print(response.status_code)
4. ملاحظة هامة حول الأمان
في كل الأمثلة التي رأيناها، قمنا بكتابة مفتاح الـ API مباشرة داخل الكود. هذا يسمى "التشفير الصلب" (Hardcoding) وهو ممارسة سيئة وخطيرة جداً.
لماذا؟ لأنه إذا شاركت هذا الكود مع أي شخص، أو قمت برفعه على منصة مثل GitHub، فسيتمكن أي شخص يرى الكود من سرقة مفتاحك واستخدامه.
لا تقلق! لن نترك الأمر هكذا. الهدف من درس اليوم كان فهم آلية استخدام المفاتيح. في درسنا القادم مباشرة، سنتعلم الطريقة الاحترافية والآمنة لإدارة هذه المفاتيح والبيانات الحساسة الأخرى باستخدام ما يسمى "متغيرات البيئة" (Environment Variables)، بحيث لا تظهر أبداً في الكود المصدري.
ملخص الدرس وأهم النقاط
أحسنت صنعاً! لقد أضفت اليوم أداة قوية جداً إلى صندوق مهاراتك. أنت الآن لم تعد مقتصراً على الواجهات العامة، بل يمكنك البدء في التعامل مع الخدمات المحمية التي تشكل العمود الفقري للعديد من التطبيقات الحديثة.
أهم النقاط التي استخلصناها:
- مفتاح الـ API هو هويتك الرقمية عند التعامل مع الخدمات المحمية.
- الترويسات (Headers) هي المكان القياسي والآمن لإرسال مفتاح الـ API.
- في بايثون، نستخدم قاموساً (dictionary) لتعريف الترويسات ونمرره إلى المعلمة
headersفي مكتبةrequests. - يجب دائماً مراجعة توثيق الـ API لمعرفة اسم الترويسة الصحيح (
Authorization,x-api-key, إلخ) والشكل المطلوب. - كتابة المفاتيح مباشرة في الكود (Hardcoding) ممارسة خطيرة سنتعلم كيفية تجنبها في الدرس القادم.
ما التالي؟
الآن بعد أن تعلمنا كيفية المصادقة، وتجنبنا كتابة مفاتيحنا بشكل غير آمن، سنكون مستعدين للخطوة الكبرى التالية. في الدرس القادم، سنتعلم كيفية تأمين مفاتيح API وبياناتنا الحساسة باستخدام متغيرات البيئة. هذا سيجعل تطبيقاتنا آمنة وجاهزة للمشاركة والتشغيل في بيئات مختلفة دون كشف أسرارنا.