مدرس Python متكيف بالذكاء الاصطناعي باستخدام FastAPI وSQLite

Share:

مدرس Python متكيف بالذكاء الاصطناعي باستخدام FastAPI وSQLite

أنشئ API مركّزًا يستقبل حل تمرين Python، ويطلب ملاحظات تعليمية منظّمة، ويخزّن مستوى إتقان الموضوع في SQLite، ثم يعيد استجابة متحققة إلى العميل.

ما الذي ستبنيه

ينشئ هذا الشرح العملي PyMentor، وهو API صغير للتدريس المتكيف لممارسة Python. يرسل العميل معرّف المتعلم والموضوع والتمرين وحل الكود. يقرأ API درجة الإتقان السابقة للمتعلم في هذا الموضوع، ويطلب من نموذج OpenAI الذي تم إعداده تقديم ملاحظات موجهة للتعليم، ويتحقق من JSON المُعاد، ويحسب درجة إتقان جديدة ضمن نطاق محدد، ويسجل المحاولة في SQLite.

الهدف محدد عمدًا. لا تشغّل الخدمة كود المتعلم، ولا تقرر ما إذا كان المتعلم قد اجتاز مقررًا، ولا تحل محل المدرّس. بل توفر سير عمل متكررًا للملاحظات: تحديد مشكلة محتملة واحدة، وتقدير جانب مفيد من المحاولة، وتقديم تلميح تالٍ، وطرح سؤال، والاحتفاظ بسجل تقدم بسيط. تحافظ هذه الحدود على وضوح المثال وتمنع عملية API من التعامل مع أي كود Python مُرسل باعتباره مدخلات قابلة للتنفيذ.

لا يتضمن سياق البحث المتاح وثائق توافق رسمية لـ FastAPI أو Pydantic أو SQLite أو OpenAI SDK. لذلك، يتجنب هذا الدليل الادعاء بأن نموذجًا أو إصدار حزمة معينًا متاح للجميع. اضبط اسم النموذج عبر متغير بيئة، ثم تحقق من توافق الحزم وAPI بالرجوع إلى الوثائق الرسمية للإصدارات التي تثبتها.

المتطلبات المسبقة

  • Python ٣.١٠ أو إصدار أحدث.
  • مفتاح OpenAI API يتم توفيره عبر متغير بيئة أو ملف تطوير محلي.
  • واجهة طرفية وعميل HTTP مثل curl.
  • إلمام أساسي بدوال Python وJSON وطلبات HTTP.

أنشئ مجلدًا للمشروع وبيئة افتراضية. أحرف متابعة السطر أدناه مقصودة، لكي يبقى أمر التثبيت صالحًا في واجهة POSIX shell.

mkdir pymentor
cd pymentor
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install fastapi "uvicorn[standard]" openai pydantic-settings
mkdir -p app

في Windows PowerShell، فعّل البيئة باستخدام ..venvScriptsActivate.ps1. أنشئ ملفًا باسم .env في جذر المشروع:

OPENAI_API_KEY=replace-with-your-api-key
OPENAI_MODEL=replace-with-a-model-available-to-your-account
DATABASE_PATH=pymentor.db
MAX_CODE_CHARACTERS=12000

لا ترفع هذا الملف إلى مستودعك. أضف الإدخالات التالية إلى .gitignore قبل البدء:

.venv/
__pycache__/
*.pyc
.env
pymentor.db
.pytest_cache/

الخطوة ١: إنشاء وحدة التطبيق

للوضوح، يحافظ هذا الشرح العملي على التطبيق كاملًا في ملف واحد. يمكن لمشروع إنتاجي لاحقًا فصل الإعدادات والمخططات والتخزين الدائم وPrompting والمسارات في وحدات مخصصة. قرار التصميم الأهم حاضر بالفعل: بيانات الطلب وملاحظات النموذج والبيانات المخزنة، لكل منها بنية صريحة.

أنشئ app/main.py والصق الكود التالي. يقيّد نموذج الطلب البيانات المقبولة من العميل. ويشكّل نموذج الملاحظات عقد التطبيق لمخرجات النموذج. تستخدم عمليات الكتابة في SQLite معاملات بدلًا من إدراج السلاسل النصية، لذا لا تُدرج القيم التي يقدمها المتعلم في نص SQL.

import json
import sqlite3
from contextlib import asynccontextmanager
from datetime import UTC, datetime
from functools import lru_cache
from pathlib import Path
from uuid import uuid4from fastapi import FastAPI, HTTPException, Request, status
from fastapi.concurrency import run_in_threadpool
from openai import OpenAI
from pydantic import BaseModel, Field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDictclass Settings(BaseSettings):
openai_api_key: str = Field(min_length=1)
openai_model: str = Field(min_length=1)
database_path: Path = Path("pymentor.db")
max_code_characters: int = Field(default=12000, ge=500, le=50000)model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
extra="ignore",
)@lru_cache
def get_settings() -> Settings:
return Settings()class TutorRequest(BaseModel):
learner_id: str = Field(
min_length=3,
max_length=80,
pattern=r"^[A-Za-z0-9_-]+$",
)
topic: str = Field(min_length=2, max_length=80)
exercise: str = Field(min_length=10, max_length=3000)
code: str = Field(min_length=1, max_length=50000)
learner_question: str | None = Field(default=None, max_length=1500)
allow_solution: bool = False@field_validator("code")
@classmethod
def reject_null_bytes(cls, value: str) -> str:
if "x00" in value:
raise ValueError("code must not contain null bytes")
return valueclass ModelFeedback(BaseModel):
summary: str = Field(min_length=1, max_length=600)
strengths: list[str] = Field(min_length=1, max_length=4)
misconceptions: list[str] = Field(min_length=1, max_length=3)
next_hint: str = Field(min_length=1, max_length=700)
socratic_question: str = Field(min_length=1, max_length=400)
suggested_concepts: list[str] = Field(min_length=1, max_length=4)
mastery_delta: int = Field(ge=-20, le=20)
needs_human_review: boolclass TutorResponse(BaseModel):
attempt_id: str
topic: str
previous_mastery: int = Field(ge=0, le=100)
current_mastery: int = Field(ge=0, le=100)
feedback: ModelFeedbackclass ProgressStore:
def __init__(self, database_path: Path) -> None:
self.database_path = database_pathdef connect(self) -> sqlite3.Connection:
connection = sqlite3.connect(self.database_path)
connection.row_factory = sqlite3.Row
return connectiondef initialize(self) -> None:
with self.connect() as connection:
connection.executescript(
"""
CREATE TABLE IF NOT EXISTS learner_progress (
learner_id TEXT NOT NULL,
topic TEXT NOT NULL,
mastery INTEGER NOT NULL CHECK (mastery BETWEEN 0 AND 100),
updated_at TEXT NOT NULL,
PRIMARY KEY (learner_id, topic)
);CREATE TABLE IF NOT EXISTS tutor_attempts (
attempt_id TEXT PRIMARY KEY,
learner_id TEXT NOT NULL,
topic TEXT NOT NULL,
exercise TEXT NOT NULL,
submitted_code TEXT NOT NULL,
feedback_json TEXT NOT NULL,
created_at TEXT NOT NULL
);
"""
)def get_mastery(self, learner_id: str, topic: str) -> int:
with self.connect()...

تابع القراءة

سجل دخولك مجاناً لقراءة المقال كاملاً والوصول إلى أدوات الذكاء الاصطناعي.

تسجيل الدخول / إنشاء حساب

هل كان هذا الشرح مفيداً؟

مرشد بوابة الذكاء الاصطناعي
نشط للخدمة
مرحباً بك في بوابة الذكاء الاصطناعي! أنا مرشدك هنا لمساعدتك في فهم خدمات المنصة، باقات التشغيل وخطط الضمان المالي. كيف يمكنني إرشادك اليوم؟