Python Programming

غلبه بر جهنم وابستگی‌ها با Poetry و Pip-Compile

آشوب وابستگی‌های شناور

در بستر پایتون، عبارت «روی ماشین من کار می‌کند» نشانه‌ای مشهور از شکست در مدیریت وابستگی‌هاست. وقتی به محدودیت‌های بدون نسخه مانند >=1.0 تکیه می‌کنید، محیط شما در معرض سلیقه به‌روزرسانی‌های بسته‌های بالادستی قرار دارد. یک افزایش جزئی در نسخه یک وابستگی غیرمستقیم می‌تواند تغییرات شکست‌دهنده را وارد کند و منجر به خطاهای مبهم در محیط تولید شود که بازتولید آن‌ها به صورت محلی غیرممکن است. این پدیده که به طور گسترده به عنوان «جهنم وابستگی» شناخته می‌شود، دلیل اصلی این است که تکرارپذیری، سنگ بنای مهندسی نرم‌افزار حرفه‌ای است. برای مقابله با این مشکل، استاندارد صنعت به سمت فایل‌های قفل (Lock files) تغییر کرده است؛ که عکس‌های ثابتی از تمام وابستگی‌های حل‌شده هستند. اگرچه ابزارهایی مانند pip مدت‌هاست که از پشتیبانی بومی فایل قفل محروم بوده‌اند، اما جامعه توسعه‌دهندگان راه‌حل‌های قدرتمندی را توسعه داده است. دو ابزار قدرتمندتر برای دستیابی به ساخت‌های قطعی، Poetry و pip-tools (به طور خاص pip-compile) هستند. این راهنما بررسی می‌کند که چگونه از هر دو برای ایجاد محیط‌های پایتون مقاوم و تکرارپذیر استفاده کنید.

استراتژی الف: بیکار یکپارچه Poetry

Poetry مدیریت وابستگی‌ها را به عنوان یک ویژگی اصلی و نه به عنوان یک فکر ثانویه در نظر می‌گیرد. این ابزار حل وابستگی‌ها، مدیریت محیط مجازی و بسته‌بندی را در یک ابزار واحد ترکیب می‌کند. قلب این سیستم، فایل poetry.lock است. وقتی دستور poetry install را اجرا می‌کنید، Poetry فقط بسته‌های فهرست شده در pyproject.toml را نصب نمی‌کند؛ بلکه فایل قفل را می‌خواند تا اطمینان حاصل کند که هر وابستگی غیرمستقیم به یک هش نسخه دقیق پین شده است. این کار تضمین می‌کند که محیط روی لپ‌تاپ شما دقیقاً مشابه محیط CI/CD و تولید باشد. در اینجا نحوه راه‌اندازی یک پروژه Poetry پایه آورده شده است:
# Initialize a new project
poetry new my-project

# Add a dependency
poetry add requests

# This generates poetry.lock, pinning requests and all its sub-dependencies
برای نصب وابستگی‌ها در محیط تولید، همیشه از فایل قفل استفاده کنید. هرگز دستور poetry update را در پایپ‌لاین تولید اجرا نکنید، زیرا این کار فایل قفل را با نسخه‌های جدیدتر احتمالی بازتولید خواهد کرد.
# Strict installation from lock file
poetry install --no-dev
مزیت Poetry یکپارچگی بی‌نقص آن است. با این حال، اگر به پایپ‌لاین‌های استاندارد pip وابسته هستید یا جداسازی دقیق بین وابستگی‌های زمان ساخت و زمان اجرا را نیاز دارید، رویکرد همه‌کاره Poetry ممکن است خیلی تک‌توده (Monolithic) به نظر برسد.

استراتژی ب: رویکرد pip-tools

برای توسعه‌دهندگانی که سادگی pip را ترجیح می‌دهند اما به ساخت‌های قطعی نیاز دارند، pip-tools راه‌حل ایده‌آلی است. ابزار pip-compile یک فایل requirements.in (که وابستگی‌های مستقیم شما را فهرست می‌کند) می‌گیرد و آن‌ها را به یک فایل requirements.txt با پین کردن کامل نسخه حل می‌کند. این روش رفتار ماژول‌های Go یا Cargo را تقلید می‌کند و جداسازی واضحی بین قصد (آنچه می‌خواهید) و اجرا (آنچه دریافت می‌کنید) فراهم می‌آورد.
# Create a requirements.in file
echo "requests==2.28.0" > requirements.in

# Resolve and compile dependencies
pip-compile requirements.in

# This generates a fully pinned requirements.txt
فایل requirements.txt تولید شده به این شکل خواهد بود:
#
# This file is autogenerated by pip-compile with python 3.10
# To update, run:
#
#    pip-compile requirements.in
#
certifi==2022.12.7
charset-normalizer==2.1.1
idna==3.4
requests==2.28.0
urllib3==1.26.13
توجه کنید که چگونه requests نسخه‌های خاصی از certifi، urllib3 و غیره را فراخوانی می‌کند. این فایل برای کامیت کردن در مخزن و نصب در محیط تولید با استفاده از pip install -r requirements.txt ایمن است.

انتخاب ابزار مناسب

هر دو ابزار یک مشکل اساسی را حل می‌کنند: تکرارپذیری. Poetry برای پروژه‌های سبز (Greenfield) یا تیم‌هایی که یک پایپ‌لاین یکپارچه برای ساخت و انتشار بسته‌ها می‌خواهند، مناسب‌تر است. این ابزار به طور خودکار محیط‌های مجازی را مدیریت می‌کند و یک CLI غنی برای مدیریت اسکریپت‌ها و پلاگین‌ها ارائه می‌دهد. از سوی دیگر، pip-tools سبک‌تر است و به طور بی‌نقص با Dockerfileها و پایپ‌لاین‌های CI/CD موجود که از pip استفاده می‌کنند، یکپارچه می‌شود. همچنین برای پروژه‌هایی که وابستگی‌های ساخت پیچیده‌ای دارند (مانند افزونه‌های C) ترجیح داده می‌شود، جایی که حل‌کننده Poetry گاهی با مشکل مواجه می‌شود.

نتیجه‌گیری

جهنم وابستگی دیگر بهانه‌ای برای ناپایداری در محیط تولید نیست. با پذیرش poetry.lock از Poetry یا requirements.txt از pip-tools، شما تضمین می‌کنید که نرم‌افزار شما در تمام محیط‌ها به طور یکسان رفتار می‌کند. نکته کلیدی ساده است: هرگز به محدودیت نسخه شناور متعهد نشوید. وابستگی‌های خود را پین کنید، به فایل‌های قفل خود اعتماد کنید و با خیال راحت بخوابید.
Share: