rest api python backend, web service programming

بناء واجهة برمجة تطبيقات API ببايثون لبيع خدماتك: دليل الفريلانسر

|

تعلّم كيف تبني واجهة برمجة تطبيقات API احترافية ببايثون وإطار العمل FastAPI، وتحوّل مهاراتك وأدواتك إلى خدمةٍ تبيعها للمطورين والشركات.

عدد الكلمات: ~١٩٠٠ · مدة القراءة: ١٠ دقائق

بناء API ببايثون لبيع خدماتك

كيف تحوّل أداواتك وسكريبتاتك إلى خدمةٍ برمجيةٍ تبيعها للمطورين والشركات


ملاحظة للقارئ: هذا المقال مستقلٌّ تماماً ويمكنك تطبيق كل ما فيه دون قراءة مقالاتٍ سابقة. لكن إذا لم تكن قد تعاملت مع مفهوم الـ Backend في بايثون من قبل، فننصحك بمراجعة مقالتنا: تحويل موقعك الثابت HTML إلى موقع ديناميكي ببايثون وفلاسك.

لديك سكريبت بايثون يُنجز شيئاً مفيداً — ربما يُحلّل النصوص، أو يُحوّل العملات، أو يُولّد تقاريراً، أو يستخرج البيانات من مواقع الويب. حتى الآن هذا السكريبت يعمل على جهازك فقط، ولا يستطيع أحدٌ غيرك استخدامه إلا بتثبيت بايثون وتشغيل الكود يدوياً.

ماذا لو استطعت تحويل هذا السكريبت إلى خدمةٍ يستخدمها أي مطوّرٍ أو تطبيقٍ في العالم بطلبٍ واحد؟ ماذا لو كنت تتقاضى رسوماً مقابل كل طلبٍ أو اشتراكاً شهرياً؟ هذا بالضبط ما يُتيحه بناء واجهة برمجة التطبيقات REST API ببايثون. في هذا المقال من منصة ذي يزن، سنبني API احترافيةً كاملةً باستخدام إطار العمل فاست إيه بي آي FastAPI، ونتعلم كيف نحميها بمفاتيح الوصول ونوثّقها تلقائياً.

 

ما هي واجهة برمجة التطبيقات API ولماذا تهمّك؟

واجهة برمجة التطبيقات API اختصارٌ للمصطلح الإنكليزي Application Programming Interface، وهي ببساطةٍ شديدة: طريقةٌ معياريةٌ تتيح لبرنامجٍ ما التحدّث مع برنامجٍ آخر عبر الإنترنت. حين يعرض تطبيق الطقس درجة الحرارة، فهو يتحدّث مع API. حين يدفع مستخدمٌ ببطاقته الائتمانية، التطبيق يُرسل طلباً لـ API شركة الدفع.

نمط واجهة برمجة التطبيقات الأكثر شيوعاً اليوم يُعرف بـ REST API اختصاراً لـ Representational State Transfer، ويعتمد على بروتوكول HTTP نفسه الذي يحرّك الويب. كل طلبٍ يصل عبر رابطٍ URL محدد، ويحمل بياناتٍ بصيغة JSON أي تنسيق بيانات JavaScript Object Notation، ويعود بردٍّ واضح.

الـ API هي اللغة المشتركة بين التطبيقات. من يملك API مفيدةً يملك خدمةً يمكن بيعها لأي مطوّرٍ بصرف النظر عن اللغة البرمجية التي يستخدمها.

api developer laptop code

لماذا FastAPI وليس Flask أو Django؟

في مقالاتٍ سابقةٍ من هذه السلسلة تعرّفنا على إطار العمل فلاسك Flask وإطار العمل جانغو Django. كلاهما قادرٌ على بناء APIs، لكن إطار العمل فاست إيه بي آي FastAPI صُمِّم لهذا الغرض تحديداً ويتميّز بثلاث مزايا تجعله الخيار الأفضل لبيع الخدمات البرمجية:

  • السرعة: يُعدّ FastAPI من أسرع أطر عمل بايثون في العالم، إذ يُنافس Go وNode.js في الأداء بفضل اعتماده على البرمجة غير المتزامنة Asynchronous.
  • التوثيق التلقائي: يُولّد FastAPI توثيقاً تفاعلياً لواجهة برمجة التطبيقات تلقائياً دون كتابة سطرٍ واحد إضافي. عميلك يستطيع تجربة الـ API مباشرةً من المتصفح.
  • التحقق التلقائي من البيانات: يتحقق من أن البيانات الواردة صحيحةٌ قبل وصولها لكودك، مما يوفّر عليك عشرات الأسطر من كود التحقق اليدوي.
الميزة فلاسك Flask جانغو Django REST فاست إيه بي آي FastAPI
الأداء والسرعة متوسط متوسط ممتازٌ جداً
التوثيق التلقائي يدوي جزئي تلقائيٌّ كامل
التحقق من البيانات يدوي عبر نماذج جانغو تلقائيٌّ عبر Pydantic
سهولة التعلم سهل معقد نسبياً سهلٌ وواضح
الأنسب لـ مواقع ويب بسيطة تطبيقاتٌ كاملة APIs وخدمات مصغّرة

التثبيت والإعداد: دقيقتان وتبدأ

ثبّت FastAPI مع خادم الويب أوفيكورن Uvicorn الذي يُشغّله:

pip install fastapi uvicorn

أنشئ ملفاً باسم main.py واكتب فيه أبسط API ممكنة:

from fastapi import FastAPI

app = FastAPI(
    title="خدمة تحليل النصوص",
    description="API لتحليل النصوص العربية والإنكليزية",
    version="1.0.0"
)

@app.get("/")
def root():
    return {"message": "مرحباً! الـ API تعمل بنجاح."}

@app.get("/health")
def health_check():
    return {"status": "ok"}

شغّل الخادم:

uvicorn main:app --reload

افتح متصفحك على http://127.0.0.1:8000/docs وستجد توثيقاً تفاعلياً كاملاً لواجهة برمجة التطبيقات الخاصة بك جاهزاً دون أن تكتب حرفاً واحداً إضافياً. هذه هي معجزة FastAPI.

بناء API حقيقية: خدمة تحليل النصوص

لنبنِ مثالاً عملياً — API لتحليل النصوص يمكن بيعها للمدوّنين والمترجمين وصنّاع المحتوى. ستقبل نصاً وتُرجع إحصاءاتٍ مفيدة عنه:

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import re
from datetime import datetime

app = FastAPI(
    title="خدمة تحليل النصوص — ذي يزن",
    description="""
    API احترافية لتحليل النصوص العربية والإنكليزية.
    تُقدّم إحصاءاتٍ دقيقةً تساعد المترجمين وصنّاع المحتوى.
    """,
    version="1.0.0"
)

# نموذج بيانات الطلب — FastAPI يتحقق منه تلقائياً
class TextRequest(BaseModel):
    text: str
    language: str = "auto"  # auto, arabic, english

# نموذج بيانات الردّ
class TextAnalysis(BaseModel):
    word_count: int
    char_count: int
    char_no_spaces: int
    sentence_count: int
    paragraph_count: int
    avg_word_length: float
    reading_time_minutes: float
    language_detected: str
    timestamp: str

def detect_language(text: str) -> str:
    """كشف اللغة بناءً على نسبة الأحرف العربية"""
    arabic_chars = len(re.findall(r'[\u0600-\u06FF]', text))
    total_chars = len(re.findall(r'[a-zA-Z\u0600-\u06FF]', text))
    if total_chars == 0:
        return "unknown"
    return "arabic" if arabic_chars / total_chars > 0.5 else "english"

@app.post("/analyze", response_model=TextAnalysis)
def analyze_text(request: TextRequest):
    """
    تحليل نصٍّ وإرجاع إحصاءاتٍ مفصّلة.
    - **text**: النص المراد تحليله (مطلوب)
    - **language**: لغة النص (اختياري — auto للكشف التلقائي)
    """
    text = request.text.strip()

    if not text:
        raise HTTPException(
            status_code=400,
            detail="النص فارغٌ. يرجى إرسال نصٍّ صالح."
        )

    if len(text) > 50000:
        raise HTTPException(
            status_code=413,
            detail="النص أطول من الحدّ المسموح به (50,000 حرف)."
        )

    # الإحصاءات
    words = text.split()
    word_count = len(words)
    char_count = len(text)
    char_no_spaces = len(text.replace(" ", ""))
    sentences = re.split(r'[.!?؟،\n]+', text)
    sentence_count = len([s for s in sentences if s.strip()])
    paragraphs = [p for p in text.split('\n\n') if p.strip()]
    paragraph_count = max(len(paragraphs), 1)
    avg_word_length = round(
        sum(len(w) for w in words) / word_count, 2
    ) if word_count > 0 else 0

    # وقت القراءة: 200 كلمة/دقيقة للإنكليزية، 150 للعربية
    lang = request.language if request.language != "auto" else detect_language(text)
    wpm = 150 if lang == "arabic" else 200
    reading_time = round(word_count / wpm, 2)

    return TextAnalysis(
        word_count=word_count,
        char_count=char_count,
        char_no_spaces=char_no_spaces,
        sentence_count=sentence_count,
        paragraph_count=paragraph_count,
        avg_word_length=avg_word_length,
        reading_time_minutes=reading_time,
        language_detected=lang,
        timestamp=datetime.now().isoformat()
    )

جرّب إرسال طلبٍ لهذه الـ API عبر Python:

import requests

response = requests.post(
    "http://127.0.0.1:8000/analyze",
    json={
        "text": "بايثون لغةٌ برمجيةٌ رائعة. تتميّز بسهولة قراءتها ووضوح بنيتها.",
        "language": "auto"
    }
)

print(response.json())
# النتيجة:
# {
#   "word_count": 9,
#   "char_count": 65,
#   "reading_time_minutes": 0.06,
#   "language_detected": "arabic",
#   ...
# }

حماية الـ API بمفاتيح الوصول API Keys

الـ API المفتوحة لا يمكن بيعها — يجب حمايتها بمفاتيح وصولٍ يحصل عليها كل عميلٍ بعد الاشتراك. إليك الطريقة الأبسط والأكثر شيوعاً:

from fastapi import FastAPI, HTTPException, Security
from fastapi.security.api_key import APIKeyHeader
import secrets

app = FastAPI()

# تعريف مكان البحث عن المفتاح — في ترويسة الطلب Header
API_KEY_HEADER = APIKeyHeader(name="X-API-Key", auto_error=False)

# في المشاريع الحقيقية هذه تُخزَّن في قاعدة البيانات
VALID_API_KEYS = {
    "key_abc123xyz": {"client": "أحمد محمد", "plan": "basic", "requests_limit": 1000},
    "key_def456uvw": {"client": "شركة التقنية", "plan": "pro", "requests_limit": 10000},
}

def verify_api_key(api_key: str = Security(API_KEY_HEADER)):
    """التحقق من صحة مفتاح الوصول"""
    if api_key is None:
        raise HTTPException(
            status_code=401,
            detail="مفتاح الوصول مفقود. أضفه في ترويسة الطلب: X-API-Key"
        )
    if api_key not in VALID_API_KEYS:
        raise HTTPException(
            status_code=403,
            detail="مفتاح الوصول غير صالح أو منتهي الصلاحية."
        )
    return VALID_API_KEYS[api_key]

# استخدام التحقق في المسارات
@app.post("/analyze")
def analyze_text(
    request: TextRequest,
    client_info: dict = Security(verify_api_key)
):
    # client_info يحتوي بيانات العميل المسجّل
    print(f"طلبٌ من العميل: {client_info['client']} — الباقة: {client_info['plan']}")
    # ... بقية الكود

الآن كل طلبٍ يصل بدون مفتاحٍ صالحٍ يُردّ برسالة خطأٍ واضحة. والمطوّر الذي يريد استخدام خدمتك يُرسل مفتاحه هكذا:

import requests

response = requests.post(
    "https://api.yourdomain.com/analyze",
    headers={"X-API-Key": "key_abc123xyz"},
    json={"text": "النص المراد تحليله..."}
)

print(response.json())

أنواع طلبات HTTP: GET وPOST وPUT وDELETE

كل عمليةٍ على بيانات الـ API تستخدم نوعاً مختلفاً من طلبات HTTP. هذا ليس اعتباطياً بل اتفاقيةٌ يتبعها جميع المطورين في العالم:

نوع الطلب الوظيفة مثالٌ عملي
GET جلب البيانات GET /clients — جلب قائمة العملاء
POST إنشاء سجلٍّ جديد POST /analyze — إرسال نصٍّ للتحليل
PUT تحديث سجلٍّ كامل PUT /clients/5 — تحديث بيانات عميل
DELETE حذف سجل DELETE /clients/5 — حذف عميل

مثالٌ على API كاملة لإدارة قائمة المهام تُظهر الأنواع الأربعة:

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional

app = FastAPI()

# تخزينٌ مؤقتٌ في الذاكرة — في المشاريع الحقيقية استخدم قاعدة بيانات
tasks_db = {}
next_id = 1

class Task(BaseModel):
    title: str
    description: Optional[str] = None
    is_done: bool = False

@app.get("/tasks")
def get_all_tasks():
    """جلب جميع المهام"""
    return list(tasks_db.values())

@app.get("/tasks/{task_id}")
def get_task(task_id: int):
    """جلب مهمةٍ واحدة بمعرّفها"""
    if task_id not in tasks_db:
        raise HTTPException(status_code=404, detail="المهمة غير موجودة")
    return tasks_db[task_id]

@app.post("/tasks", status_code=201)
def create_task(task: Task):
    """إنشاء مهمةٍ جديدة"""
    global next_id
    task_data = {"id": next_id, **task.dict()}
    tasks_db[next_id] = task_data
    next_id += 1
    return task_data

@app.put("/tasks/{task_id}")
def update_task(task_id: int, task: Task):
    """تحديث مهمةٍ موجودة"""
    if task_id not in tasks_db:
        raise HTTPException(status_code=404, detail="المهمة غير موجودة")
    tasks_db[task_id].update(task.dict())
    return tasks_db[task_id]

@app.delete("/tasks/{task_id}")
def delete_task(task_id: int):
    """حذف مهمة"""
    if task_id not in tasks_db:
        raise HTTPException(status_code=404, detail="المهمة غير موجودة")
    del tasks_db[task_id]
    return {"message": f"تم حذف المهمة {task_id} بنجاح"}

التوثيق التلقائي: هديتك المجانية من FastAPI

حين تُشغّل تطبيق FastAPI، تحصل تلقائياً على واجهتَي توثيقٍ تفاعليتين جاهزتين:

  • واجهة Swagger UI على الرابط /docs — تُتيح تجربة الـ API مباشرةً من المتصفح بنقرةٍ واحدة.
  • واجهة ReDoc على الرابط /redoc — توثيقٌ أنيقٌ وقابلٌ للطباعة، مثاليٌّ لمشاركته مع العملاء.

هذان الرابطان يتحدّثان عن خدمتك بشكلٍ احترافيٍّ جاهز. بدلاً من كتابة وثيقة PDF لتشرح للعميل كيف يستخدم API الخاصة بك، ترسل له رابط /docs ويجرّبها بنفسه. هذا وحده يوفّر عليك ساعاتٍ من العمل مع كل عميل.

كيف تبيع API الخاصة بك؟ نماذج تسعيرٍ عملية

بعد بناء الـ API وحمايتها، يبقى السؤال الأهم: كيف تحوّلها إلى دخل؟ هناك ثلاثة نماذج تسعيرٍ شائعة يستخدمها مطوّرو الـ APIs:

النموذج الأول — الدفع بحسب الاستخدام Pay Per Use: كل طلبٍ يُكلّف مبلغاً صغيراً. مثلاً 0.001 دولار لكل تحليل نصٍّ. مناسبٌ للعملاء الذين يستخدمون الخدمة بشكلٍ متقطع.

النموذج الثاني — الاشتراك الشهري Subscription: باقاتٌ ثابتة بعدد طلباتٍ محدّد. الباقة الأساسية 1,000 طلب/شهر بـ 9 دولارات. مناسبٌ لمن يريد دخلاً ثابتاً متوقعاً.

النموذج الثالث — الترخيص المؤسسي Enterprise: تبيع API بترخيصٍ سنويٍّ ثابتٍ للشركات التي تريد نشرها على خوادمها الخاصة. أعلى سعراً وأقل عملاءً.

منصات مثل RapidAPI وAPI Layer تُتيح لك نشر API الخاصة بك ووضع تسعيرها وإدارة الاشتراكات والمدفوعات تلقائياً، مما يُغنيك عن بناء نظام دفعٍ من الصفر في البداية.

الفريلانسر الذكي لا يبيع وقته فقط، بل يبني أصولاً رقمية تعمل وتُدرّ دخلاً حتى وهو نائم. الـ API هي أقرب شيءٍ لهذا المفهوم في عالم البرمجة.

rest api python backend, web service programming

نشر الـ API على الإنترنت

لنشر تطبيق FastAPI على الإنترنت، أضف ملف requirements.txt يحتوي تبعيات مشروعك:

fastapi==0.111.0
uvicorn==0.30.0
pydantic==2.7.0

وملف Procfile لبيئات الاستضافة السحابية:

web: uvicorn main:app --host 0.0.0.0 --port $PORT

منصة ريندر Render ومنصة ريلواي Railway تقبلان هذا الإعداد مباشرةً. ادفع المشروع على GitHub واربطه بالمنصة وستعمل الـ API على رابطٍ عامٍّ خلال دقائق.


خلاصة المقال والخطوة القادمة

اليوم تعلّمنا كيف نبني واجهة برمجة تطبيقاتٍ REST API احترافيةً ببايثون وإطار العمل فاست إيه بي آي FastAPI، وكيف نحميها بمفاتيح الوصول، ووثّقناها تلقائياً دون جهدٍ إضافي، وتعرّفنا على نماذج البيع والتسعير. الـ API ليست مجرد أداةٍ تقنية — هي نموذج عملٍ كاملٌ يتيح لك تحويل أي مهارةٍ أو خوارزميةٍ إلى منتجٍ رقميٍّ قابلٍ للبيع.

الخطوة التالية الموصى بها:

بنينا API رائعةً — لكن ماذا لو أردنا إضافة الذكاء الاصطناعي إليها؟ ماذا لو أصبحت API الخاصة بك تستخدم نماذج اللغة الكبيرة Large Language Models لتحليل النصوص وتوليدها بدلاً من الخوارزميات اليدوية؟ في المقال القادم نتعلم كيف ندمج نماذج الذكاء الاصطناعي داخل مشاريعنا ببايثون.

تابع معنا المقال الثالث عشر: كيف تستخدم نماذج الذكاء الاصطناعي داخل مشاريعك ببايثون.


المراجع والمصادر:

  1. التوثيق الرسمي لـ FastAPI: FastAPI Official Documentation
  2. دليل مكتبة Pydantic للتحقق من البيانات: Pydantic Documentation
  3. دليل HTTP Methods على موزيلا MDN: MDN Web Docs — HTTP request methods
  4. منصة RapidAPI لنشر وبيع الـ APIs: RapidAPI Marketplace

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *