احصل على بيانات البنك الدولي باستخدام Python

تفهرس Narwhal API عددًا قدره 1,489 مؤشرًا سنويًا من مؤشرات WDI للبنك الدولي بموجب CC BY 4.0. للحصول على بيانات البنك الدولي باستخدام Python، ابحث عن مؤشر، وأضف رمز بلد بالأحرف الصغيرة إلى قالب معرّفه، واطلب الملاحظات باستخدام مفتاح API. تتضمن الاستجابة الفترات والقيم كسلاسل نصية لأعداد عشرية ونسبة البيانات إلى مصدرها ورابط الترخيص. تحدد خطتك النطاق الزمني للسجل التاريخي والحصة اليومية لعمليات الجلب غير المخزنة مؤقتًا.

نفّذ ذلك باستخدام واجهة API

  1. احصل على مفتاح مجاني وجهّز Python أنشئ حسابًا عبر التسجيل، واحصل على مفتاح API، واضبط NARWHAL_API_KEY في الصدفة التي ستشغّل فيها Python. استبدل العنصر النائب بمفتاحك. ثبّت requests لاستدعاءات HTTP وpandas لإنشاء DataFrame. يستخدم كل طلب المفتاح في ترويسة Authorization؛ ويقرأه السكربت الكامل في الخطوة الأخيرة من البيئة.
    ثبّت التبعيات واضبط مفتاحك
    python -m pip install requests pandas
    export NARWHAL_API_KEY="replace-with-your-key"
  2. ابحث عن مؤشر ابحث في الكتالوج عن gdp per capita مع source=wdi. اطبع id_template وعنوان كل نتيجة، ثم اختر المؤشر الذي تحتاج إليه. البحث في الكتالوج متاح على جميع الخطط ولا يستدعي أي مصدر. يتولى الوسيط params معالجة المسافات في عبارة البحث. تصف نتائج البحث المؤشرات؛ ويُدرج البلد في معرّف السلسلة الذي ستنشئه بعد ذلك.
    ابحث عن قوالب مؤشرات البنك الدولي
    import os
    import requests
    
    BASE_URL = "https://api.narwhalapi.com"
    headers = {
        "Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"
    }
    response = requests.get(
        f"{BASE_URL}/v1/economics/catalogue",
        headers=headers,
        params={"q": "gdp per capita", "source": "wdi"},
        timeout=10,
    )
    response.raise_for_status()
    catalogue = response.json()
    for hit in catalogue["results"]:
        print(hit["id_template"], hit["title"])
  3. أضف بلدًا إلى القالب استبدل {country} في القالب الذي اخترته برمز ISO 3166-1 alpha-3 بالأحرف الصغيرة. تستخدم إندونيسيا idn. يأخذ معرّف البنك الدولي الصيغة wdi:<indicator>/<iso3>، بما فيها الشرطة المائلة بين المؤشر والبلد. مرر المعرّف الكامل عبر معامل الاستعلام id. يختار المقتطف أول نتيجة بحث؛ راجع عنوانها المطبوع قبل استخدامها.
    أنشئ معرّف سلسلة خاصًا ببلد
    if not catalogue["results"]:
        raise SystemExit("No matching indicators found.")
    selected = catalogue["results"][0]
    series_id = selected["id_template"].replace("{country}", "idn")
    print(series_id)
  4. اقرأ الملاحظات السنوية اطلب الملاحظات لذلك المعرّف. تستخدم الفترات السنوية YYYY؛ ويشمل النطاق الحدين الاختياريين start وend. يقبل حد الاستجابة ما يصل إلى 1,000 ملاحظة، بحد افتراضي قدره 100. إذا كانت لـ next_cursor قيمة، فمررها بوصفها cursor للمتابعة. لا يؤدي رفع الحد إلى توسيع النطاق الزمني للسجل التاريخي في خطتك، وتظل السنوات المفقودة غائبة عن الاستجابة.
    اقرأ السلسلة المختارة
    response = requests.get(
        f"{BASE_URL}/v1/economics/catalogue/series/observations",
        headers=headers,
        params={"id": series_id, "limit": 1000},
        timeout=10,
    )
    response.raise_for_status()
    observations = response.json()["observations"]
  5. أنشئ DataFrame أنشئ DataFrame من الملاحظات، وحوّل period إلى عدد صحيح، وvalue إلى عدد ذي فاصلة عائمة. تصل القيم كسلاسل نصية لأعداد عشرية. استخدم Decimal بدلًا من float() عندما تحتاج إلى حساب عشري. احتفظ بتسمية الوحدة الواردة في الاستجابة مع تحليلك: فعنوان المؤشر يصف ما تقيسه قيمه. لا يملأ التحويل الفجوات ولا ينشئ ملاحظات للسنوات المفقودة.
    حوّل الفترات والقيم
    import pandas as pd
    
    frame = pd.DataFrame(observations, columns=["period", "value"])
    frame["period"] = frame["period"].astype(int)
    frame["value"] = frame["value"].map(float)
    print(frame)
  6. اجمع طلبات البلدان وعالج أخطاء الطلبات شغّل هذا السكربت الكامل لسلسلة الناتج المحلي الإجمالي في المثال ولدفعة أحدث القيم لإندونيسيا وكندا. افصل المعرّفات بفواصل؛ تقبل نقطة نهاية أحدث القيم من 1 إلى 50 معرّفًا مختلفًا. وتحتسب استدعاءً واحدًا لكل سلسلة مُعادة، في خطوة واحدة. يطبع السكربت الفترة والقيمة لكل بلد، ويبلّغ عن المعرّفات المفقودة، ويتوقف برسالة خطأ عند استجابات 400 أو 404 أو 429 fetch_limit_reached.
    اقرأ السجل التاريخي للناتج المحلي الإجمالي واجلب أحدث القيم دفعة واحدة
    import os
    import requests
    import pandas as pd
    
    BASE_URL = "https://api.narwhalapi.com"
    HEADERS = {
        "Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"
    }
    
    def get_json(path, params):
        response = requests.get(
            f"{BASE_URL}{path}",
            headers=HEADERS,
            params=params,
            timeout=10,
        )
        try:
            response.raise_for_status()
        except requests.HTTPError:
            problem = response.json()
            code = problem.get("code", "unknown_error")
            if response.status_code == 429 and code == "fetch_limit_reached":
                retry_after = response.headers.get("Retry-After")
                raise SystemExit(
                    f"Uncached fetch allowance used. Retry-After: {retry_after}"
                )
            if response.status_code in (400, 404):
                raise SystemExit(f"{code}: {problem.get('detail', '')}")
            raise
        return response.json()
    
    series_id = "wdi:ny.gdp.mktp.cd/idn"
    rows = []
    params = {"id": series_id, "limit": 1000}
    while True:
        payload = get_json(
            "/v1/economics/catalogue/series/observations", params
        )
        rows.extend(payload["observations"])
        cursor = payload.get("next_cursor")
        if not cursor:
            break
        params["cursor"] = cursor
    
    frame = pd.DataFrame(rows, columns=["period", "value"])
    frame["period"] = frame["period"].astype(int)
    frame["value"] = frame["value"].map(float)
    print(frame)
    
    countries = ("idn", "can")
    ids = [f"wdi:ny.gdp.mktp.cd/{country}" for country in countries]
    batch = get_json(
        "/v1/economics/catalogue/latest",
        {"ids": ",".join(ids)},
    )
    for observation in batch["observations"]:
        country = observation["id"].rsplit("/", 1)[1]
        print(country, observation["period"], observation["value"])
    for missing in batch["missing"]:
        print("Missing:", missing)

كيف أقرأ مثال الناتج المحلي الإجمالي لإندونيسيا؟

السلسلة wdi:ny.gdp.mktp.cd/idn هي الناتج المحلي الإجمالي لإندونيسيا بالدولار الأمريكي بالأسعار الجارية. أعاد طلب بمفتاح Pro في 27 أكتوبر 2026 مع limit=3 هذه الملاحظات. يستخدم هذا المثال إجمالي الناتج المحلي؛ استخدم القالب من بحثك في الكتالوج عندما تريد نصيب الفرد من الناتج المحلي الإجمالي.

الملاحظات المسجلة من استجابة الناتج المحلي الإجمالي
[
  {"period": "1967", "value": "5667756627.92093"},
  {"period": "1968", "value": "7076465299.81141"},
  {"period": "1969", "value": "8337423312.88344"}
]

لعام 1967، يحوّل float("5667756627.92093") القيمة لإجراء العمليات العددية في DataFrame. احتفظ بالسلسلة النصية الأصلية إذا كنت تحتاج أيضًا إلى تمثيلها العشري. تتضمن الاستجابات نسبة البيانات إلى مؤشرات WDI للبنك الدولي ورابط ترخيص CC BY 4.0. احتفظ بمعلومات النسبة والترخيص مع البيانات التي تستخدمها.

لماذا يعيد مفتاح Free الخاص بي بضع سنوات فقط؟

تتيح Free نطاقًا زمنيًا للسجل التاريخي قدره 12 شهرًا، مع حد أدنى للسلاسل السنوية يشمل أحدث 5 ملاحظات. تطبق Narwhal ما يمنحك عددًا أكبر من الملاحظات: النطاق الزمني للخطة أو ذلك الحد الأدنى. لذلك تحتفظ السلاسل السنوية بعدة ملاحظات حتى عندما يقع معظمها خارج النطاق المعتاد. ينطبق الحد الأدنى السنوي على جميع الخطط.

الحد المطبق على خطتي:

الخطةعمليات الجلب غير المخزنة مؤقتًا لكل حساب في اليوم بتوقيت UTCالنطاق الزمني للبيانات التاريخية
مجاني10آخر 12 شهرًا، مع أحدث 5 ملاحظات سنوية على الأقل
Basic100آخر 5 سنوات، مع أحدث 5 ملاحظات سنوية على الأقل
Pro1,000السجل التاريخي الكامل

يؤدي طلب نطاق يقع بالكامل قبل النطاق الزمني المسموح لك به إلى إرجاع 403 plan_upgrade_required. بالنسبة إلى السلاسل السنوية، تتحقق Narwhal من ذلك النطاق بعد تحميل السلسلة حتى تتمكن من مراعاة الحد الأدنى. استخدم تفاصيل الخطط لاختيار النطاق الزمني للسجل التاريخي الذي يحتاج إليه تحليلك.

ماذا يعني الخطأ 429 fetch_limit_reached؟

استهلك حسابك حصته اليومية، ويتطلب الطلب عملية جلب غير مخزنة مؤقتًا. اقرأ Retry-After قبل إعادة المحاولة؛ وتتجدد الحصة عند 00:00 UTC. تظل السلسلة المخزنة مؤقتًا متاحة للاستجابة بعد بلوغ الحد. تتراوح مدد التخزين المؤقت لبيانات البنك الدولي من 24 ساعة إلى 7 أيام، لذلك لا يتطلب طلب آخر بالضرورة عملية جلب.

عند ظهور 400 invalid_series_id، تحقق من المؤشر والشرطة المائلة ورمز البلد بالأحرف الصغيرة. يعني 400 invalid_query أن الاستعلام غير صالح. وقد يعني 404 not_found أن المؤشر غير معروف في الفهرس؛ وتحتفظ Narwhal بهذه النتيجة لمدة 24 ساعة. طابق المعرّف مع نتيجة الكتالوج قبل تكرار الطلب.

لا تُحتسب الاستجابات ذات البيانات القديمة ولا استجابات 400 و404 و503. إذا كان المصدر غير متاح ولا توجد نسخة مخزنة مؤقتًا، تعيد Narwhal 503 upstream_busy مع Retry-After. راجع التخزين المؤقت ومعالجة 429 لمعالجة إعادة المحاولة.

نُشر في .

الخطوات التالية