لجلب أسعار الذهب المباشرة في Python، أرسل طلب GET إلى api.goldprice.dev/v1/spot/XAU-USD-SPOT عبر requests، وضع مفتاح API في ترويسة X-API-Key. غلّف الاستدعاء بـcachetools.TTLCache للتخزين المؤقت لمدة 60 ثانية، واستخدم Decimal لحسابات الأسعار. تشمل الخطة المجانية 5,000 استدعاء/شهر دون بطاقة ائتمان. اختُبر في أكتوبر 2026 باستخدام Python 3.15 + requests 2.34.
احصل على مفتاح API لدى goldprice.dev
أنشئ حسابًا مجانيًا في goldprice.dev/onboarding. بعد تأكيد البريد الإلكتروني، تعرض لوحة التحكم مفتاحًا يبدأ بـga_live_. عيّنه كمتغير بيئة:
export GOLDPRICE_API_KEY=ga_live_replace_with_your_key_hereتشمل الخطة المجانية 5,000 استدعاء/شهر وسعر الذهب الفوري بـ31 عملة. لا تحتاج إلى بطاقة ائتمان.
ثبّت الحزم المطلوبة
تحتاج إلى ثلاث حزم: requests لطلب HTTP، وcachetools للتخزين المؤقت بصلاحية TTL داخل العملية، وtenacity لإعادة المحاولة عند 429. ثبّتها باستخدام pip أو uv:
# pippip install requests cachetools tenacity# or uv (recommended)uv add requests cachetools tenacityاكتب عميل goldprice
احفظ الكود باسم goldprice.py. تخزّن الدالة spot() النتائج لكل رمز لمدة 60 ثانية، وتعيد المحاولة حتى 3 مرات عند 429 بفواصل انتظار تتزايد أُسّيًا، وتُرجع الأسعار كقيم Decimal لتجنّب أخطاء دقة float في الحسابات اللاحقة.
# python: goldprice.py# curl-equivalent: https://api.goldprice.dev/v1/spot/XAU-USD-SPOTimport osfrom decimal import Decimalfrom typing import TypedDictimport requestsfrom cachetools import TTLCache, cachedfrom tenacity import ( retry, retry_if_exception_type, stop_after_attempt, wait_exponential,)API_BASE = "https://api.goldprice.dev"API_KEY = os.environ["GOLDPRICE_API_KEY"]TIMEOUT = 5 # secondsclass SpotResponse(TypedDict): symbol: str quote_currency: str price: Decimal bid: Decimal | None # only on plans that include bid and ask ask: Decimal | None is_stale: bool computed_at: strclass RateLimited(Exception): """Raised on HTTP 429 so tenacity retries with backoff."""@cached(cache=TTLCache(maxsize=128, ttl=60))@retry( retry=retry_if_exception_type(RateLimited), wait=wait_exponential(multiplier=1, min=2, max=30), stop=stop_after_attempt(3), reraise=True,)def spot(symbol: str = "XAU-USD-SPOT") -> SpotResponse: """Fetch live spot price. Cached 60s per symbol, retries 3x on 429.""" resp = requests.get( f"{API_BASE}/v1/spot/{symbol}", headers={"X-API-Key": API_KEY}, timeout=TIMEOUT, ) if resp.status_code == 429: raise RateLimited(resp.text) resp.raise_for_status() data = resp.json() return { "symbol": data["symbol"], "quote_currency": data["quote_currency"], "price": Decimal(data["price"]), "bid": Decimal(data["bid"]) if data.get("bid") else None, "ask": Decimal(data["ask"]) if data.get("ask") else None, "is_stale": data["is_stale"], "computed_at": data["computed_at"], }if __name__ == "__main__": r = spot("XAU-USD-SPOT") print(f"{r['symbol']}-{r['quote_currency']}: {r['price']} (computed {r['computed_at']})")شغّل الملف
شغّل الملف من الصدفة نفسها التي صدّرت فيها GOLDPRICE_API_KEY. يستدعي الطلب الأول API؛ وتُرجع الاستدعاءات خلال 60 ثانية القيمة المخزّنة فورًا. لا تستفيد مرات التشغيل في عملية جديدة من الذاكرة المؤقتة، لأنها داخل العملية فقط؛ استخدم Redis للتخزين المشترك بين العمليات.
python goldprice.py# XAU-USD: 4012.75 (computed 2026-10-23T07:00:18.221118+00:00)غيّر العملة أو المعدن
تتبع الرموز الصيغة METAL-CURRENCY-SPOT. مرّر إلى spot() أي رمز من عملات السعر الفوري البالغ عددها 31. يُخزّن كل رمز مستقلًا في TTLCache؛ لذا ترسل لوحة متعددة العملات تستطلع 5 رموز بفواصل 60s عدد 5 استدعاءات API/دقيقة دون تخزين مؤقت، و0 عند توفر النتائج في الذاكرة المؤقتة.
# USD spot, defaultspot("XAU-USD-SPOT")spot("XAU-INR-SPOT")spot("XAU-EUR-SPOT")# Silver in USDspot("XAG-USD-SPOT")النتيجة المتوقعة
{ "symbol": "XAU", "quote_currency": "USD", "unit": "troy_ounce", "contract_type": "spot", "price": "4012.75", "is_stale": false, "computed_at": "2026-10-23T07:00:18.221118+00:00"}يعرض الخرج القياسي سطرًا واحدًا: symbol وquote_currency وprice بصيغة Decimal، والطابع الزمني computed_at بصيغة ISO 8601. يستخدم كودك اللاحق استجابة TypedDict.
أخطاء شائعة
| الرمز | ما يظهر لك | الحل |
|---|---|---|
| 401 | requests.exceptions.HTTPError: 401 Client Error | مفتاح API مفقود أو غير صالح. تحقّق من تعيين GOLDPRICE_API_KEY: echo $GOLDPRICE_API_KEY. إذا كان فارغًا، فأعد تصديره من لوحة التحكم. يطلق العميل استثناءً عند غياب متغير البيئة وقت الاستيراد، لا وقت الاستدعاء؛ لذا يظهر الفشل عند أول import goldprice. |
| 429 | تفشل ثلاث محاولات RateLimited بفواصل انتظار متزايدة، ثم يُطلق استثناء | استنفدت حد الطلبات في الدقيقة. تمنع ذاكرة 60 ثانية ذلك عند الاستطلاع المنتظم؛ إذا جاءت رموز مختلفة دفعة واحدة، فارفع TTLCache.maxsize أو وزّع الاستدعاءات زمنيًا. للاستخدام الكثيف المستمر، راجع الخطط المدفوعة في الأسعار. |
| N/A | تتراكم أخطاء دقة float عند جمع أسعار كثيرة | استخدم Decimal طوال الحسابات، وتجنّب float. يُرجع العميل الأسعار كقيم Decimal؛ ولتحويلها إلى JSON، استخدم str(price) بدل التحويل إلى float للحفاظ على الدقة أثناء النقل. |
خطوات إضافية
- شارك الذاكرة المؤقتة بين العمليات: استبدل
TTLCacheبذاكرة مؤقتة تعتمد على Redis لتشارك العمليات العاملة سعرًا واحدًا في الذاكرة - أضف دالة
bars()لتغليف/v1/bars?symbol=XAU-USD-SPOT&interval=1d&from=...&to=...وتحويل النتائج إلى pandas DataFrame للاختبار التاريخي - استبدل
requestsبـhttpx.AsyncClientإذا كانت خدمتك غير متزامنة؛ بنية الاستجابة متطابقة - اربط العميل بنقطة نهاية FastAPI وقدّمه داخليًا للخدمات المكتوبة بغير Python
- أتح مقاييس Prometheus لنسبة نجاح التخزين المؤقت، وزمن الاستجابة p50/p95، وعدد محاولات الإعادة عند 429