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

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

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

ERexchangerate.dev·Sep 8, 2026·قراءة خلال 8 دقائق

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

Key points
استخدم 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 modelcopy
from decimal import Decimal

def 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 writecopy
import json
import os
import tempfile
from pathlib import Path

def 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 itcopy
chmod 700 python-exchange-rate-alerts.py
export 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

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

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

ER
exchangerate.dev
أدلة تكامل للمطورين.

تابع القراءة

Tutorialالحصول على أسعار الصرف في Pythonاقرأ Referenceقراءة source وmarket_sessionاقرأ Guideالسجل التاريخي في طلب واحداقرأ
المزيد من المقارناتFixer vs exchangerate.devOpen Exchange Rates vs exchangerate.devCurrencylayer vs exchangerate.dev
تعلّمReading source and market_session in your pipelineIndicative vs executable FX rates: what a rates API actually gives youأسعار الصرف المرجعية للبنك المركزي الأوروبي، موضحة
أسعار مباشرةEUR/USDGBP/USDUSD/JPY