الخطوة 5 في الواجهة الخلفية: التكامل مع OpenAI
استبدل ردّ البوت الثابت في الكود باستجابة حقيقية من الذكاء الاصطناعي عبر OpenAI.
ما ستتعلمه
- تحميل متغيرات البيئة باستخدام
python-dotenv - استدعاء واجهة Chat Completions من OpenAI
- التعامل مع أخطاء API
- بث الاستجابات (اختياري)
الخطوة 1: احصل على مفتاح OpenAI API
- انتقل إلى https://platform.openai.com/api-keys
- أنشئ حسابًا أو سجّل الدخول
- انقر على "Create new secret key"
- انسخ المفتاح (يبدأ بـ
sk-...)
الخطوة 2: إعداد ملف .env
cd aiproject/backend
cp app/.env.example app/.env
حرّر ملف app/.env وضع مفتاحك الفعلي مكان القيمة:
OPENAI_API_KEY=sk-proj-your-actual-key-here
إذا كنت تستخدم Docker: يُحمّل docker-compose.yml ملف .env هذا تلقائيًا داخل الحاوية. لا حاجة إلى أي إعداد إضافي.
الخطوة 3: أضف .env إلى .gitignore
echo ".env" >> .gitignore
بهذا تضمن ألا يصل مفتاحك السري إلى commit عن غير قصد.
الخطوة 4: تحميل متغيرات البيئة
حدّث ملف backend/app/__init__.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from dotenv import load_dotenv
load_dotenv()
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///chat.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.init_app(app)
from .routes import api
app.register_blueprint(api, url_prefix="/api")
with app.app_context():
db.create_all()
return app
if __name__ == "__main__":
app = create_app()
app.run(debug=True, port=5000)
يقرأ الاستدعاء load_dotenv() ملف .env ويجعل محتواه متاحًا عبر os.getenv().
الخطوة 5: تحديث routes.py لدعم OpenAI
from flask import Blueprint, request, jsonify
from . import db
from .models import Message
from openai import OpenAI
import os
api = Blueprint("api", __name__)
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
@api.route("/status")
def status():
return jsonify({"status": "ok"})
@api.route("/messages", methods=["GET"])
def get_messages():
messages = Message.query.order_by(Message.timestamp.asc()).all()
return jsonify([msg.to_dict() for msg in messages])
@api.route("/chat", methods=["POST"])
def chat():
data = request.get_json()
user_message = data.get("message", "")
if not user_message:
return jsonify({"error": "Message is required"}), 400
user_msg = Message(content=user_message, sender="user")
db.session.add(user_msg)
db.session.commit()
try:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": "You are a helpful assistant.",
},
{"role": "user", "content": user_message},
],
)
ai_reply = response.choices[0].message.content
ai_msg = Message(content=ai_reply, sender="ai")
db.session.add(ai_msg)
db.session.commit()
return jsonify({
"user_message": user_msg.to_dict(),
"ai_message": ai_msg.to_dict(),
})
except Exception as e:
return jsonify({"error": str(e)}), 500
الخطوة 6: اختبره
cd aiproject/backend
source venv/bin/activate
python app/__init__.py
في طرفية أخرى:
curl -X POST http://127.0.0.1:5000/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "What is the capital of France?"}'
الاستجابة المتوقعة (ردّ الذكاء الاصطناعي الفعلي):
{
"user_message": {"id": 1, "content": "What is the capital of France?", "sender": "user", ...},
"ai_message": {"id": 2, "content": "The capital of France is Paris.", "sender": "ai", ...}
}
كيف يعمل استدعاء OpenAI
response = client.chat.completions.create(
model="gpt-4o-mini", # أي نموذج ذكاء اصطناعي تستخدم
messages=[ # سجل المحادثة
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": user_message},
],
)
model: أي نموذج ذكاء اصطناعي تستخدمه.gpt-4o-miniسريع ورخيص.messages: سياق المحادثة. رسالةsystemتحدد شخصية الذكاء الاصطناعي، ورسالةuserهي السؤال.response.choices[0].message.content: يستخرج نص ردّ الذكاء الاصطناعي.
التعامل مع الأخطاء
تلتقط كتلة try/except أي أخطاء من API:
- مفتاح API غير صالح ← خطأ مصادقة
- تجاوز حد الطلبات المسموح ← طلبات كثيرة جدًا
- خطأ في الشبكة ← تعذّر الوصول إلى OpenAI
إذا حدث خطأ، تُرجع API {"error": "..."} برمز الحالة 500 بدلًا من أن تتعطل.
الخطوة 7: محاكاة OpenAI في الاختبارات
اختباراتك تستدعي حاليًا واجهة OpenAI API الحقيقية، وهذا يهدر المال ويستغرق وقتًا طويلًا. بدلًا من ذلك، حاكِ API — استبدلها بنسخة وهمية تُرجع ردًّا جاهزًا.
هذه مهارة بالغة الأهمية: لا تدع اختباراتك تعتمد على خدمات خارجية أبدًا.
حدّث اختبارك لتحاكي OpenAI:
from unittest.mock import patch
@patch("app.routes.client.chat.completions.create")
def test_chat_with_mock_openai(mock_openai, client):
mock_openai.return_value.choices = [
MockChoice(MockMessage("Mock AI reply"))
]
response = client.post("/api/chat", json={"message": "Hello"})
assert response.status_code == 200
data = response.get_json()
assert data["ai_message"]["content"] == "Mock AI reply"
أضف أصنافًا مساعدة في أعلى ملف الاختبار:
class MockMessage:
def __init__(self, content):
self.content = content
class MockChoice:
def __init__(self, message):
self.message = message
الآن تعمل اختباراتك فورًا ودون تكلفة — لا حاجة إلى مفتاح API، ولا اتصالات بالشبكة.
التحقق
- أرسل سؤالًا واحصل على استجابة حقيقية من الذكاء الاصطناعي
- أرسل رسالة فارغة واحصل على خطأ 400
- افحص
instance/chat.dbلتتأكد من حفظ الرسائل - شغّل
pytest tests/ -v— ينبغي أن تنجح الاختبارات دون مفتاح API حقيقي