التثبيت وإعداد البيئة — مدير الحزم السريع UV
بيئة التطوير الجيدة كمطبخ مجهز بالكامل — المكونات (التبعيات) متوفرة في ثوانٍ، الموقد (الخادم) يُشعل بنقرة واحدة، والوصفة (هيكل المشروع) منظمة ترتيباً جيداً.
1. ما ستتعلمه
- تثبيت UV والأوامر الأساسية: سير عمل
uv initوuv addوuv run - إنشاء هيكل مشروع PriceTracker: بنية الدليل واصطلاحات التسمية
- إعدادات خادم تطوير Uvicorn:
--reloadو--hostو--portو--workers - إدارة متغيرات البيئة
.envوالتكامل مع python-dotenv - استخدم
uv run uvicornلبدء خدمة التطوير بنقرة واحدة
2. القصة الحقيقية لـ Alice
(1) نقطة الألم: pip بطيء كالحلزون عند تثبيت التبعيات
استخدمت Alice تثبيت التبعيات لمشروع FastAPI باستخدام pip، واستغرق الأمر ثلاث دقائق لينتهي. وما زاد الأمر سوءاً، أن Bob في الفريق كان يستخدم Python 3.11، بينما Alice كانت تستخدم 3.12 — عدم توافق الإصدار تسبب في تعارضات متكررة في بيئاتهم الافتراضية. في كل مرة يعمل pip install -r requirements.txt، يكون الأمر كاللعب باليانصيب — لا تعرف أبداً ما إذا سيفشل بسبب تعارض إصدار مع ملف قفل ما.
(2) حل مشكلة UV
UV هو مدير حزم بايثون مكتوب بـ Rust من فريق Astral. يثبّت التبعيات أسرع بـ 10 إلى 100 مرة من pip، ويتميز بإدارة بيئات افتراضية مدمجة والتبديل بين إصدارات بايثون، ويسمح لك بتهيئة مشروع بأمر واحد.
# تهيئة المشروع وإضافة FastAPI دفعة واحدة
uv init pricetracker
cd pricetracker
uv add fastapi uvicorn
uv run uvicorn app.main:app --reload
(3) العائد
انخفض زمن تثبيت تبعيات Alice من 3 دقائق إلى 3 ثوانٍ؛ Bob وAlice لديهما بيئات متطابقة (الإصدارات مقفلة في uv.lock)، وانخفضت أزمنة بناء CI/CD بنسبة 80%.
3. أساسيات مدير حزم UV
(1) مرجع سريع لأوامر UV الأساسية
| الأمر | الوظيفة | المقابل في pip |
|---|---|---|
uv init |
تهيئة المشروع | إنشاء venv + requirements.txt يدوياً |
uv add <pkg> |
إضافة تبعية إلى pyproject.toml | pip install + تحديث requirements.txt يدوياً |
uv remove <pkg> |
إزالة تبعية | pip uninstall + تحديث يدوي |
uv run <cmd> |
تشغيل أوامر في البيئة الافتراضية | source venv/bin/activate && cmd |
uv sync |
مزامنة جميع التبعيات | pip install -r requirements.txt |
uv lock |
قفل إصدارات التبعيات | pip freeze > requirements.txt |
uv python install 3.12 |
تثبيت Python | pyenv install 3.12 |
(1) ▶ مثال: تهيئة مشروع UV
# إنشاء دليل المشروع
uv init pricetracker
cd pricetracker
# هذا ينشئ:
# pricetracker/
# pyproject.toml
# .python-version
# hello.py
# .venv/ (بيئة افتراضية تُنشأ تلقائياً)
Output:
Initialized project pricetracker
(2) ▶ مثال: إضافة تبعية FastAPI
# إضافة FastAPI وUvicorn
uv add fastapi uvicorn[standard]
# فحص pyproject.toml
cat pyproject.toml
Output (مقتطف من pyproject.toml):
[project]
name = "pricetracker"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"fastapi>=0.115.0",
"uvicorn[standard]>=0.30.0",
]
(2) مقارنة بين UV وpip وPoetry
| البُعد | UV | pip | Poetry |
|---|---|---|---|
| سرعة التثبيت | أسرع بـ 10-100 مرة | المعيار المرجعي | أسرع بـ 2-5 مرة |
| ملف القفل | uv.lock |
لا يوجد | poetry.lock |
| البيئة الافتراضية | إدارة تلقائية | venv يدوي |
إدارة تلقائية |
| إدارة إصدار Python | مدمج | لا يوجد | يتطلب pyenv |
| ملف الإعداد | pyproject.toml |
requirements.txt |
pyproject.toml |
| نواة Rust | نعم | لا | لا |
4. هيكل مشروع PriceTracker
(1) تصميم بنية الدليل
graph TD
Root[pricetracker/] --> App[app/]
App --> Main[__init__.py]
App --> MainPy[main.py]
App --> Api[api/]
Api --> Routes[routes/]
Routes --> Products[products.py]
Routes --> Prices[prices.py]
Routes --> Auth[auth.py]
App --> Models[models/]
App --> Schemas[schemas/]
App --> Services[services/]
App --> Core[core/]
Core --> Config[config.py]
Core --> Security[security.py]
App --> Db[db.py]
Root --> Tests[tests/]
Root --> Alembic[alembic/]
Root --> Docker[docker/]
Root --> Env[.env]
Root --> Pyproject[pyproject.toml]
| الدليل | المسؤوليات | الوصف |
|---|---|---|
app/ |
حزمة التطبيق الرئيسية | جميع كود الأعمال |
app/api/routes/ |
وحدة التوجيه | تقسيم نقاط النهاية حسب الوظيفة |
app/models/ |
نماذج SQLAlchemy | تعيينات جداول قاعدة البيانات |
app/schemas/ |
نماذج Pydantic | التحقق من الطلب/الاستجابة |
app/services/ |
منطق الأعمال | طبقة التخزين وطبقة الخدمة |
app/core/ |
الإعداد الأساسي | الإعداد، الأمان، التبعيات |
tests/ |
الاختبار | مجموعة اختبار pytest |
alembic/ |
ترحيل قاعدة البيانات | سكربتات ترحيل Alembic |
docker/ |
إعداد الحاويات | Dockerfile + Compose |
(1) ▶ مثال: إنشاء هيكل المشروع
# إنشاء جميع الدلائل
mkdir -p app/api/routes app/models app/schemas app/services app/core
mkdir -p tests alembic docker
# إنشاء ملفات __init__.py
touch app/__init__.py app/api/__init__.py app/api/routes/__init__.py
touch app/models/__init__.py app/schemas/__init__.py
touch app/services/__init__.py app/core/__init__.py
touch tests/__init__.py
الناتج:
CONTAINER ID IMAGE STATUS
abc123 latest Up 2 hours
(2) ▶ مثال: تطبيق FastAPI مصغّر app/main.py
from fastapi import FastAPI
app = FastAPI(
title="PriceTracker API",
description="خدمة تتبع أسعار SaaS للتجارة الإلكترونية",
version="0.1.0",
)
@app.get("/health")
async def health_check():
return {"status": "healthy", "service": "pricetracker"}
الناتج:
# تم تعريف الدالة بنجاح
5. خادم تطوير Uvicorn
(1) المعاملات الرئيسية لـ Uvicorn
| المعامل | القيمة الافتراضية | الوصف |
|---|---|---|
--host |
127.0.0.1 |
عنوان الاستماع؛ 0.0.0.0 يسمح بالوصول الخارجي |
--port |
8000 |
منفذ الاستماع |
--reload |
False |
إعادة تشغيل تلقائية عند تغيير الملفات (للتطوير فقط) |
--reload-dir |
. |
الدلائل المراقبة؛ يمكن إدخال عدة |
--workers |
1 |
عدد عمليات العامل (للإنتاج؛ يتعارض مع --reload) |
--log-level |
info |
مستوى السجل |
(1) ▶ مثال: البدء في وضع التطوير
# البدء مع إعادة التحميل الساخنة - إعادة تشغيل تلقائية عند تغيير الكود
uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
Output:
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: Started reloader process
INFO: Started server process
INFO: Waiting for application startup.
INFO: Application startup complete.
(2) ▶ مثال: البدء في وضع الإنتاج
# الإنتاج: عمليات عامل متعددة، بدون إعادة تحميل
uv run uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
الناتو:
# تم تنفيذ الأمر بنجاح
(2) مقارنة إعدادات Uvicorn للتطوير مقابل الإنتاج
| الإعداد | بيئة التطوير | بيئة الإنتاج |
|---|---|---|
--reload |
مفعّل | معطّل |
--workers |
1 | عدد أنوية المعالج x 2 + 1 |
--host |
127.0.0.1 | 0.0.0.0 |
--log-level |
debug | info/warning |
| وكيل أمامي | لا يوجد | Nginx/Traefik |
6. إدارة متغيرات البيئة
(1) ملف .env وpython-dotenv
متغيرات البيئة مبدأ أساسي في تطبيق الـ 12-Factor؛ يجب عدم ترميز الإعدادات الحساسة (مثل كلمات مرور قاعدة البيانات ومفاتيح JWT) في الكود أبداً.
(1) ▶ مثال: إنشاء ملف .env
# .env - لا ترفع هذا الملف أبداً إلى git!
APP_NAME=PriceTracker
DEBUG=true
DATABASE_URL=postgresql+asyncpg://pricetracker:secret@localhost:5432/pricetracker
REDIS_URL=redis://localhost:6379/0
SECRET_KEY=your-super-secret-key-change-in-production
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
الناتج:
// تم التنفيذ بنجاح
(2) ▶ مثال: قراءة متغيرات البيئة باستخدام Pydantic Settings
# app/core/config.py
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "PriceTracker"
debug: bool = False
database_url: str = "postgresql+asyncpg://localhost/pricetracker"
redis_url: str = "redis://localhost:6379/0"
secret_key: str = "change-me-in-production"
algorithm: str = "HS256"
access_token_expire_minutes: int = 30
model_config = {"env_file": ".env", "env_file_encoding": "utf-8"}
settings = Settings()
الناتج:
# تم التنفيذ بنجاح
(3) ▶ مثال: استخدام الإعداد في FastAPI
# app/main.py
from fastapi import FastAPI
from app.core.config import settings
app = FastAPI(
title=settings.app_name,
debug=settings.debug,
)
@app.get("/info")
async def app_info():
return {
"app": settings.app_name,
"debug": settings.debug,
"database": settings.database_url.split("@")[-1], # إخفاء بيانات الاعتماد
}
الناتج:
# تم تعريف الدالة بنجاح
(2) عناصر ضرورية لـ .gitignore
# أضف إلى .gitignore
.env
.env.local
.env.production
.venv/
__pycache__/
*.pyc
| الملف | يُرفع | السبب |
|---|---|---|
.env |
لا | يحتوي على معلومات حساسة |
.env.example |
نعم | قالب مرجعي للفريق |
uv.lock |
نعم | قفل إصدارات التبعيات |
pyproject.toml |
نعم | إعداد المشروع |
7. مثال شامل
بالجمع بين إدارة حزم UV وإعداد Pydantic Settings وبدء Uvicorn، يوضح هذا الدليل العملية الكاملة من تهيئة المشروع إلى نشر الخدمة.
# تبعيات pyproject.toml: fastapi, uvicorn, pydantic-settings
from fastapi import FastAPI
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "PriceTracker"
debug: bool = False
database_url: str = "postgresql+asyncpg://user:pass@localhost/pricetracker"
model_config = {"env_file": ".env"}
settings = Settings()
app = FastAPI(title=settings.app_name, debug=settings.debug)
@app.get("/health")
async def health():
return {"status": "ok", "app": settings.app_name}
@app.get("/info")
async def info():
return {"app": settings.app_name, "debug": settings.debug}
# البدء: uv run uvicorn app.main:app --reload
الناتج:
GET /health → {"status":"ok","app":"PriceTracker"}
GET /info → {"app":"PriceTracker","debug":false}
❓أسئلة شائعة
uv.lock والبيئات الافتراضية؛ واستخدام pip جنباً إلى جنب معه قد يسبب تعارضات في التبعيات. التزم بسير عمل uv add/uv run.powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex".📖ملخص
- UV مكتوب بـ Rust؛ يثبّت التبعيات أسرع بـ 10 إلى 100 مرة من pip ويشمل بيئات افتراضية مدمجة وإدارة إصدارات بايثون.
- مشروع PriceTracker يستخدم بنية طبقية من خمس طبقات: api/routes، models، schemas، services، core
- يستخدم Uvicorn
--reloadلإعادة التحميل الساخنة في التطوير و--workersللتشغيل متعدد العمليات في الإنتاج .env+ Pydantic Settings: إدارة متغيرات البيئة؛ لا ترمّز الإعدادات الحساسة أبداً في الكودuv run uvicorn app.main:app --reloadأطلق بيئة تطوير كاملة بأمر واحد
📝تمارين
- تمرين أساسي (الصعوبة ⭐): أنشئ مشروعاً باستخدام
uv init، أضف تبعيات FastAPI وUvicorn، وشغّل أول نقطة نهاية "Hello World". تلميح:uv add fastapi uvicorn - تمرين متقدم (الصعوبة: ⭐⭐): أنشئ بنية دلائل مشروع PriceTracker، واكتب نقطة نهاية
app/main.pyتتضمن نقطة النهاية/health، واستخدمuv run uvicornللبدء والتحقق. تلميح: راجع مخطط بنية الدلائل في هذا الدرس. - تحدٍ (الصعوبة: ⭐⭐⭐): استخدم Pydantic Settings لإنشاء فئة إعداد تقرأ من ملف
.env، اقرأDATABASE_URLوSECRET_KEY، وأرجع اسم التطبيق في نقطة النهاية/info(دون كشف السر). تلميح:pip install pydantic-settings، أيuv add pydantic-settings
---|



