عند استدعاء Nano Banana Pro API لإنشاء الصور، ما الفرق بين الاستدعاء المتزامن (Synchronous) والاستدعاء غير المتزامن (Asynchronous)؟ في الوقت الحالي، تدعم كل من APIYI وGemini الرسمية وضع الاستدعاء المتزامن فقط، إلا أن APIYI حسّنت تجربة المستخدم بشكل كبير من خلال توفير مخرجات الصور عبر روابط OSS URL. سيحلل هذا المقال بشكل منهجي الاختلافات الجوهرية بين الاستدعاءات المتزامنة وغير المتزامنة، بالإضافة إلى حلول التحسين التي تقدمها منصة APIYI لتنسيقات إخراج الصور.
القيمة الجوهرية: بعد قراءة هذا المقال، ستفهم الفرق الجوهري بين الاستدعاء المتزامن وغير المتزامن في تصميم الـ API، ومزايا مخرجات رابط OSS URL الخاص بمنصة APIYI مقارنة بترميز base64، وكيفية اختيار الحل الأمثل للحصول على الصور بناءً على سيناريو العمل الخاص بك.

مقارنة أساسية بين أنماط استدعاء واجهة برمجة تطبيقات (API) Nano Banana Pro
| الميزة | الاستدعاء المتزامن (Synchronous) | الاستدعاء غير المتزامن (Asynchronous) | الدعم الحالي في APIYI |
|---|---|---|---|
| نمط الاتصال | الحفاظ على اتصال HTTP، وانتظار الإكمال | إرجاع معرف المهمة (Task ID) فوراً، وإغلاق الاتصال | ✅ استدعاء متزامن |
| آلية الانتظار | انتظار معطل (30-170 ثانية) | غير معطل، استطلاع (Polling) أو Webhook | ✅ متزامن (انتظار معطل) |
| مخاطر انتهاء المهلة | عالية (تتطلب ضبط المهلة بين 300-600 ثانية) | منخفضة (تحتاج مهلة قصيرة فقط لإرسال المهمة) | ⚠️ يتطلب ضبط المهلة بشكل مناسب |
| تعقيد التنفيذ | منخفض (يتم بطلب واحد) | متوسط (يتطلب استطلاعاً أو مراقبة Webhook) | ✅ بسيط وسهل الاستخدام |
| سيناريوهات الاستخدام | التوليد الفوري، والعرض المباشر | المعالجة الدفعية، والمهام الخلفية | ✅ توليد فوري |
| تحسين التكلفة | السعر القياسي | واجهة برمجة تطبيقات Google Batch توفر 50% | – |
كيفية عمل الاستدعاء المتزامن
يعتمد الاستدعاء المتزامن (Synchronous Call) على نمط طلب-انتظار-استجابة:
- العميل يرسل الطلب: يتم إرسال طلب توليد الصورة إلى الخادم.
- الحفاظ على اتصال HTTP: يبقي العميل اتصال TCP مفتوحاً، بانتظار انتهاء الخادم من عملية الاستدلال.
- انتظار معطل: خلال فترة الاستدلال التي تتراوح بين 30 إلى 170 ثانية، لا يمكن للعميل إجراء عمليات أخرى.
- استلام الاستجابة الكاملة: يعيد الخادم بيانات الصورة المنشأة (سواء بصيغة base64 أو كـ URL).
- إغلاق الاتصال: يتم إغلاق اتصال HTTP بعد الانتهاء.
الميزة الجوهرية: الاستدعاء المتزامن هو نمط معطل (Blocking)، حيث يجب على العميل انتظار استجابة الخادم قبل الاستمرار في تنفيذ أي عمليات لاحقة. وهذا يتطلب ضبط وقت مهلة (Timeout) طويل بما يكفي (يُنصح بـ 300 ثانية لصور 1K/2K، و600 ثانية لصور 4K) لتجنب انقطاع الاتصال قبل اكتمال الاستدلال.
كيفية عمل الاستدعاء غير المتزامن
يعتمد الاستدعاء غير المتزامن (Asynchronous Call) على نمط طلب-قبول-إخطار:
- العميل يرسل المهمة: يتم إرسال طلب توليد الصورة إلى الخادم.
- إرجاع معرف المهمة فوراً: يقبل الخادم الطلب، ويعيد معرف المهمة (مثل
task_abc123)، ثم يغلق الاتصال فوراً. - الاستدلال في الخلفية: يقوم الخادم بتوليد الصورة في الخلفية، بينما يمكن للعميل معالجة عمليات أخرى.
- الحصول على النتيجة: يحصل العميل على النتيجة بإحدى الطريقتين:
- الاستطلاع (Polling): إرسال طلبات دورية إلى المسار
/tasks/task_abc123/statusللاستعلام عن حالة المهمة. - Webhook: يقوم الخادم باستدعاء عنوان URL الذي وفره العميل تلقائياً عند اكتمال المهمة.
- الاستطلاع (Polling): إرسال طلبات دورية إلى المسار
- تنزيل الصورة: بعد اكتمال المهمة، يتم تنزيل الصورة المنشأة عبر الرابط (URL) المرتجع.
الميزة الجوهرية: الاستدعاء غير المتزامن هو نمط غير معطل (Non-blocking)، حيث يمكن للعميل معالجة طلبات أخرى فور إرسال المهمة، دون الحاجة للبقاء متصلاً لفترة طويلة. هذا النمط مناسب للمعالجة الدفعية، والمهام الخلفية، والحالات التي لا تتطلب استجابة فورية.
💡 نصيحة تقنية: تدعم منصة APIYI حالياً نمط الاستدعاء المتزامن فقط، ولكنها توفر تجربة مستخدم محسنة بشكل كبير من خلال تحسين إعدادات المهلة وتوفير مخرجات عبر روابط OSS URL. بالنسبة للحالات التي تتطلب توليد كميات كبيرة من الصور، نوصي باستخدام منصة APIYI عبر الموقع apiyi.com، حيث توفر واجهات برمجة تطبيقات مستقرة بمنافذ HTTP، مع إعدادات مهلة افتراضية مناسبة ودعم عالٍ للاستدعاءات المتزامنة المتعددة.

الاختلاف الجوهري 1: مدة بقاء الاتصال وإعدادات المهلة
متطلبات بقاء الاتصال في الاستدعاء المتزامن
يتطلب الاستدعاء المتزامن من العميل إبقاء اتصال HTTP مفتوحاً طوال عملية توليد الصورة، مما يؤدي إلى التحديات التقنية التالية:
| التحدي | التأثير | الحل |
|---|---|---|
| اتصالات خاملة لفترة طويلة | قد تقوم أجهزة الشبكة الوسيطة (NAT، جدار الحماية) بإغلاق الاتصال | ضبط TCP Keep-Alive |
| تعقيد إعدادات المهلة | الحاجة إلى تكوين وقت المهلة بدقة بناءً على الدقة المطلوبة | 1K/2K: 300 ثانية، 4K: 600 ثانية |
| الحساسية لتقلبات الشبكة | سهولة انقطاع الاتصال في بيئات الشبكة الضعيفة | تنفيذ آليات إعادة المحاولة |
| قيود الاتصالات المتزامنة | المتصفحات تقتصر افتراضياً على 6 اتصالات متزامنة كحد أقصى | استخدام استدعاءات من جهة الخادم أو زيادة حوض الاتصالات (Connection Pool) |
مثال على استدعاء متزامن باستخدام Python:
import requests
import time
def generate_image_sync(prompt: str, size: str = "4096x4096") -> dict:
"""
استدعاء متزامن لـ Nano Banana Pro API عبر APIYI لتوليد صورة
الوسائط:
prompt: موجه الصورة
size: حجم الصورة
القيمة المرجعة:
نتيجة استجابة API
"""
start_time = time.time()
# استدعاء متزامن: إبقاء الاتصال مفتوحاً حتى اكتمال التوليد
response = requests.post(
"http://api.apiyi.com:16888/v1/images/generations",
json={
"prompt": prompt,
"size": size,
"model": "nano-banana-pro",
"n": 1,
"response_format": "url" # تدعم APIYI مخرجات URL
},
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=(10, 600) # مهلة الاتصال 10 ثوانٍ، مهلة القراءة 600 ثانية
)
elapsed = time.time() - start_time
print(f"⏱️ الوقت المستغرق في الاستدعاء المتزامن: {elapsed:.2f} ثانية")
print(f"🔗 حالة الاتصال: ظل مفتوحاً لمدة {elapsed:.2f} ثانية")
return response.json()
# مثال على الاستخدام
result = generate_image_sync(
prompt="A futuristic cityscape at sunset",
size="4096x4096"
)
print(f"✅ رابط الصورة: {result['data'][0]['url']}")
ملاحظات أساسية:
- يظل العميل محظوراً (Blocked) تماماً خلال وقت الاستدلال الذي يتراوح بين 100-170 ثانية.
- يظل اتصال HTTP مفتوحاً باستمرار، مما يستهلك موارد النظام.
- إذا لم يتم ضبط إعدادات المهلة بشكل صحيح (مثلاً 60 ثانية)، سينقطع الاتصال قبل اكتمال الاستدلال.
ميزة الاتصال القصير في الاستدعاء غير المتزامن
يقوم الاستدعاء غير المتزامن بإنشاء اتصالات قصيرة فقط عند تقديم المهمة والاستعلام عن الحالة، مما يقلل بشكل كبير من وقت بقاء الاتصال:
| المرحلة | وقت الاتصال | إعداد المهلة |
|---|---|---|
| تقديم المهمة | 1-3 ثوانٍ | 30 ثانية كافية |
| فحص الحالة (Polling) | 1-2 ثانية لكل مرة | 10 ثوانٍ كافية |
| تحميل الصورة | 5-10 ثوانٍ | 60 ثانية كافية |
| الإجمالي | 10-20 ثانية (موزعة) | أقل بكثير من الاستدعاء المتزامن |
مثال على استدعاء غير متزامن باستخدام Python (محاكاة لدعم APIYI المستقبلي):
import requests
import time
def generate_image_async(prompt: str, size: str = "4096x4096") -> str:
"""
استدعاء غير متزامن لـ Nano Banana Pro API لتوليد صورة (ميزة مستقبلية)
الوسائط:
prompt: موجه الصورة
size: حجم الصورة
القيمة المرجعة:
معرف المهمة (Task ID)
"""
# الخطوة 1: تقديم المهمة (اتصال قصير)
response = requests.post(
"http://api.apiyi.com:16888/v1/images/generations/async", # واجهة مستقبلية
json={
"prompt": prompt,
"size": size,
"model": "nano-banana-pro",
"n": 1,
"response_format": "url"
},
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=(10, 30) # مهلة تقديم المهمة 30 ثانية فقط
)
task_data = response.json()
task_id = task_data["task_id"]
print(f"✅ تم تقديم المهمة: {task_id}")
print(f"🔓 تم إغلاق الاتصال، يمكن معالجة مهام أخرى")
return task_id
def poll_task_status(task_id: str, max_wait: int = 300) -> dict:
"""
فحص حالة المهمة بشكل دوري حتى تكتمل
الوسائط:
task_id: معرف المهمة
max_wait: أقصى وقت انتظار (بالثواني)
القيمة المرجعة:
نتائج التوليد
"""
start_time = time.time()
poll_interval = 5 # فحص الحالة كل 5 ثوانٍ
while time.time() - start_time < max_wait:
# الاستعلام عن حالة المهمة (اتصال قصير)
response = requests.get(
f"http://api.apiyi.com:16888/v1/tasks/{task_id}", # واجهة مستقبلية
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=(10, 10) # مهلة الاستعلام 10 ثوانٍ فقط
)
status_data = response.json()
status = status_data["status"]
if status == "completed":
elapsed = time.time() - start_time
print(f"✅ اكتملت المهمة! إجمالي الوقت: {elapsed:.2f} ثانية")
return status_data["result"]
elif status == "failed":
raise Exception(f"فشلت المهمة: {status_data.get('error')}")
else:
print(f"⏳ حالة المهمة: {status}، جاري الانتظار {poll_interval} ثوانٍ للمحاولة مجدداً...")
time.sleep(poll_interval)
raise TimeoutError(f"انتهت مهلة المهمة: {task_id}")
# مثال على الاستخدام
task_id = generate_image_async(
prompt="A serene mountain landscape",
size="4096x4096"
)
# خلال فترة الفحص الدوري، يمكن معالجة مهام أخرى
print("🚀 يمكن معالجة طلبات أخرى بالتزامن...")
# فحص حالة المهمة
result = poll_task_status(task_id, max_wait=600)
print(f"✅ رابط الصورة: {result['data'][0]['url']}")
عرض مثال لنمط استدعاء Webhook (ميزة مستقبلية)
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
# قاموس عالمي لتخزين نتائج المهام
task_results = {}
@app.route('/webhook/image_completed', methods=['POST'])
def handle_webhook():
"""استقبال استدعاء Webhook عند اكتمال المهمة غير المتزامنة من APIYI"""
data = request.json
task_id = data['task_id']
status = data['status']
result = data.get('result')
if status == 'completed':
task_results[task_id] = result
print(f"✅ المهمة {task_id} اكتملت: {result['data'][0]['url']}")
else:
print(f"❌ المهمة {task_id} فشلت: {data.get('error')}")
return jsonify({"received": True}), 200
def generate_image_with_webhook(prompt: str, size: str = "4096x4096") -> str:
"""
توليد صورة بشكل غير متزامن باستخدام نمط Webhook
الوسائط:
prompt: موجه الصورة
size: حجم الصورة
القيمة المرجعة:
معرف المهمة
"""
response = requests.post(
"http://api.apiyi.com:16888/v1/images/generations/async",
json={
"prompt": prompt,
"size": size,
"model": "nano-banana-pro",
"n": 1,
"response_format": "url",
"webhook_url": "https://your-domain.com/webhook/image_completed" # رابط الاستدعاء
},
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=(10, 30)
)
task_id = response.json()["task_id"]
print(f"✅ تم تقديم المهمة: {task_id}")
print(f"📞 سيقوم Webhook بالاتصال بـ: https://your-domain.com/webhook/image_completed")
return task_id
# تشغيل خادم Flask للاستماع لـ Webhook
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
🎯 القيود الحالية: يدعم كل من APIYI و Gemini الرسمي حالياً نمط الاستدعاء المتزامن فقط، ومن المخطط إطلاق ميزات الاستدعاء غير المتزامن في الإصدارات المستقبلية. بالنسبة للسيناريوهات التي تتطلب توليد صور بكثافة عالية، يُنصح باستخدام استدعاءات متزامنة عبر منصة APIYI (apiyi.com) باستخدام الخيوط المتعددة (Multi-threading) أو العمليات المتعددة (Multi-processing)، مع ضبط مهلات زمنية معقولة.
الاختلاف الجوهري 2: القدرة على المعالجة المتزامنة واستهلاك الموارد
قيود التزامن في الاستدعاء المتزامن
يواجه الاستدعاء المتزامن مشكلات ملحوظة في استهلاك الموارد عند العمل في بيئات ذات ضغط عالٍ:
مشكلة حظر الخيط الواحد:
import time
# ❌ خطأ: استدعاء تسلسلي بخيط واحد، إجمالي الوقت = وقت المرة الواحدة × عدد المهام
def generate_multiple_images_sequential(prompts: list) -> list:
results = []
start_time = time.time()
for prompt in prompts:
result = generate_image_sync(prompt, size="4096x4096")
results.append(result)
elapsed = time.time() - start_time
print(f"❌ استغرق التوليد التسلسلي لـ {len(prompts)} صور: {elapsed:.2f} ثانية")
# بفرض 120 ثانية لكل صورة، 10 صور = 1200 ثانية (20 دقيقة!)
return results
تحسين التزامن باستخدام الخيوط المتعددة:
from concurrent.futures import ThreadPoolExecutor, as_completed
import time
# ✅ صحيح: استدعاء متزامن بخيوط متعددة، للاستفادة القصوى من وقت انتظار الإدخال/الإخراج
def generate_multiple_images_concurrent(prompts: list, max_workers: int = 5) -> list:
"""
توليد صور متعددة بشكل متزامن باستخدام الخيوط المتعددة
الوسائط:
prompts: قائمة الموجهات
max_workers: أقصى عدد للخيوط المتزامنة
القيمة المرجعة:
قائمة بنتائج التوليد
"""
results = []
start_time = time.time()
with ThreadPoolExecutor(max_workers=max_workers) as executor:
# تقديم جميع المهام
future_to_prompt = {
executor.submit(generate_image_sync, prompt, "4096x4096"): prompt
for prompt in prompts
}
# انتظار اكتمال جميع المهام
for future in as_completed(future_to_prompt):
prompt = future_to_prompt[future]
try:
result = future.result()
results.append(result)
print(f"✅ اكتمل: {prompt[:30]}...")
except Exception as e:
print(f"❌ فشل: {prompt[:30]}... - {e}")
elapsed = time.time() - start_time
print(f"✅ استغرق التوليد المتزامن لـ {len(prompts)} صور: {elapsed:.2f} ثانية")
# بفرض 120 ثانية لكل صورة، 10 صور ≈ 120-150 ثانية (2-2.5 دقيقة)
return results
# مثال على الاستخدام
prompts = [
"A cyberpunk city at night",
"A serene forest landscape",
"An abstract geometric pattern",
"A futuristic space station",
"A vintage car in the desert",
# ... المزيد من الموجهات
]
results = generate_multiple_images_concurrent(prompts, max_workers=5)
print(f"🎉 تم توليد {len(results)} صورة")
| طريقة التزامن | وقت توليد 10 صور بدقة 4K | استهلاك الموارد | حالات الاستخدام |
|---|---|---|---|
| استدعاء تسلسلي | 1200 ثانية (20 دقيقة) | منخفض (اتصال واحد) | صورة واحدة، توليد فوري |
| خيوط متعددة (5 خيوط) | 250 ثانية (4 دقائق) | متوسط (5 اتصالات) | دفعات صغيرة ومتوسطة (10-50 صورة) |
| عمليات متعددة (10 عمليات) | 150 ثانية (2.5 دقيقة) | عالٍ (10 اتصالات) | دفعات كبيرة (50+ صورة) |
| استدعاء غير متزامن (مستقبلاً) | 120 ثانية + وقت الفحص الدوري | منخفض (اتصالات فحص قصيرة) | دفعات ضخمة (100+ صورة) |
مزايا التزامن في الاستدعاء غير المتزامن
يتمتع الاستدعاء غير المتزامن بمزايا واضحة في سيناريوهات المعالجة بالدفعات:
تقديم بالدفعات + فحص بالدفعات:
def generate_batch_async(prompts: list) -> list:
"""
توليد الصور بالدفعات بشكل غير متزامن (ميزة مستقبلية)
الوسائط:
prompts: قائمة الموجهات
القيمة المرجعة:
قائمة بمعرفات المهام
"""
task_ids = []
# الخطوة 1: تقديم جميع المهام بالدفعات بسرعة (1-3 ثوانٍ لكل مهمة)
for prompt in prompts:
task_id = generate_image_async(prompt, size="4096x4096")
task_ids.append(task_id)
print(f"✅ تم تقديم {len(task_ids)} مهمة، استغرق الأمر حوالي {len(prompts) * 2} ثانية")
# الخطوة 2: فحص حالة المهام بالدفعات
results = []
for task_id in task_ids:
result = poll_task_status(task_id, max_wait=600)
results.append(result)
return results
| المؤشر | استدعاء متزامن (خيوط متعددة) | استدعاء غير متزامن (مستقبلاً) | الفرق |
|---|---|---|---|
| وقت مرحلة التقديم | 1200 ثانية (انتظار محظور) | 20 ثانية (تقديم سريع) | غير المتزامن أسرع بـ 60 مرة |
| إجمالي الوقت | 250 ثانية (5 خيوط) | 120 ثانية + وقت الفحص | غير المتزامن أسرع بمرتين |
| ذروة عدد الاتصالات | 5 اتصالات طويلة | اتصال قصير واحد (عند التقديم) | غير المتزامن يوفر 80% من الاتصالات |
| القدرة على معالجة مهام أخرى | ❌ الخيوط محظورة | ✅ غير محظور تماماً | غير المتزامن أكثر مرونة |

💰 تحسين التكلفة: يوفر Google Gemini API نمط Batch API، الذي يدعم المعالجة غير المتزامنة مع خصم يصل إلى 50% من السعر (السعر القياسي 0.133-0.24 دولار للصورة، بينما Batch API بـ 0.067-0.12 دولار للصورة)، ولكن يجب تقبل وقت تسليم يصل إلى 24 ساعة كحد أقصى. بالنسبة للسيناريوهات التي لا تتطلب توليداً فورياً، يمكن التفكير في استخدام Batch API لتقليل التكاليف.
الاختلاف الجوهري 3: مزايا مخرجات رابط OSS URL في منصة APIYI
مقارنة بين ترميز base64 ومخرجات URL
يدعم Nano Banana Pro API تنسيقين لمخرجات الصور:
| الخاصية | ترميز base64 | مخرجات رابط OSS (حصري لـ APIYI) | التوصية |
|---|---|---|---|
| حجم جسم الاستجابة | 6-8 ميجابايت (صورة بدقة 4K) | 200 بايت (الرابط فقط) | URL ✅ |
| وقت النقل | 5-10 ثوانٍ (أبطأ في الشبكات الضعيفة) | أقل من ثانية واحدة | URL ✅ |
| ذاكرة التخزين المؤقت للمتصفح | ❌ لا يمكن تخزينها | ✅ تخزين HTTP قياسي | URL ✅ |
| تسريع CDN | ❌ لا يمكن استخدامه | ✅ تسريع CDN عالمي | URL ✅ |
| تحسين الصور | ❌ لا يدعم WebP وغيرها | ✅ يدعم تحويل التنسيقات | URL ✅ |
| تحميل تدريجي | ❌ يجب التنزيل بالكامل | ✅ يدعم التحميل التدريجي | URL ✅ |
| أداء الهاتف المحمول | ❌ استهلاك عالٍ للذاكرة | ✅ تدفق تنزيل مُحسّن | URL ✅ |
مشكلات الأداء في ترميز base64:
-
تضخم جسم الاستجابة بنسبة 33%: يؤدي ترميز base64 إلى زيادة حجم البيانات بنسبة 33% تقريبًا.
- صورة 4K الأصلية: حوالي 6 ميجابايت.
- بعد ترميز base64: حوالي 8 ميجابايت.
-
عدم القدرة على الاستفادة من CDN: يتم تضمين سلسلة base64 داخل استجابة JSON، مما يمنع تخزينها مؤقتًا عبر شبكات CDN.
-
الضغط على ذاكرة الهاتف المحمول: يتطلب فك تشفير سلسلة base64 موارد إضافية من الذاكرة ووحدة المعالجة المركزية.
مزايا مخرجات رابط OSS URL من APIYI:
import requests
# ✅ 推荐: 使用 APIYI OSS URL 输出
response = requests.post(
"http://api.apiyi.com:16888/v1/images/generations",
json={
"prompt": "A beautiful sunset over mountains",
"size": "4096x4096",
"model": "nano-banana-pro",
"n": 1,
"response_format": "url" # 指定 URL 输出
},
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=(10, 600)
)
result = response.json()
# 响应体仅包含 URL,大小约 200 字节
print(f"响应体大小: {len(response.content)} 字节")
# 输出: 响应体大小: 234 字节
# OSS URL 示例
image_url = result['data'][0]['url']
print(f"图像 URL: {image_url}")
# 输出: https://apiyi-oss.oss-cn-beijing.aliyuncs.com/nano-banana/abc123.png
# 后续通过标准 HTTP 下载图像,享受 CDN 加速
image_response = requests.get(image_url)
with open("output.png", "wb") as f:
f.write(image_response.content)
مقارنة: مشكلات الأداء في مخرجات base64:
# ❌ 不推荐: base64 编码输出
response = requests.post(
"https://api.example.com/v1/images/generations",
json={
"prompt": "A beautiful sunset over mountains",
"size": "4096x4096",
"model": "nano-banana-pro",
"n": 1,
"response_format": "b64_json" # base64 编码
},
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=(10, 600)
)
result = response.json()
# 响应体包含完整 base64 字符串,大小约 8 MB
print(f"响应体大小: {len(response.content)} 字节")
# 输出: 响应体大小: 8388608 字节 (8 MB!)
# 需要解码 base64 字符串
import base64
image_b64 = result['data'][0]['b64_json']
image_bytes = base64.b64decode(image_b64)
with open("output.png", "wb") as f:
f.write(image_bytes)
| مؤشر المقارنة | ترميز base64 | رابط OSS من APIYI | تحسين الأداء |
|---|---|---|---|
| حجم استجابة API | 8 ميجابايت | 200 بايت | تقليل بنسبة 99.998% |
| وقت استجابة API | 125 ثانية + 5-10 ثوانٍ نقل | 125 ثانية + < 1 ثانية | توفير 5-10 ثوانٍ |
| طريقة تنزيل الصورة | مدمجة في JSON | طلب HTTP مستقل | إمكانية التنزيل المتزامن |
| تخزين المتصفح | غير قابل للتخزين | تخزين HTTP قياسي | فتح فوري عند الزيارة المتكررة |
| تسريع CDN | لا يدعم | عقد CDN عالمية | تسريع الوصول الدولي |
🚀 التكوين الموصى به: عند استدعاء Nano Banana Pro API على منصة APIYI، استخدم دائمًا
"response_format: "url"للحصول على مخرجات رابط OSS بدلاً من ترميز base64. هذا لا يقلل بشكل كبير من حجم استجابة API ووقت النقل فحسب، بل يتيح أيضًا الاستفادة الكاملة من تسريع CDN وتخزين المتصفح المؤقت لتحسين تجربة المستخدم.
الاختلاف الجوهري 4: سيناريوهات التطبيق والخطط المستقبلية
أفضل سيناريوهات الاستخدام للاستدعاء المتزامن
السيناريوهات الموصى بها:
- توليد الصور في الوقت الفعلي: عرض الصور التي تم إنشاؤها فور تقديم المستخدم للموجه.
- معالجة الدفعات الصغيرة: توليد 1-10 صور؛ حيث يمكن للاستدعاء المتزامن تلبية متطلبات الأداء.
- التكامل البسيط: لا حاجة لتنفيذ الاستطلاع (Polling) أو الويب هوك (Webhook)، مما يقلل من تعقيد التطوير.
- التطبيقات التفاعلية: أدوات الرسم بالذكاء الاصطناعي، ومحررات الصور، وغيرها من السيناريوهات التي تتطلب تعليقات فورية.
نمط الكود النموذجي:
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
@app.route('/generate', methods=['POST'])
def generate_image():
"""实时图像生成接口"""
data = request.json
prompt = data['prompt']
size = data.get('size', '1024x1024')
# 同步调用,用户等待生成完成
response = requests.post(
"http://api.apiyi.com:16888/v1/images/generations",
json={
"prompt": prompt,
"size": size,
"model": "nano-banana-pro",
"n": 1,
"response_format": "url"
},
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=(10, 300 if size != '4096x4096' else 600)
)
result = response.json()
return jsonify({
"success": True,
"image_url": result['data'][0]['url']
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
سيناريوهات التطبيق المستقبلية للاستدعاء غير المتزامن
السيناريوهات المناسبة (دعم مستقبلي):
- توليد الصور بالجملة: توليد أكثر من 100 صورة، مثل صور المنتجات للتجارة الإلكترونية أو مكتبات مواد التصميم.
- المهام المجدولة في الخلفية: توليد أنواع معينة من الصور تلقائيًا يوميًا دون الحاجة لاستجابة فورية.
- معالجة منخفضة التكلفة: استخدام Google Batch API للحصول على خصم 50% على السعر، مع قبول وقت تسليم يصل إلى 24 ساعة.
- سيناريوهات التزامن العالي: مئات المستخدمين يرسلون طلبات التوليد في نفس الوقت، لتجنب استنفاد تجمع الاتصالات.
نمط الكود النموذجي (مستقبلاً):
from flask import Flask, request, jsonify
from celery import Celery
import requests
app = Flask(__name__)
celery = Celery('tasks', broker='redis://localhost:6379/0')
@celery.task
def generate_image_task(prompt: str, size: str, user_id: str):
"""Celery 异步任务:生成图像"""
# 提交异步任务到 APIYI
response = requests.post(
"http://api.apiyi.com:16888/v1/images/generations/async", # 未来接口
json={
"prompt": prompt,
"size": size,
"model": "nano-banana-pro",
"n": 1,
"response_format": "url",
"webhook_url": f"https://your-domain.com/webhook/{user_id}"
},
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=(10, 30)
)
task_id = response.json()["task_id"]
return task_id
@app.route('/generate_async', methods=['POST'])
def generate_image_async():
"""异步图像生成接口"""
data = request.json
prompt = data['prompt']
size = data.get('size', '1024x1024')
user_id = data['user_id']
# 提交 Celery 任务,立即返回
task = generate_image_task.delay(prompt, size, user_id)
return jsonify({
"success": True,
"message": "任务已提交,完成后将通过 Webhook 通知",
"task_id": task.id
})
@app.route('/webhook/<user_id>', methods=['POST'])
def handle_webhook(user_id: str):
"""接收 APIYI 异步任务完成的 Webhook 回调"""
data = request.json
task_id = data['task_id']
result = data['result']
# 通知用户图像生成完成 (如发送邮件、推送通知等)
notify_user(user_id, result['data'][0]['url'])
return jsonify({"received": True}), 200
التخطيط المستقبلي لمنصة APIYI
| الوظيفة | الحالة الحالية | التخطيط المستقبلي | الوقت المتوقع |
|---|---|---|---|
| الاستدعاء المتزامن | ✅ مدعوم حاليًا | تحسين مستمر لتكوينات المهلة | – |
| مخرجات رابط OSS URL | ✅ مدعوم حاليًا | إضافة المزيد من عقد CDN | الربع الثاني 2026 |
| الاستدعاء غير المتزامن (استطلاع) | ❌ غير مدعوم | دعم تقديم المهام + استعلام عن الحالة | الربع الثاني 2026 |
| الاستدعاء غير المتزامن (ويب هوك) | ❌ غير مدعوم | دعم إشعارات الويب هوك عند اكتمال المهمة | الربع الثاني 2026 |
| تكامل Batch API | ❌ غير مدعوم | دمج Google Batch API | الربع الرابع 2026 |
💡 نصيحة للمطورين: تخطط منصة APIYI لإطلاق ميزة الاستدعاء غير المتزامن في الربع الثالث من عام 2026، مع دعم تقديم المهام والاستعلام عن الحالة وإشعارات الويب هوك. بالنسبة للمطورين الذين لديهم احتياجات معالجة دفعات حالية، يُنصح باستخدام الاستدعاء المتزامن المتعدد عبر الخيوط (Multithreading)، والحصول على واجهات منافذ HTTP مستقرة وتكوينات مهلة مُحسّنة عبر منصة APIYI على apiyi.com.
الأسئلة الشائعة
س1: لماذا لا يدعم كل من APIYI وGemini الرسمي الاستدعاء غير المتزامن (Async)؟
الأسباب التقنية:
-
قيود البنية التحتية لجوجل: تدعم البنية التحتية الأساسية لـ Google Gemini API حالياً وضع الاستنتاج المتزامن فقط، وتتطلب الاستدعاءات غير المتزامنة أنظمة إضافية لإدارة طوابير المهام والحالات.
-
تعقيد التطوير: يتطلب الاستدعاء غير المتزامن تنفيذ ما يلي:
- إدارة طوابير المهام
- استمرارية حالة المهام (Persistence)
- آلية ربط الويب (Webhook)
- منطق إعادة المحاولة والتعويض عند الفشل
-
أولوية احتياجات المستخدمين: يحتاج معظم المستخدمين إلى إنشاء الصور في الوقت الفعلي، والاستدعاء المتزامن يلبي بالفعل أكثر من 80% من سيناريوهات الاستخدام.
الحلول:
- حالياً: استخدم الاستدعاء المتزامن للواجهات مع تعدد الخيوط (Multi-threading) أو العمليات المتعددة (Multi-processing).
- مستقبلاً: تخطط APIYI لإطلاق ميزة الاستدعاء غير المتزامن في الربع الثاني من عام 2026.
س2: هل سيتم حفظ صور OSS URL من APIYI بشكل دائم؟
سياسة التخزين:
| مدة التخزين | الوصف | حالات الاستخدام المناسبة |
|---|---|---|
| 7 أيام | حفظ افتراضي لمدة 7 أيام، ثم تُحذف تلقائياً | المعاينة المؤقتة، اختبارات التوليد |
| 30 يوماً | يمكن للمشتركين تمديدها إلى 30 يوماً | المشاريع قصيرة الأجل، مواد الحملات الإعلانية |
| دائم | يقوم المستخدم بتنزيلها إلى OSS الخاص به | الاستخدام طويل الأمد، المشاريع التجارية |
الممارسة الموصى بها:
import requests
# توليد الصورة والحصول على الرابط (URL)
result = generate_image_sync(prompt="A beautiful landscape", size="4096x4096")
temp_url = result['data'][0]['url']
print(f"رابط URL مؤقت: {temp_url}")
# تنزيل الصورة محلياً أو إلى OSS الخاص بك
image_response = requests.get(temp_url)
with open("permanent_image.png", "wb") as f:
f.write(image_response.content)
# أو الرفع إلى OSS الخاص بك (مثال على Alibaba Cloud OSS)
import oss2
auth = oss2.Auth('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY')
bucket = oss2.Bucket(auth, 'oss-cn-beijing.aliyuncs.com', 'your-bucket')
bucket.put_object('images/permanent_image.png', image_response.content)
ملاحظة: روابط OSS URL التي توفرها APIYI هي للتخزين المؤقت، وهي مناسبة للمعاينة السريعة والاختبار. بالنسبة للصور التي تحتاج لاستخدامها على المدى الطويل، يرجى تنزيلها إلى مساحتك التخزينية المحلية أو السحابية في الوقت المناسب.
س3: كيف نتجنب انتهاء المهلة (Timeout) عند الاستدعاء المتزامن؟
3 إعدادات رئيسية لتجنب انتهاء المهلة:
-
ضبط وقت المهلة بشكل صحيح:
# ✅ صحيح: ضبط مهلة الاتصال ومهلة القراءة بشكل منفصل timeout=(10, 600) # (مهلة الاتصال 10 ثوانٍ، مهلة القراءة 600 ثانية) # ❌ خطأ: ضبط قيمة واحدة فقط للمهلة timeout=600 # قد يتم تطبيقها على مهلة الاتصال فقط -
استخدام واجهة منفذ HTTP:
# ✅ موصى به: استخدام منفذ HTTP الخاص بـ APIYI لتجنب أعباء مصافحة HTTPS url = "http://api.apiyi.com:16888/v1/images/generations" # ⚠️ اختياري: واجهة HTTPS، تزيد من وقت مصافحة TLS url = "https://api.apiyi.com/v1/images/generations" -
تنفيذ آلية إعادة المحاولة:
from requests.adapters import HTTPAdapter from requests.packages.urllib3.util.retry import Retry # تكوين استراتيجية إعادة المحاولة retry_strategy = Retry( total=3, # إعادة المحاولة 3 مرات كحد أقصى status_forcelist=[429, 500, 502, 503, 504], # إعادة المحاولة فقط لهذه الأكواد backoff_factor=2 # تراجع أسي: 2ث، 4ث، 8ث ) adapter = HTTPAdapter(max_retries=retry_strategy) session = requests.Session() session.mount("http://", adapter) # استخدام session لإرسال الطلب response = session.post( "http://api.apiyi.com:16888/v1/images/generations", json={...}, timeout=(10, 600) )
س4: كيف يمكن استدعاء Nano Banana Pro API مباشرة من الواجهة الأمامية (Frontend)؟
أسباب عدم التوصية بالاستدعاء المباشر من الواجهة الأمامية:
- خطر تسريب مفتاح API: سيكشف كود الواجهة الأمامية مفتاح API الخاص بك لجميع المستخدمين.
- قيود الاتصالات المتزامنة في المتصفح: المتصفحات تسمح بحد أقصى 6 اتصالات متزامنة لنفس النطاق افتراضياً.
- قيود المهلة: مهلة
fetchالافتراضية في المتصفح قصيرة، وقد لا تكفي لإكمال عملية التوليد.
الهيكل الموصى به: نمط الوكيل في الخلفية (Backend Proxy):
// كود الواجهة الأمامية (مثال React)
async function generateImage(prompt, size) {
// استدعاء واجهة الخلفية الخاصة بك
const response = await fetch('https://your-backend.com/api/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_USER_TOKEN' // توكن مصادقة المستخدم
},
body: JSON.stringify({ prompt, size })
});
const result = await response.json();
return result.image_url; // إرجاع رابط OSS URL من APIYI
}
// الاستخدام
const imageUrl = await generateImage("A futuristic city", "4096x4096");
document.getElementById('result-image').src = imageUrl;
# كود الخلفية (مثال Flask)
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
@app.route('/api/generate', methods=['POST'])
def generate():
# التحقق من توكن المستخدم
user_token = request.headers.get('Authorization')
if not verify_user_token(user_token):
return jsonify({"error": "Unauthorized"}), 401
data = request.json
# استدعاء API APIYI من الخلفية (لن يتم كشف مفتاح API للواجهة الأمامية)
response = requests.post(
"http://api.apiyi.com:16888/v1/images/generations",
json={
"prompt": data['prompt'],
"size": data['size'],
"model": "nano-banana-pro",
"n": 1,
"response_format": "url"
},
headers={"Authorization": "Bearer YOUR_APIYI_API_KEY"}, # مخزن بأمان في الخلفية
timeout=(10, 600)
)
result = response.json()
return jsonify({"image_url": result['data'][0]['url']})
ملخص
النقاط الجوهرية للاستدعاء المتزامن وغير المتزامن لـ Nano Banana Pro API:
- خصائص الاستدعاء المتزامن: الحفاظ على اتصال HTTP حتى يكتمل التوليد، مع انتظار يتراوح بين 30-170 ثانية، مما يتطلب إعداد مهلة طويلة (300-600 ثانية).
- مزايا الاستدعاء غير المتزامن: إرجاع معرف المهمة (Task ID) فوراً، عدم حجب العمليات، مناسب للمعالجة الجماعية والمهام الخلفية، ولكن حالياً لا تدعمه APIYI ولا Gemini رسمياً.
- مخرجات OSS URL من APIYI: مقارنة بترميز base64، يقل حجم الاستجابة بنسبة 99.998%، ويدعم تسريع CDN وتخزين المتصفح المؤقت، مما يحسن الأداء بشكل كبير.
- أفضل الممارسات الحالية: استخدم الاستدعاء المتزامن + تعدد الخيوط + مخرجات OSS URL، واحصل على إعدادات مهلة محسنة عبر منفذ HTTP الخاص بـ APIYI.
- الخطط المستقبلية: تخطط APIYI لإطلاق ميزة الاستدعاء غير المتزامن في الربع الثاني من عام 2026، لدعم إرسال المهام، والاستعلام عن الحالة، وطلبات Webhook.
نوصي بالدمج السريع لـ Nano Banana Pro API عبر APIYI (apiyi.com). توفر المنصة واجهة منفذ HTTP محسنة (http://api.apiyi.com:16888/v1)، ومخرجات صور OSS URL حصرية، بالإضافة إلى إعدادات مهلة معقولة تناسب سيناريوهات توليد الصور في الوقت الفعلي والمعالجة الجماعية.
الكاتب: الفريق التقني لـ APIYI | إذا كانت لديك أي أسئلة تقنية، نرحب بزيارة APIYI (apiyi.com) للحصول على المزيد من حلول الوصول إلى نماذج الذكاء الاصطناعي.
