ابدأ بـ بايثون فاست إي بي آي: خطوتك الأولى العملية اليوم
بايثون FastAPI: الأساسيات في مقال واحد — كود حقيقي، مخططات وخطوات ملموسة، مقتطفات من دورة تتكون من 32 درسًا.
أفضل طريقة لتعلم Python FastAPI هي بالممارسة. يضعك هذا المقال على الطريق الصحيح مع مقتطفات عملية مستمدة من دورة تضم 32 درسًا — ما يكفي للحصول على نتيجة أولية اليوم.
tl;dr
- مقدمة وتثبيت
- المسارات والطرق
- Pydantic والتحقق
- حقن التبعيات
- قاعدة البيانات
~$ cat ./parcours.md # Python FastAPI — 10 فصول
01
مقدمة وتثبيت
→ Pourquoi FastAPI ?→ Installer FastAPI et uvicorn+ 1 دروس أخرى
02
المسارات والطرق
→ Path params et query params→ POST, PUT, PATCH, DELETE+ 1 دروس أخرى
03
Pydantic والتحقق
→ BaseModel للطلبات→ Validators والقيود+ 2 دروس أخرى
04
حقن التبعيات
→ Depends - المبدأ→ التبعيات مع yield+ 1 دروس أخرى
05
قاعدة البيانات
→ SQLAlchemy مع FastAPI→ CRUD كامل+ 1 دروس أخرى
06
المصادقة JWT
→ OAuth2 + JWT→ الأدوار والأذونات+ 1 دروس أخرى
07
Async والأداء
→ async vs sync→ BackgroundTasks+ 1 دروس أخرى
08
الاختبارات
→ TestClient و pytest→ تجاوز التبعيات+ 1 دروس أخرى
🏁
المشروع النهائي (+ 2 فصول في الطريق)
→ Tu repars avec un projet concret et démontrable
لماذا FastAPI؟
NOTEالهدف — فهم ما يميز FastAPI عن أطر عمل Python الأخرى ومتى تختاره.
FastAPI في جملة واحدة
إطار عمل Python حديث لبناء واجهات برمجة تطبيقات REST سريعة، مكتوبة بالأنواع ومع توثيق تلقائي، مبني على Starlette (ASGI) وPydantic.
القوى الخارقة الأربع
| القوة | التفاصيل |
|---|---|
| الأداء | دعم Async أصلي عبر ASGI/uvicorn، مشابه لـ Node/Go |
| سلامة الأنواع | تلميحات الأنواع في Python -> تحقق في وقت التشغيل عبر Pydantic |
| التوثيق التلقائي | Swagger UI + ReDoc يُنشآن تلقائيًا |
| تجربة المطور | إكمال تلقائي في IDE، أخطاء واضحة، تبعيات قابلة للحقن |
مقارنة Flask vs FastAPI vs Django
| المعيار | Flask | FastAPI | Django |
|---|---|---|---|
| الأسلوب | Micro | Micro (تركيز على API) | Full-stack |
| دعم Async أصلي | لا (إضافات) | نعم | جزئي (DRF لا) |
| تلميحات الأنواع | لا | نعم (Pydantic) | لا |
| التوثيق التلقائي | لا | نعم (Swagger) | عبر DRF (يدوي) |
| ORM مضمن | لا | لا | نعم (Django ORM) |
| سهولة التعلم | سهل جدًا | سهل | متوسط |
| الأداء (req/s) | ~5k | ~20-30k | ~3k |
مثال صغير: "Hello World"
# فلاسك from flask import Flask app = Flask(__name__) @app.route("/items/<int:item_id>") def get_item(item_id): return {"id": item_id}
# فاست إيه بي آي from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") def get_item(item_id: int): return {"id": item_id} # + تحقق تلقائي، توثيق تلقائي، تلميحات الأنواع
متى تختار FastAPI؟
TIPنعم
- خلفية API REST (خدمات مصغرة)
- تقديم نموذج تعلم آلي
- الحاجة إلى أداء (async)
- فريق يقدر الكتابة بالأنواع
- توثيق OpenAPI مطلوب
WARNINGلا
- تطبيق full-stack مع قوالب HTML ثقيلة (Django)
- سكريبت صغير لمرة واحدة (Flask يكفي)
- فريق منتج بالفعل بإطار عمل آخر
من يستخدم FastAPI؟
النظام البيئي
| المكون | الدور |
|---|---|
| Starlette | إطار ASGI الأساسي |
| Pydantic | التحقق والتسلسل |
| uvicorn | خادم ASGI (للتطوير) |
| gunicorn | مدير العمليات (للإنتاج) |
| SQLAlchemy | ORM (شائع) |
| Alembic | ترحيلات قاعدة البيانات |
الملخص
NOTEللتذكر
- FastAPI = أداء + سلامة الأنواع + توثيق تلقائي
- مبني على Starlette (ASGI) وPydantic
- مثالي لواجهات API والخدمات المصغرة الحديثة
- دعم Async أصلي، أسرع بحوالي 5 مرات من Flask
الخطوة التالية: الجزء 2 — تثبيت FastAPI
النشر بـ Docker والاختبارات
المشروع النهائي • Docker • الاختبارات • CI/CD
NOTEالهدف — إنهاء المشروع: اختبارات pytest، Dockerfile، docker-compose، CI GitHub Actions.
اختبارات التكامل الرئيسية
# tests/test_posts.py import pytest def test_create_post_requires_auth(client): r = client.post("/posts", json={"title": "Test", "content": "Hello world"}) assert r.status_code == 401 def test_create_post(client, auth_headers): r = client.post("/posts", headers=auth_headers, json={ "title": "Mon premier post", "content": "Contenu interessant ici", "tags": ["python", "fastapi"], "published": True }) assert r.status_code == 201 data = r.json() assert data["slug"] == "mon-premier-post" assert len(data["tags"]) == 2 def test_list_posts_only_published(client, auth_headers): client.post("/posts", headers=auth_headers, json={"title": "Draft", "content": "...", "published": False}) client.post("/posts", headers=auth_headers, json={"title": "Published", "content": "...", "published": True}) r = client.get("/posts") assert len(r.json()["items"]) == 1 def test_only_author_can_delete(client): h1 = make_user_and_login(client, "alice", "alice@x.com") h2 = make_user_and_login(client, "bob", "bob@x.com") r = client.post("/posts", headers=h1, json={"title": "Mien", "content": "...", "published": True}) slug = r.json()["slug"] # يحاول Bob حذف منشور Alice r = client.delete(f"/posts/{slug}", headers=h2) assert r.status_code == 403 # يمكن لـ Alice r = client.delete(f"/posts/{slug}", headers=h1) assert r.status_code == 204
conftest.py النهائي
import pytest from fastapi.testclient import TestClient from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from app.main import app from app.db import Base, get_db TestEngine = create_engine("sqlite:///./test.db", connect_args={"check_same_thread": False}) TestSession = sessionmaker(bind=TestEngine) def override_db(): db = TestSession() try: yield db finally: db.close() app.dependency_overrides[get_db] = override_db @pytest.fixture(autouse=True) def reset_db(): Base.metadata.create_all(bind=TestEngine) yield Base.metadata.drop_all(bind=TestEngine) @pytest.fixture def client(): return TestClient(app) @pytest.fixture def auth_headers(client): client.post("/auth/register", json={ "email": "test@x.com", "username": "test", "password": "secret123" }) r = client.post("/auth/login", data={ "username": "test@x.com", "password": "secret123" }) return {"Authorization": f'Bearer {r.json()["access_token"]}'}
Dockerfile
FROM python:3.11-slim AS builder WORKDIR /build COPY requirements.txt . RUN pip install --user --no-cache-dir -r requirements.txt FROM python:3.11-slim RUN useradd -m app USER app WORKDIR /home/app ENV PATH=/home/app/.local/bin:$PATH COPY --from=builder /root/.local /home/app/.local COPY --chown=app:app . . EXPOSE 8000 HEALTHCHECK CMD curl -fsS http://localhost:8000/health || exit 1 ENTRYPOINT ["./entrypoint.sh"] CMD ["gunicorn", "-c", "gunicorn.conf.py", "app.main:app"]
docker-compose.yml
services:
api:
build: .
ports:
- "8000:8000"
environment:
DATABASE_URL: postgresql://blog:pwd@db/blogdb
SECRET_KEY: change-me-in-prod
REFRESH_SECRET_KEY: change-me-too
depends_on:
db: {condition: service_healthy}
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: blog
POSTGRES_PASSWORD: pwd
POSTGRES_DB: blogdb
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U blog"]
interval: 5s
retries: 5
volumes:
pgdata:CI/CD GitHub Actions
# .github/workflows/ci.yml name: CI on: push: branches: [main] pull_request: jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: {python-version: "3.11"} - run: pip install -r requirements.txt - run: pip install pytest pytest-cov httpx - run: pytest --cov=app --cov-report=xml - uses: codecov/codecov-action@v4 build: needs: test runs-on: ubuntu-latest if: github.ref == "refs/heads/main" steps: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/build-push-action@v5 with: push: true tags: ghcr.io/${{ github.repository }}:latest
التشغيل في الإنتاج
# محلي كامل docker-compose up -d docker-compose logs -f api docker-compose exec api alembic upgrade head # زيارة # http://localhost:8000/docs # http://localhost:8000/redoc
WebSockets مع FastAPI
NOTEالهدف — بناء دردشة في الوقت الفعلي باستخدام WebSocket الأصلي في FastAPI.
Hello WebSocket
from fastapi import FastAPI, WebSocket, WebSocketDisconnect app = FastAPI() @app.websocket("/ws") async def websocket_endpoint(ws: WebSocket): await ws.accept() try: while True: data = await ws.receive_text() await ws.send_text(f"Echo: {data}") except WebSocketDisconnect: print("Client deconnecte")
اختبار سريع باستخدام wscat
npm install -g wscat
wscat -c ws://localhost:8000/ws
> Hello
< Echo: HelloConnection Manager
class ConnectionManager: def __init__(self): self.active: list[WebSocket] = [] async def connect(self, ws: WebSocket): await ws.accept() self.active.append(ws) def disconnect(self, ws: WebSocket): self.active.remove(ws) async def broadcast(self, message: str): for connection in self.active: try: await connection.send_text(message) except: pass manager = ConnectionManager()
بث الدردشة
@app.websocket("/chat/{username}") async def chat(ws: WebSocket, username: str): await manager.connect(ws) await manager.broadcast(f">> {username} a rejoint") try: while True: msg = await ws.receive_text() await manager.broadcast(f"[{username}] {msg}") except WebSocketDisconnect: manager.disconnect(ws) await manager.broadcast(f"<< {username} a quitte")
إرسال JSON
@app.websocket("/json") async def json_ws(ws: WebSocket): await ws.accept() try: while True: data = await ws.receive_json() await ws.send_json({"echo": data, "server_time": str(datetime.now())}) except WebSocketDisconnect: pass
مصادقة WebSocket
from fastapi import WebSocketException, status @app.websocket("/ws") async def ws(ws: WebSocket, token: str): try: payload = decode_token(token) user_id = payload["sub"] except: raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION) await ws.accept() await ws.send_text(f"Connecte en tant que {user_id}") ... # العميل: ws://localhost:8000/ws?token=eyJ...
va-plus-loin
يغطي هذا المقال المقتطفات الأكثر فائدة — الدورة الكاملة Python FastAPI (10 فصول، 32 درسًا، تمارين مصححة ومشروع نهائي) تأخذك إلى النهاية.
./acceder-au-cours-complet cours gratuit : Vibe Codingالأسئلة الشائعة
كم من الوقت يستغرق تعلم Python FastAPI؟
مع تقدم منظم (10 فصول، 32 درسًا قصيرًا وعمليًا)، يمكن الوصول إلى مستوى تشغيلي في بضعة أسابيع بمعدل 30 إلى 60 دقيقة يوميًا. المهم هو ممارسة كل مفهوم فورًا.
هل هناك متطلبات مسبقة؟
تكفي أساسيات الحاسوب. إذا كنت تعرف استخدام الطرفية وقراءة كود بسيط، فأنت جاهز.
من أين أبدأ عمليًا؟
أعد تنفيذ الأوامر في هذا المقال، ثم تابع الدورة الكاملة Python FastAPI: فهي تربط الـ 32 درسًا بالترتيب، مع تمارين ومشروع نهائي.
./a-lire-aussi
→ Lance-toi en Portfolio IA SEO Vercel : ton premier pas concret aujourd'hui→ IA Stripe GitHub SaaS en pratique : le code et les commandes qui comptent vraiment→ Python Requests APIs expliqué simplement (avec schémas et vrai code)📬 هل تريد تلقي هذا النوع من الأدلة كل أسبوع؟ اشترك مجانًا — كود حقيقي، بدون كلام زائد.