الأدلةدروس

إنشاء تنبيه لسعر USD/IDR في Python

أنشئ مراقباً بمكتبة Python القياسية ينبه مرة واحدة عند تجاوز عتبة، ويحفظ حالته بأمان ويحترم حداثة السعر وحدود الواجهة.

8 سبتمبر 2026 · قراءة خلال 8 دقائق

يقارن التنبيه كل ملاحظة USD/IDR جديدة وفعالة بالملاحظة السابقة، لا بوقت الاستطلاع السابق. الملاحظة الأولى تنشئ خط أساس، ولا تغيّر الأخطاء أو البيانات القديمة الحالة.

  • استخدم sources["IDR"] وeffective_at["IDR"] للحكم على IDR. الحقل العام source ملخص محافظ لكل العملات المطلوبة.
  • الملاحظة الأولى خط أساس فقط. بعد التجاوز ينفذ التنبيه مرة ثم يتوقف، ولا يعود إلا بعد ملاحظة صالحة ترجع دون العتبة.
  • اكتب JSON في ملف مؤقت، اضبط 0600، ثم استبدل الملف بـ os.replace حتى لا تترك المقاطعة حالة ناقصة.
  • استخدم مهلة عشر ثوانٍ، واحفظ المفتاح في EXCHANGERATE_API_KEY. اجعل الفاصل 60 ثانية على الأقل، واحترم Retry-After بعد 429.
  • نزّل النص الكامل واضبط العتبة ومسار الحالة خارج التحكم بالإصدارات. الإخراج إلى وحدة التحكم المحلية فقط.

نمذجة الملاحظة لكل عملة

استخدم sources["IDR"] وeffective_at["IDR"] للحكم على IDR. الحقل العام source ملخص محافظ لكل العملات المطلوبة.

python · observation model
from decimal import Decimaldef idr_observation(payload: dict) -> dict:    return {        "rate": Decimal(str(payload["rates"]["IDR"])),        "source": payload["sources"]["IDR"],        "effective_at": payload["effective_at"]["IDR"],        "market_session": payload["market_session"],    }

تعريف سياسة التجاوز

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

الحالةتغيير الحالةالتنبيه
الملاحظة الصالحة الأولىحفظ خط الأساسلا
ملاحظة دون العتبةarmed=trueلا
تجاوز والإنذار مسلحarmed=falseمرة واحدة
ملاحظة مكررة/قديمة أو خطأحفظ الحالةلا

حفظ الحالة بأمان

اكتب JSON في ملف مؤقت، اضبط 0600، ثم استبدل الملف بـ os.replace حتى لا تترك المقاطعة حالة ناقصة.

python · atomic state write
import jsonimport osimport tempfilefrom pathlib import Pathdef save_state(path: Path, state: dict) -> None:    path.parent.mkdir(parents=True, exist_ok=True)    fd, temporary = tempfile.mkstemp(prefix=f".{path.name}.", dir=path.parent, text=True)    try:        os.fchmod(fd, 0o600)        with os.fdopen(fd, "w") as handle:            json.dump(state, handle, sort_keys=True)            handle.write("\n")        os.replace(temporary, path)    except Exception:        try:            os.unlink(temporary)        except OSError:            pass        raise

تقييد الشبكة والحصة

استخدم مهلة عشر ثوانٍ، واحفظ المفتاح في EXCHANGERATE_API_KEY. اجعل الفاصل 60 ثانية على الأقل، واحترم Retry-After بعد 429. الفاصل الافتراضي خمس دقائق ويستهلك نحو 8,640 طلباً خلال 30 يوماً؛ أما 60 ثانية فتستهلك نحو 43,200 وقد تتجاوز الحصة المشتركة.

لا يمكن للأخطاء إنشاء تنبيهات زائفة

استخدم مهلة عشر ثوانٍ، واحفظ المفتاح في EXCHANGERATE_API_KEY. اجعل الفاصل 60 ثانية على الأقل، واحترم Retry-After بعد 429.

تشغيل المراقب الكامل

نزّل النص الكامل واضبط العتبة ومسار الحالة خارج التحكم بالإصدارات. الإخراج إلى وحدة التحكم المحلية فقط. الحد الافتراضي لعمر البيانات ساعة واحدة. اضبط FX_ALERT_MAX_AGE_SECONDS إذا كنت تقبل مرجعاً يومياً أو سوقاً مغلقاً. python-exchange-rate-alerts.py

shell · run it
chmod 700 python-exchange-rate-alerts.pyexport EXCHANGERATE_API_KEY="your-key"export FX_ALERT_THRESHOLD_PCT="1.0"export FX_ALERT_POLL_SECONDS="300"export FX_ALERT_STATE_PATH="$HOME/.local/state/fx-alert.json"python3 python-exchange-rate-alerts.py

اختبار السياسة دون انتظار السوق

اختبر الملاحظة الأولى والتجاوز والبيانات القديمة وإعادة التسليح بواسطة محاكاة للشبكة.

أسئلة

لماذا لا ينبه التشغيل الأول؟

لأنه لا يملك ملاحظة فعالة سابقة؛ يحفظ خط الأساس فقط.

لماذا نستخدم effective_at؟

لأنه يحدد وقت كتابة ملاحظة IDR ويمنع تكرار رد قديم.

هل بيانات إغلاق السوق غير صالحة دائماً؟

لا. احفظ source وmarket_session وافهمها كسعر مرجعي.

هل يرسل رسالة إلى أحد؟

لا، يطبع في وحدة التحكم المحلية.

تابع القراءة

ابدأ بمفتاح API مجاني

5,000 طلب شهريًا ضمن الخطة المجانية. لا حاجة إلى بطاقة ائتمان.

احصل على مفتاح مجاني