AzLearn

مكتبة requests

The requests Library

مفهوم ~20 دقيقة

مكتبة requests — The requests Library

كل مرة تبحث في جوجل أو تفتح تطبيق الطقس أو تراسل أحداً عبر واتساب، هناك برنامج في الخلفية يرسل طلبات HTTP ويستقبل استجابات. Python تتيح لك فعل نفس الشيء في أسطر قليلة، وأشهر أداة لذلك هي مكتبة requests.

ما هو HTTP؟

HTTP (HyperText Transfer Protocol) هو البروتوكول الذي يتحدث به الويب. كل تبادل يبدأ من العميل (أنت) بطلب، وينتهي باستجابة من الخادم:

العميل → [GET /api/weather?city=Riyadh] → الخادم
العميل ← [200 OK, {"temp": 38}] ← الخادم

كل طلب له:

  • الأسلوب (Method): GET لقراءة البيانات، POST لإنشائها، PUT لتحديثها، DELETE لحذفها
  • الرابط (URL): عنوان الخادم والمسار
  • الترويسات (Headers): معلومات إضافية مثل نوع المحتوى أو بيانات المصادقة
  • الجسم (Body): البيانات المُرسَلة (في POST وPUT عادةً)

وكل استجابة لها:

  • رمز الحالة (Status Code): 200 نجاح، 404 غير موجود، 500 خطأ في الخادم
  • الترويسات: تصف نوع المحتوى وغيره
  • الجسم: البيانات المُعادة، غالباً JSON

تثبيت المكتبة

pip install requests

طلب GET — قراءة البيانات

GET هو أبسط الطلبات — تطلب بيانات ولا ترسل شيئاً:

import requests

# طلب حقيقي — Real request (يحتاج اتصال بالإنترنت)
response = requests.get("https://api.github.com/users/octocat")

print(response.status_code)   # 200
print(response.json())        # dict يحتوي بيانات المستخدم

لكن داخل المتصفح، الكود يعمل على Pyodide — بيئة Python وضعيّة في المتصفح لا تستطيع إرسال طلبات HTTP حقيقية لأسباب أمنية تتعلق بـ CORS وsandboxing. لذلك في التدريبات، سنحاكي الاستجابات بتحليل JSON نصي — وهذا يمنحنا تدريباً حقيقياً على الجزء الأهم: فهم شكل الاستجابة والتعامل معها.

تحليل استجابة JSON

الجزء الأكثر استخداماً في العمل مع APIs هو تحليل الاستجابة. في كود حقيقي:

import requests

response = requests.get("https://api.example.com/users/1")
# تحويل الاستجابة إلى dict — Convert response to dict
data = response.json()
print(data["name"])

في التدريبات، نُحاكي هذا بـ json.loads():

main.go

المعاملات في URL — Query Parameters

كثير من APIs تقبل معاملات في الرابط مثل ?page=2&limit=10. مكتبة requests تتولى بناء هذا الرابط تلقائياً:

import requests

# بدون requests — رابط يدوي
url = "https://api.example.com/products?category=books&page=1&limit=20"

# مع requests — params تُبنى تلقائياً
params = {
    "category": "books",   # الفئة — category
    "page": 1,             # رقم الصفحة — page number
    "limit": 20            # عدد النتائج — results per page
}
response = requests.get("https://api.example.com/products", params=params)
# requests يبني الرابط نيابةً عنك — requests builds URL for you

دعنا نتدرب على تحليل نتائج مُصنّفة:

main.go

الترويسات — Headers

الترويسات تُرسَل مع كل طلب وتحمل معلومات مهمة. أشيع استخدام لها هو المصادقة (Authentication):

import requests

# مفتاح API في الترويسة — API key in header
headers = {
    "Authorization": "Bearer my-secret-token",
    "Accept": "application/json",
    "Accept-Language": "ar"
}

response = requests.get(
    "https://api.example.com/profile",
    headers=headers
)
main.go

طلب POST — إرسال البيانات

POST يُستخدم لإنشاء موارد جديدة أو إرسال بيانات للمعالجة. الفرق الرئيسي عن GET أنه يحمل جسماً (body):

import requests

# إنشاء مستخدم جديد — Create a new user
new_user = {
    "name": "فاطمة",
    "email": "[email protected]",
    "role": "مطورة"
}

# json= يُحوّل dict إلى JSON ويضبط Content-Type تلقائياً
# json= converts dict to JSON and sets Content-Type automatically
response = requests.post(
    "https://api.example.com/users",
    json=new_user,
    headers={"Authorization": "Bearer my-token"}
)

if response.status_code == 201:
    created = response.json()
    print(f"أُنشئ المستخدم: {created['id']}")
main.go

رموز حالة HTTP — Status Codes

رموز الحالة هي لغة الخوادم — كل رمز يخبرك بما حدث:

الرمزالمعنىمتى يظهر
200OK — ناجحGET أو PUT نجح
201Created — أُنشئPOST أنشأ موردًا
400Bad Request — طلب سيءبيانات ناقصة أو خاطئة
401Unauthorized — غير مصرحلا توكن أو توكن منتهٍ
403Forbidden — محظورلا صلاحية كافية
404Not Found — غير موجودالمورد غير موجود
422Unprocessable — لا يمكن معالجتهالبيانات غير صالحة منطقياً
500Server Error — خطأ في الخادمخطأ داخلي في الخادم
import requests

response = requests.get("https://api.example.com/users/99999")

# تحقق من نجاح الطلب — Check if request succeeded
if response.status_code == 200:
    print("نجح الطلب")
elif response.status_code == 404:
    print("المستخدم غير موجود")
elif response.status_code >= 500:
    print("خطأ في الخادم — حاول لاحقاً")

# أو أبسط: raise_for_status تُولّد استثناءً عند فشل الطلب
response.raise_for_status()   # HTTPError إذا status >= 400

الجلسات — Sessions

عندما تُرسل عدة طلبات لنفس الخادم، Session تُحسّن الأداء وتحتفظ بالإعدادات المشتركة:

import requests

session = requests.Session()

# ضبط مرة واحدة — Set once
session.headers.update({
    "Authorization": "Bearer my-token",
    "Accept": "application/json"
})

# كل الطلبات ترث الإعدادات — All requests inherit settings
users = session.get("https://api.example.com/users").json()
products = session.get("https://api.example.com/products").json()
main.go

خلاصة

مكتبة requests تجعل التعامل مع HTTP بديهياً في Python. اتقان قراءة وتحليل JSON هو المهارة الأساسية — سواء كنت تبني عميل API أو تختبر خادمك. في الدرس القادم، ستنقلب الأدوار: ستبني الخادم الذي يرد على هذه الطلبات.

تحدي — Challenge