آموزش‌های کلادفلر به‌زودی در این بخش قرار داده می‌شود.

آموزش کار با uv؛ ابزار جدید مدیریت پکیج پایتون و جایگزین pip

فکر کنین دارین روی یه پروژه پایتونی کار میکنین و مدام با نصب پکیج‌ها، مدیریت محیط‌های مجازی و چیزهایی شبیه این سر و کار دارین. uv اومده تا این کارها رو با یه روش متفاوت انجام بده. پس بیایین با هم ببینیم این uv اصلا چی هست و چه کارهایی انجام میده.

uv دقیقا چیه؟ یه ابزار همه‌کاره؟

خب، بذارین ساده بگم. uv یک ابزار مدیریت پکیج و پروژه برای پایتون هست که با زبان برنامه‌نویسی راست (Rust) نوشته شده. سازنده‌های این ابزار، یعنی شرکت Astral، همون‌هایی هستن که ابزار معروف Ruff رو ساختن که یک لینتر و فرمتر خیلی سریع برای پایتونه.

هدف اصلی از ساخت uv این بوده که یک جایگزین سریع برای ابزارهای رایجی مثل pip و pip-tools باشه. یعنی شما میتونین بدون اینکه لازم باشه چیز جدیدی یاد بگیرین یا فرایندهای کاریتون رو تغییر بدین، از uv استفاده کنین.

سازنده‌هاش میگن که uv بخشی از یک هدف بزرگتره به اسم «کارگو برای پایتون» (Cargo for Python). کارگو ابزار مدیریت پروژه و پکیج توی دنیای راست هست که خیلی سریع و قابل اعتماده. حالا تیم Astral میخواد یه همچین تجربه‌ای رو برای برنامه‌نویس‌های پایتون هم به وجود بیاره؛ یعنی یک ابزار واحد که هم سریع باشه، هم قابل اعتماد و هم استفاده ازش راحت باشه.

جالبه بدونین که uv به صورت یک فایل اجرایی تنها (static binary) عرضه میشه. این یعنی برای نصب و استفاده ازش، خودتون نیازی به پایتون یا راست ندارین. این ویژگی کمک میکنه که دیگه درگیر مدیریت نصب pip روی نسخه‌های مختلف پایتون (مثلا pip در مقابل pip3 یا pip3.7) نباشین.

سرعت، مهمترین ادعای uv

یکی از اصلی‌ترین چیزهایی که سازنده‌های uv روش تاکید دارن، سرعته. اونها معیارهایی رو منتشر کردن که نشون میده uv چقدر میتونه سریع‌تر از ابزارهای دیگه باشه.

  • مقایسه با pip و pip-tools: طبق بنچمارک‌ها، uv موقعی که کش (cache) خالی باشه، حدود ۸ تا ۱۰ برابر سریع‌تر از pip و pip-tools عمل میکنه. حالا کش چیه؟ فکر کنین یه انباری دارین که پکیج‌هایی که قبلا دانلود کردین رو اونجا نگه میدارین. دفعه بعدی که به همون پکیج نیاز داشتین، به جای دانلود دوباره، از همون انباری برمیدارین. به این انباری میگن کش. وقتی این کش گرم باشه (یعنی قبلا پکیج‌ها دانلود شدن)، سرعت uv حتی بیشتر هم میشه و به ۸۰ تا ۱۱۵ برابر سریع‌تر از ابزارهای مشابه میرسه.
  • ساخت محیط مجازی (Virtual Environment): برای ساخت محیط‌های مجازی هم uv خیلی سریع‌تره. گفته شده که حدود ۸۰ برابر سریع‌تر از python -m venv و ۷ برابر سریع‌تر از virtualenv عمل میکنه، اونم در حالی که خودش هیچ وابستگی مستقیمی به پایتون نداره.

برای بهینه کردن سرعت و مصرف حافظه، uv از یک کش سراسری برای ماژول‌ها استفاده میکنه تا از دانلود و ساخت مجدد وابستگی‌ها جلوگیری کنه. همچنین روی فایل‌سیستم‌هایی که پشتیبانی میکنن، از تکنیک‌هایی مثل Copy-on-Write و hardlink استفاده میکنه تا فضای کمتری روی دیسک اشغال بشه.

ویژگی‌های کلیدی uv در یک نگاه

اگه بخوایم ویژگی‌های اصلی uv رو لیست کنیم، به موارد زیر میرسیم:

  • جایگزین مستقیم: طراحی شده تا جایگزین ابزارهایی مثل pip, pip-tools, virtualenv و حتی ابزارهای دیگه‌ای مثل pipx, poetry, pyenv و twine بشه.
  • سرعت بالا: همونطور که گفتیم، ۱۰ تا ۱۰۰ برابر سریع‌تر از pip.
  • بهینه‌سازی فضای دیسک: با استفاده از کش سراسری، از نگهداری پکیج‌های تکراری جلوگیری میکنه.
  • نصب آسان: بدون نیاز به نصب راست یا پایتون، با دستوراتی مثل curl یا حتی خود pip نصب میشه.
  • پشتیبانی گسترده: روی سیستم‌عامل‌های مک، لینوکس و ویندوز کار میکنه.
  • مدیریت وابستگی پیشرفته: قابلیت‌هایی مثل بازنویسی نسخه‌های وابستگی (overrides)، استراتژی‌های مختلف برای حل وابستگی‌ها و رزولور (resolver) قدرتمند برای پیدا کردن تضادها داره.
  • پشتیبانی از قابلیت‌های مدرن: از نصب‌های قابل ویرایش (editable installs)، وابستگی‌های گیت (Git)، وابستگی‌های از طریق URL، وابستگی‌های محلی و فایل‌های محدودیت (constraint files) پشتیبانی میکنه.
  • مدیریت پروژه و اسکریپت: نه تنها پکیج‌ها، بلکه خود نسخه‌های پایتون رو هم مدیریت میکنه و میتونه اسکریپت‌هایی که وابستگی‌هاشون داخل خود فایل تعریف شده رو اجرا کنه.
  • فایل قفل سراسری (Universal Lockfile): مدیریت پروژه رو با فایل‌های قفل پایدار و قابل حمل ساده‌تر میکنه.
  • پشتیبانی از Workspace: برای پروژه‌های بزرگ و مقیاس‌پذیر، از فضاهای کاری به سبک کارگو پشتیبانی میکنه.

چطوری uv رو نصب کنیم؟

نصب uv خیلی ساده‌ست و چند تا راه مختلف داره.

  1. استفاده از نصب‌کننده‌های مستقل (Standalone Installers): این راحت‌ترین راهه و نیازی به ابزار دیگه‌ای نداره.
  • روی مک و لینوکس:
curl -LsSf https://astral.sh/uv/install.sh | sh
  • روی ویندوز (با PowerShell):
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
  1. نصب از طریق PyPI: اگه پایتون و pip رو روی سیستمتون دارین، میتونین از این روش استفاده کنین.
  • با pip:
pip install uv
  • یا با pipx:
pipx install uv
  1. روش‌های دیگه:
  • با Homebrew (روی مک):
brew install uv
  • با Pacman (روی توزیع‌های لینوکس مثل آرچ):
pacman -S uv

نکته مهم: بعد از نصب، ممکنه لازم باشه مسیر نصب uv رو به متغیر محیطی PATH سیستمتون اضافه کنین تا بتونین از هر جایی توی ترمینال بهش دسترسی داشته باشین.

  • برای لینوکس و مک:
export PATH="$HOME/.local/bin:$PATH"
  • برای ویندوز: باید به صورت گرافیکی به بخش Environment Variables برین و مسیر %USERPROFILE%\.local\bin رو به متغیر Path اضافه کنین.

بعد از اینکه نصب تموم شد، میتونین با زدن دستور uv توی ترمینال مطمئن بشین که درست نصب شده. اگه با نصب‌کننده مستقل نصب کردین، میتونین با دستور زیر خودش رو آپدیت کنین:

uv self update

استفاده از uv به سبک pip

یکی از بهترین ویژگی‌های uv اینه که لازم نیست از همون اول همه چیز رو از نو یاد بگیرین. uv یک رابط کاربری به اسم uv pip داره که دقیقا مثل دستورات pip و pip-tools کار میکنه. اینطوری میتونین خیلی سریع و راحت به uv مهاجرت کنین.

ساخت محیط مجازی

برای ساخت یه محیط مجازی جدید، کافیه این دستور رو بزنین:

uv venv

این دستور یه پوشه به اسم .venv میسازه. بعدش باید فعالش کنین:

  • روی مک و لینوکس:
source .venv/bin/activate
  • روی ویندوز:
.venv\Scripts\activate

نصب پکیج‌ها

نصب پکیج‌ها هم دقیقا مثل pip هست، فقط اولش uv میاد:

# نصب پکیج فلسک
uv pip install flask

# نصب از روی فایل requirements.txt
uv pip install -r requirements.txt

# نصب پروژه فعلی در حالت قابل ویرایش
uv pip install -e .

# نصب پروژه فعلی از روی دیسک
uv pip install "package @ ."

# نصب فلسک با قابلیت اضافی dotenv
uv pip install "flask[dotenv]"

کامپایل و همگام‌سازی وابستگی‌ها

اگه با pip-tools کار کرده باشین، با دستورهای pip-compile و pip-sync آشنا هستین. uv هم معادل اینها رو داره:

  • uv pip compile: این دستور مثل pip-compile عمل میکنه. یعنی یک فایل ورودی مثل requirements.in رو میگیره و یک فایل requirements.txt قفل‌شده و دقیق ازش میسازه.
uv pip compile docs/requirements.in --output-file docs/requirements.txt

یه قابلیت جالب اینجا پرچم --universal هست. با این پرچم، uv یک فایل requirements.txt میسازه که مستقل از پلتفرمه.

  • uv pip sync: این دستور هم مثل pip-sync هست. یعنی محیط مجازی شما رو دقیقا با پکیج‌هایی که توی فایل requirements.txt لیست شدن، همگام میکنه. نه یکی کمتر، نه یکی بیشتر.
uv pip sync docs/requirements.txt

مدیریت کامل پروژه با uv

علاوه بر جایگزینی pip، uv میتونه مثل ابزارهایی مثل Poetry یا Rye کل پروژه شما رو مدیریت کنه. بیایین یه مثال رو با هم ببینیم.

  1. شروع یک پروژه جدید:
    با دستور init یه پروژه جدید به اسم example میسازیم.
$ uv init example
Initialized project `example` at `/home/user/example`
  1. اضافه کردن وابستگی:
    وارد پوشه پروژه میشیم و پکیج ruff رو به عنوان وابستگی اضافه میکنیم.
$ cd example
$ uv add ruff
Creating virtual environment at: .venv
Resolved 2 packages in 170ms
Built example @ file:///home/user/example
Prepared 2 packages in 627ms
Installed 2 packages in 1ms
+ example==0.1.0 (from file:///home/user/example)
+ ruff==0.5.0
  1. اجرای دستورات در محیط پروژه:
    با دستور run میتونیم دستورات رو داخل محیط مجازی پروژه‌مون اجرا کنیم.
$ uv run ruff check
All checks passed!
  1. قفل کردن وابستگی‌ها:
    با دستور lock میتونیم یه فایل قفل (lockfile) از وابستگی‌هامون بسازیم تا مطمئن بشیم همیشه همین نسخه‌ها نصب میشن.
$ uv lock
Resolved 2 packages in 0.33ms
  1. همگام‌سازی محیط:
    و در نهایت با دستور sync محیط مجازی رو با فایل قفل همگام میکنیم.
$ uv sync
Resolved 2 packages in 0.70ms
Audited 1 package in 0.02ms

مدیریت خود پایتون با uv

یکی از قابلیت‌های خیلی جالب uv اینه که میتونه نسخه‌های مختلف پایتون رو براتون نصب و مدیریت کنه. این یعنی میتونه کار ابزاری مثل pyenv رو هم انجام بده. البته استفاده از این قابلیت اختیاریه و uv با پایتونی که از قبل روی سیستمتون نصب کردین هم به خوبی کار میکنه.

  • نصب چند نسخه پایتون:
$ uv python install 3.10 3.11 3.12
Searching for Python versions matching: Python 3.10
Searching for Python versions matching: Python 3.11
Searching for Python versions matching: Python 3.12
Installed 3 versions in 3.42s
+ cpython-3.10.14-macos-aarch64-none
+ cpython-3.11.9-macos-aarch64-none
+ cpython-3.12.4-macos-aarch64-none
  • استفاده از یک نسخه خاص موقع نیاز:
    میتونین موقع ساخت محیط مجازی یا اجرای یک دستور، مشخص کنین که از کدوم نسخه پایتون استفاده بشه. uv اگه اون نسخه رو نداشته باشه، خودش دانلودش میکنه.
# ساخت محیط مجازی با پایتون 3.12.0
$ uv venv --python 3.12.0
Using CPython 3.12.0
Creating virtual environment at: .venv

# اجرای یک دستور با نسخه 3.8 از PyPy
$ uv run --python [email protected] -- python --version
Python 3.8.16 ...
  • پین کردن نسخه پایتون برای یک پوشه:
    میتونین برای یک پوشه یا پروژه خاص، یک نسخه پایتون رو «پین» کنین. uv این کار رو با ساختن یک فایل به اسم .python-version انجام میده.
$ uv python pin 3.11
Pinned `.python-version` to `3.11`

uv برای اسکریپت‌ها و ابزارهای خط فرمان

uv میتونه کار ابزاری مثل pipx رو هم انجام بده، یعنی اجرای ابزارهای خط فرمانی که به صورت پکیج پایتون منتشر شدن.

اجرای اسکریپت‌های تک‌فایلی

فرض کنین یه اسکریپت پایتون دارین و میخوایین وابستگی‌هاش رو هم کنارش تعریف کنین.

  1. یه فایل پایتون به اسم example.py میسازیم:
import requests; print(requests.get("https://astral.sh"))
  1. حالا با uv بهش میگیم که این اسکریپت به پکیج requests نیاز داره:
$ uv add --script example.py requests
Updated `example.py`

این دستور اطلاعات وابستگی رو به صورت کامنت به خود فایل اضافه میکنه.

  1. در نهایت، با uv run اسکریپت رو اجرا میکنیم. uv خودش یه محیط ایزوله میسازه، وابستگی‌ها رو نصب میکنه و بعد اسکریپت رو اجرا میکنه.
$ uv run example.py
Reading inline script metadata from: example.py
Installed 5 packages in 12ms

نصب و اجرای ابزارهای خط فرمان

  • uvx برای اجرای موقت:
    uvx (که مخفف uv tool run هست) به شما اجازه میده یه ابزار رو بدون اینکه دائمی نصبش کنین، اجرا کنین. مثلا:
$ uvx pycowsay 'hello world!'
...
< hello world! >
------------
\   ^__^
 \  (oo)\_______
    (__)\       )\/\
        ||----w |
        ||     ||
  • uv tool install برای نصب دائمی:
    اگه میخواین یه ابزار رو همیشه در دسترس داشته باشین، میتونین با این دستور نصبش کنین:
$ uv tool install ruff
Resolved 1 package in 6ms
Installed 1 package in 2ms
+ ruff==0.5.0
Installed 1 executable: ruff

حالا میتونین از هر جایی دستور ruff رو اجرا کنین. برای دیدن لیست ابزارهای نصب‌شده هم از uv tool list استفاده میشه.

قابلیت‌های پیشرفته و خاص uv

uv چند تا قابلیت ویژه هم داره که اون رو از ابزارهای سنتی متمایز میکنه:

  • استراتژی‌های مختلف حل وابستگی: به صورت پیش‌فرض، uv همیشه سعی میکنه جدیدترین نسخه سازگار از هر پکیج رو نصب کنه. اما شما میتونین با فرستادن --resolution=lowest بهش بگین که پایین‌ترین نسخه سازگار رو نصب کنه. این قابلیت برای توسعه‌دهنده‌های کتابخانه‌ها خیلی مفیده تا مطمئن بشن کدشون با نسخه‌های قدیمی‌تر وابستگی‌ها هم کار میکنه.
  • حل وابستگی برای نسخه‌های مختلف پایتون: pip همیشه وابستگی‌ها رو بر اساس نسخه پایتونی که باهاش در حال اجراست، حل میکنه. اما uv پارامتری به اسم --python-version قبول میکنه. اینطوری شما میتونین حتی اگه روی سیستم‌تون پایتون ۳.۱۲ دارین، یک فایل نیازمندی‌های سازگار با پایتون ۳.۷ تولید کنین.
  • بازنویسی وابستگی‌ها (Overrides): uv مفهومی به اسم «override» داره که از «constraints» توی pip یک قدم فراتره. با استفاده از فایل‌های override (مثلا با -o overrides.txt)، شما میتونین به رزولور کمک کنین و وابستگی‌های تعریف‌شده توسط یک پکیج رو بازنویسی کنین. این قابلیت یه راه فرار برای مواقعی هست که یک پکیج محدودیت‌های اشتباهی (مثلا یک سقف نسخه نادرست) برای وابستگی‌هاش تعریف کرده.

چشم‌انداز آینده: داستان Rye و «کارگو برای پایتون»

همونطور که اول گفتیم، uv فقط یه ابزار ساده نیست، بلکه بخشی از یک چشم‌انداز بزرگتره. تیم Astral میخواد یک تجربه مثل «کارگو برای پایتون» بسازه؛ یعنی یک ابزار واحد که از راه‌اندازی اولیه پایتون گرفته تا مدیریت پروژه، پکیج، تست و انتشار، همه چیز رو پوشش بده.

این چشم‌انداز خیلی شبیه به چیزیه که آرمین روناکر (Armin Ronacher)، خالق فلسک، با پروژه آزمایشی خودش به اسم Rye دنبال میکرد. تیم Astral و آرمین متوجه شدن که اهدافشون خیلی به هم نزدیکه و برای رسیدن به این هدف، نیاز به سرمایه‌گذاری زیادی روی ابزارهای پایه‌ای مثل یک رزولور و نصب‌کننده سریع و چندپلتفرمی هست. uv دقیقا همون ابزار پایه‌ای هست.

در نتیجه، اونها تصمیم گرفتن با هم همکاری کنن و تیم Astral مسئولیت پروژه Rye رو به عهده گرفت. برنامه اینه که uv در نهایت به یک «کارگو برای پایتون» کامل و آماده برای استفاده تبدیل بشه و یک مسیر مهاجرت راحت از Rye به uv فراهم بشه. تا اون زمان، تیم Astral پروژه Rye رو نگهداری میکنه، اون رو به استفاده از uv در زیرساختش منتقل میکنه و ازش به عنوان یک بستر آزمایشی برای تجربه کاربری نهایی که در ذهن دارن، استفاده میکنه.

محدودیت‌های فعلی uv

با همه این خوبی‌ها، uv هنوز یه ابزار در حال توسعه‌ست و مثل هر ابزار دیگه‌ای، محدودیت‌هایی هم داره. مهمه که اینها رو هم بدونیم:

  • سازگاری ناقص با pip: هرچند uv بخش بزرگی از رابط کاربری pip رو پشتیبانی میکنه، اما هنوز همه قابلیت‌های اون رو پوشش نمیده. مثلا از فرمت‌های قدیمی مثل توزیع‌های .egg پشتیبانی نمیکنه. بعضی از این تفاوت‌ها عمدی هستن و بعضی‌ها به خاطر اینه که uv هنوز در مراحل اولیه توسعه قرار داره.
  • فایل requirements.txt وابسته به پلتفرم: uv، مثل pip-compile، فایل‌های requirements.txt تولید میکنه که مخصوص همون پلتفرم و نسخه پایتونی هستن که باهاش اجرا شدن. این برخلاف ابزارهایی مثل Poetry و PDM هست که فایل‌های قفل مستقل از پلتفرم (مثل poetry.lock و pdm.lock) میسازن. در نتیجه، ممکنه فایل requirements.txt ساخته‌شده با uv روی پلتفرم‌ها یا نسخه‌های پایتون مختلف به راحتی قابل استفاده نباشه، مگر اینکه از گزینه‌هایی مثل --universal استفاده بشه.

ساخت و انتشار پروژه‌ها

علاوه بر همه کارهایی که تا اینجا گفتیم، uv از ساخت (build) و انتشار (publish) پروژه‌ها هم پشتیبانی میکنه، حتی اگه اون پروژه‌ها با خود uv مدیریت نشن. این یعنی میتونه جایگزین ابزاری مثل twine هم باشه. برای جزئیات بیشتر در این مورد، باید به راهنمای انتشار در مستندات خود uv مراجعه کرد.


پرسش و پاسخ‌

سوال ۱: پس uv قراره جای همه ابزارهای پایتون رو بگیره؟
جواب: هدف بلندمدتش همینه. سازنده‌هاش دوست دارن یه ابزار واحد بسازن که کار pip, virtualenv, pip-tools, pyenv, pipx, poetry و twine رو با هم انجام بده. اما در حال حاضر، تمرکزش روی جایگزینی pip, pip-tools و virtualenv هست.

سوال ۲: آیا برای استفاده از uv باید زبان راست (Rust) بلد باشم؟
جواب: اصلا و ابدا. uv با راست نوشته شده، ولی شما برای استفاده ازش نیازی به دونستن راست یا حتی نصب کردنش ندارین. همونطور که برای استفاده از گوگل کروم لازم نیست C++ بلد باشین.

سوال ۳: اسم uv از کجا اومده و چطوری تلفظ میشه؟
جواب: توی مستنداتش گفته شده که لطفا فقط بگین «uv». تلفظش هم «یو وی» هست (/juː viː/).

سوال ۴: اگه من الان از Poetry یا PDM استفاده میکنم، باید سریع بیام سراغ uv؟
جواب: نه لزوما. خود سازنده‌هاش هم گفتن که uv در حال حاضر برای پروژه‌هایی که حول محور pip و pip-tools ساخته شدن، مناسب‌تره. چون هنوز فایل قفل مستقل از پلتفرم مثل Poetry تولید نمیکنه. اما چشم‌انداز آینده‌ش اینه که به اون سمت هم حرکت کنه.

سوال ۵: این ابزار توسط چه کسانی پشتیبانی میشه و آیا قابل اعتماده؟
جواب: uv توسط شرکت Astral پشتیبانی میشه که تیم سازنده Ruff هم هست. Ruff الان یکی از محبوب‌ترین ابزارها توی اکوسیستم پایتونه. uv هم از کتابخونه‌های معتبری مثل PubGrub (که رزولور اصلیش هست) استفاده میکنه و از پروژه‌های موفقی مثل Cargo, pnpm و Bun الهام گرفته. پس میشه گفت پشتوانه قوی‌ای داره.

منابع

  • [2] Introducing uv: Next-Gen Python Package Manager | by Vishnu Sivan | Medium
  • [4] GitHub – astral-sh/uv: An extremely fast Python package and project manager, written in Rust.
  • [1] uv
  • [3] uv: Python packaging in Rust

دیدگاه‌ها

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *