مجموعة من أدوات سطر الأوامر لمساعدتك في الحفاظ على حزمك المستندة pip
، حتى عند تثبيتها. أنت تقوم بتثبيتهم، أليس كذلك؟ (عند إنشاء تطبيق Python الخاص بك وتبعياته للإنتاج، فإنك تريد التأكد من أن إصداراتك يمكن التنبؤ بها وحتمية.)
كما هو الحال مع pip
، يجب تثبيت pip-tools
في كل بيئة من البيئات الافتراضية لمشروعك:
$ source /path/to/venv/bin/activate
(venv) $ python -m pip install pip-tools
ملاحظة : تفترض جميع أمثلة الأوامر المتبقية أنك قمت بتنشيط البيئة الافتراضية لمشروعك.
pip-compile
يتيح لك الأمر pip-compile
تجميع ملف requirements.txt
من تبعياتك، المحددة في pyproject.toml
أو setup.cfg
أو setup.py
أو requirements.in
.
قم بتشغيله باستخدام pip-compile
أو python -m piptools compile
(أو pipx run --spec pip-tools pip-compile
إذا تم تثبيت pipx
مع إصدار Python المناسب). إذا كنت تستخدم إصدارات متعددة من Python، فيمكنك أيضًا تشغيل py -XY -m piptools compile
على Windows و pythonX.Y -m piptools compile
على أنظمة أخرى.
يجب تشغيل pip-compile
من نفس البيئة الافتراضية لمشروعك، لذا فإن التبعيات الشرطية التي تتطلب إصدارًا محددًا من Python، أو علامات بيئة أخرى، يتم حلها بالنسبة لبيئة مشروعك.
ملاحظة : إذا عثرت pip-compile
على ملف requirements.txt
موجود يلبي التبعيات، فلن يتم إجراء أي تغييرات، حتى لو كانت التحديثات متوفرة. للتجميع من البداية، قم أولاً بحذف ملف requirements.txt
الموجود، أو راجع تحديث المتطلبات للأساليب البديلة.
pyproject.toml
يعد ملف pyproject.toml
هو أحدث معيار لتكوين الحزم والتطبيقات، ويوصى به للمشاريع الجديدة. يدعم pip-compile
كلاً من تثبيت project.dependencies
الخاص بك بالإضافة إلى project.optional-dependencies
. بفضل حقيقة أن هذا معيار رسمي، يمكنك استخدام pip-compile
لتثبيت التبعيات في المشاريع التي تستخدم أدوات التعبئة والتغليف الحديثة الملتزمة بالمعايير مثل Setuptools أو Hatch أو flit.
لنفترض أن لديك تطبيق Python 'foobar' الذي تم حزمه باستخدام Setuptools
، وتريد تثبيته للإنتاج. يمكنك إعلان البيانات الوصفية للمشروع على النحو التالي:
[ build-system ]
requires = [ " setuptools " , " setuptools-scm " ]
build-backend = " setuptools.build_meta "
[ project ]
requires-python = " >=3.9 "
name = " foobar "
dynamic = [ " dependencies " , " optional-dependencies " ]
[ tool . setuptools . dynamic ]
dependencies = { file = [ " requirements.in " ] }
optional-dependencies.test = { file = [ " requirements-test.txt " ] }
إذا كان لديك تطبيق Django تم حزمه باستخدام Hatch
، وتريد تثبيته للإنتاج. أنت تريد أيضًا تثبيت أدوات التطوير الخاصة بك في ملف دبوس منفصل. تعلن عن django
باعتباره تبعية وتقوم بإنشاء dev
تبعية اختياري يتضمن pytest
:
[ build-system ]
requires = [ " hatchling " ]
build-backend = " hatchling.build "
[ project ]
name = " my-cool-django-app "
version = " 42 "
dependencies = [ " django " ]
[ project . optional-dependencies ]
dev = [ " pytest " ]
يمكنك إنتاج ملفاتك الشخصية بسهولة مثل:
$ pip-compile -o requirements.txt pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --output-file=requirements.txt pyproject.toml
#
asgiref==3.6.0
# via django
django==4.1.7
# via my-cool-django-app (pyproject.toml)
sqlparse==0.4.3
# via django
$ pip-compile --extra dev -o dev-requirements.txt pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --extra=dev --output-file=dev-requirements.txt pyproject.toml
#
asgiref==3.6.0
# via django
attrs==22.2.0
# via pytest
django==4.1.7
# via my-cool-django-app (pyproject.toml)
exceptiongroup==1.1.1
# via pytest
iniconfig==2.0.0
# via pytest
packaging==23.0
# via pytest
pluggy==1.0.0
# via pytest
pytest==7.2.2
# via my-cool-django-app (pyproject.toml)
sqlparse==0.4.3
# via django
tomli==2.0.1
# via pytest
يعد هذا أمرًا رائعًا لتثبيت تطبيقاتك، وأيضًا للحفاظ على استقرار CI لحزمة Python مفتوحة المصدر.
setup.py
و setup.cfg
يتمتع pip-compile
أيضًا بدعم كامل للمشروعات المستندة إلى setup.py
و setup.cfg
التي تستخدم setuptools
.
ما عليك سوى تحديد تبعياتك وإضافاتك كالمعتاد وتشغيل pip-compile
كما هو مذكور أعلاه.
requirements.in
يمكنك أيضًا استخدام ملفات نصية عادية لتلبية متطلباتك (على سبيل المثال، إذا كنت لا تريد أن يكون تطبيقك عبارة عن حزمة). لاستخدام ملف requirements.in
للإعلان عن تبعية Django:
# requirements.in
django
الآن، قم بتشغيل pip-compile requirements.in
:
$ pip-compile requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile requirements.in
#
asgiref==3.6.0
# via django
django==4.1.7
# via -r requirements.in
sqlparse==0.4.3
# via django
وسوف يُنتج requirements.txt
الخاص بك، مع تثبيت جميع تبعيات Django (وجميع التبعيات الأساسية).
(متطلبات التحديث)=
يقوم pip-compile
بإنشاء ملف requirements.txt
باستخدام أحدث الإصدارات التي تفي بالتبعيات التي تحددها في الملفات المدعومة.
إذا عثرت pip-compile
على ملف requirements.txt
موجود يلبي التبعيات، فلن يتم إجراء أي تغييرات، حتى لو كانت التحديثات متوفرة.
لإجبار pip-compile
على تحديث كافة الحزم في ملف requirements.txt
الموجود، قم بتشغيل pip-compile --upgrade
.
لتحديث حزمة معينة إلى الإصدار الأحدث أو إلى إصدار محدد، استخدم علامة --upgrade-package
أو -P
:
# only update the django package
$ pip-compile --upgrade-package django
# update both the django and requests packages
$ pip-compile --upgrade-package django --upgrade-package requests
# update the django package to the latest, and requests to v2.0.0
$ pip-compile --upgrade-package django --upgrade-package requests==2.0.0
يمكنك الجمع بين --upgrade
و --upgrade-package
في أمر واحد، لتوفير القيود على الترقيات المسموح بها. على سبيل المثال، لترقية جميع الحزم مع تقييد الطلبات إلى الإصدار الأحدث الأقل من 3.0:
$ pip-compile --upgrade --upgrade-package ' requests<3.0 '
إذا كنت ترغب في استخدام وضع التحقق من التجزئة المتوفر في pip
منذ الإصدار 8.0، pip-compile
يقدم علامة --generate-hashes
:
$ pip-compile --generate-hashes requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --generate-hashes requirements.in
#
asgiref==3.6.0
--hash=sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac
--hash=sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506
# via django
django==4.1.7
--hash=sha256:44f714b81c5f190d9d2ddad01a532fe502fa01c4cb8faf1d081f4264ed15dcd8
--hash=sha256:f2f431e75adc40039ace496ad3b9f17227022e8b11566f4b363da44c7e44761e
# via -r requirements.in
sqlparse==0.4.3
--hash=sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34
--hash=sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268
# via django
لإخراج المتطلبات المثبتة في اسم ملف آخر غير requirements.txt
، استخدم --output-file
. قد يكون هذا مفيدًا لتجميع ملفات متعددة، على سبيل المثال مع قيود مختلفة على Django لاختبار مكتبة بكلا الإصدارين باستخدام tox:
$ pip-compile --upgrade-package ' django<1.0 ' --output-file requirements-django0x.txt
$ pip-compile --upgrade-package ' django<2.0 ' --output-file requirements-django1x.txt
أو للإخراج إلى الإخراج القياسي، استخدم --output-file=-
:
$ pip-compile --output-file=- > requirements.txt
$ pip-compile - --output-file=- < requirements.in > requirements.txt
pip
يمكن تمرير أي إشارات أو وسائط صالحة pip
pip-compile
باستخدام خيار --pip-args
، على سبيل المثال
$ pip-compile requirements.in --pip-args " --retries 10 --timeout 30 "
يمكنك تحديد الإعدادات الافتراضية على مستوى المشروع لـ pip-compile
و pip-sync
عن طريق كتابتها إلى ملف تكوين في نفس الدليل مثل ملفات إدخال المتطلبات الخاصة بك (أو دليل العمل الحالي في حالة إدخال الأنابيب من stdin). افتراضيًا، سيبحث كل من pip-compile
و pip-sync
أولاً عن ملف .pip-tools.toml
ثم في pyproject.toml
. يمكنك أيضًا تحديد ملف تكوين TOML بديل باستخدام خيار --config
.
من الممكن تحديد قيم التكوين عالميًا وقيمًا خاصة بالأوامر. على سبيل المثال، لإنشاء تجزئات pip
بشكل افتراضي في مخرجات ملف المتطلبات الناتجة، يمكنك التحديد في ملف التكوين:
[ tool . pip-tools ]
generate-hashes = true
يجب تحديد خيارات pip-compile
و pip-sync
التي يمكن استخدامها أكثر من مرة كقوائم في ملف تكوين، حتى لو كانت تحتوي على قيمة واحدة فقط.
تدعم pip-tools
القيم الافتراضية لجميع إشارات سطر الأوامر الصالحة لأوامرها الفرعية. قد تحتوي مفاتيح التكوين على شرطات سفلية بدلاً من الشرطات، لذلك يمكن أيضًا تحديد ما ورد أعلاه بهذا التنسيق:
[ tool . pip-tools ]
generate_hashes = true
يمكن وضع إعدادات التكوين الافتراضية الخاصة بـ pip-compile
و pip-sync
تحت أقسام منفصلة. على سبيل المثال، لإجراء تجربة تجريبية افتراضيًا باستخدام pip-compile
:
[ tool . pip-tools . compile ] # "sync" for pip-sync
dry-run = true
ولا يؤثر هذا على أمر pip-sync
، الذي يحتوي أيضًا على خيار --dry-run
. لاحظ أن الإعدادات المحلية لها الأفضلية على الإعدادات العامة التي تحمل الاسم نفسه، عندما يتم الإعلان عن كليهما، وبالتالي فإن هذا من شأنه أيضًا أن يؤدي إلى إنشاء pip-compile
، ولكن يتجاهل إعداد التشغيل الجاف العام:
[ tool . pip-tools ]
generate-hashes = true
dry-run = true
[ tool . pip-tools . compile ]
dry-run = false
ربما تقوم بتغليف الأمر pip-compile
في برنامج نصي آخر. لتجنب إرباك مستهلكي البرنامج النصي المخصص الخاص بك، يمكنك تجاوز أمر التحديث الذي تم إنشاؤه في الجزء العلوي من ملفات المتطلبات عن طريق تعيين متغير البيئة CUSTOM_COMPILE_COMMAND
.
$ CUSTOM_COMPILE_COMMAND= " ./pipcompilewrapper " pip-compile requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# ./pipcompilewrapper
#
asgiref==3.6.0
# via django
django==4.1.7
# via -r requirements.in
sqlparse==0.4.3
# via django
إذا كانت لديك بيئات مختلفة تحتاج إلى تثبيت حزم مختلفة ولكن متوافقة لها، فيمكنك إنشاء ملفات متطلبات ذات طبقات واستخدام طبقة واحدة لتقييد الطبقة الأخرى.
على سبيل المثال، إذا كان لديك مشروع Django حيث تريد الإصدار 2.1
الأحدث في الإنتاج وعند التطوير تريد استخدام شريط أدوات تصحيح Django، فيمكنك إنشاء ملفين *.in
، واحد لكل طبقة:
# requirements.in
django<2.2
في الجزء العلوي من متطلبات التطوير dev-requirements.in
يمكنك استخدام -c requirements.txt
لتقييد متطلبات التطوير بالحزم المحددة بالفعل للإنتاج في requirements.txt
.
# dev-requirements.in
-c requirements.txt
django-debug-toolbar<2.2
أولاً، قم بتجميع requirements.txt
كالمعتاد:
$ pip-compile
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile
#
django==2.1.15
# via -r requirements.in
pytz==2023.3
# via django
الآن قم بتجميع متطلبات التطوير ويتم استخدام ملف requirements.txt
كقيد:
$ pip-compile dev-requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile dev-requirements.in
#
django==2.1.15
# via
# -c requirements.txt
# django-debug-toolbar
django-debug-toolbar==2.1
# via -r dev-requirements.in
pytz==2023.3
# via
# -c requirements.txt
# django
sqlparse==0.4.3
# via django-debug-toolbar
كما ترون أعلاه، على الرغم من توفر الإصدار 2.2
من Django، فإن متطلبات التطوير تتضمن فقط الإصدار 2.1
من Django لأنها كانت مقيدة. الآن يمكن تثبيت كلا ملفي المتطلبات المجمعين بأمان في بيئة التطوير.
لتثبيت المتطلبات في مرحلة الإنتاج، استخدم:
$ pip-sync
يمكنك تثبيت المتطلبات في مرحلة التطوير عن طريق:
$ pip-sync requirements.txt dev-requirements.txt
يمكنك استخدام pip-compile
كخطاف للالتزام المسبق. راجع مستندات الالتزام المسبق للحصول على التعليمات. نموذج .pre-commit-config.yaml
:
repos :
- repo : https://github.com/jazzband/pip-tools
rev : 7.4.1
hooks :
- id : pip-compile
قد ترغب في تخصيص وسيطات pip-compile
عن طريق تكوين args
و/أو files
، على سبيل المثال:
repos :
- repo : https://github.com/jazzband/pip-tools
rev : 7.4.1
hooks :
- id : pip-compile
files : ^requirements/production.(in|txt)$
args : [--index-url=https://example.com, requirements/production.in]
إذا كان لديك ملفات متطلبات متعددة، فتأكد من إنشاء رابط لكل ملف.
repos :
- repo : https://github.com/jazzband/pip-tools
rev : 7.4.1
hooks :
- id : pip-compile
name : pip-compile setup.py
files : ^(setup.py|requirements.txt)$
- id : pip-compile
name : pip-compile requirements-dev.in
args : [requirements-dev.in]
files : ^requirements-dev.(in|txt)$
- id : pip-compile
name : pip-compile requirements-lint.in
args : [requirements-lint.in]
files : ^requirements-lint.(in|txt)$
- id : pip-compile
name : pip-compile requirements.in
args : [requirements.in]
files : ^requirements.(in|txt)$
pip-sync
الآن بعد أن أصبح لديك ملف requirements.txt
، يمكنك استخدام pip-sync
لتحديث بيئتك الافتراضية لتعكس بالضبط ما هو موجود هناك. سيؤدي هذا إلى تثبيت/ترقية/إلغاء تثبيت كل ما هو ضروري لمطابقة محتويات ملف requirements.txt
.
قم بتشغيله باستخدام pip-sync
أو python -m piptools sync
. إذا كنت تستخدم إصدارات متعددة من Python، فيمكنك أيضًا تشغيل py -XY -m piptools sync
على Windows و pythonX.Y -m piptools sync
على أنظمة أخرى.
يجب تثبيت pip-sync
وتشغيله من نفس البيئة الافتراضية لمشروعك لتحديد الحزم التي سيتم تثبيتها أو ترقيتها.
كن حذرًا : من المفترض أن يتم استخدام pip-sync
فقط مع ملف requirements.txt
الذي تم إنشاؤه بواسطة pip-compile
.
$ pip-sync
Uninstalling flake8-2.4.1:
Successfully uninstalled flake8-2.4.1
Collecting click==4.1
Downloading click-4.1-py2.py3-none-any.whl (62kB)
100% |................................| 65kB 1.8MB/s
Found existing installation: click 4.0
Uninstalling click-4.0:
Successfully uninstalled click-4.0
Successfully installed click-4.1
لمزامنة قوائم تبعية متعددة *.txt
، ما عليك سوى تمريرها عبر وسيطات سطر الأوامر، على سبيل المثال
$ pip-sync dev-requirements.txt requirements.txt
قد يؤدي تمرير الوسيطات الفارغة إلى تعيين المتطلبات الافتراضية إلى requirements.txt
.
يمكن تمرير أي إشارات أو وسائط صالحة pip install
باستخدام خيار --pip-args
الخاص بـ pip-sync
، على سبيل المثال
$ pip-sync requirements.txt --pip-args " --no-cache-dir --no-deps "
ملاحظة : لن يقوم pip-sync
بترقية أو إلغاء تثبيت أدوات التغليف مثل setuptools
أو pip
أو pip-tools
نفسها. استخدم python -m pip install --upgrade
لترقية تلك الحزم.
requirements.in
و requirements.txt
للتحكم بالمصادر؟ بشكل عام، نعم. إذا كنت تريد تثبيت بيئة قابلة للتكرار متاحًا من التحكم بالمصدر، فنعم، يجب عليك الالتزام بكل من requirements.in
و requirements.txt
بالتحكم بالمصدر.
لاحظ أنه إذا كنت تقوم بالنشر على بيئات Python متعددة (اقرأ القسم أدناه)، فيجب عليك إنشاء ملف إخراج منفصل لكل بيئة Python. نقترح استخدام تنسيق {env}-requirements.txt
(على سبيل المثال: win32-py3.7-requirements.txt
و macos-py3.10-requirements.txt
وما إلى ذلك).
requirements.in
/ requirements.txt
و pip-compile
يمكن أن تتغير تبعيات الحزمة اعتمادًا على بيئة Python التي تم تثبيتها فيها. هنا، نحدد بيئة بايثون على أنها مزيج من نظام التشغيل، وإصدار بايثون (3.7، 3.8، وما إلى ذلك)، وتنفيذ بايثون (CPython، PyPy، وما إلى ذلك). للحصول على تعريف دقيق، راجع المجموعات المحتملة لعلامات البيئة PEP 508.
نظرًا لأن requirements.txt
الناتج يمكن أن يختلف بالنسبة لكل بيئة، يجب على المستخدمين تنفيذ pip-compile
في كل بيئة Python بشكل منفصل لإنشاء ملف requirements.txt
صالح لكل بيئة مذكورة. يمكن استخدام نفس requirements.in
in كملف مصدر لجميع البيئات، باستخدام علامات البيئة PEP 508 حسب الحاجة، بنفس الطريقة التي سيتم بها الاستخدام العادي pip
البيئات.
إذا ظل ملف requirements.txt
الذي تم إنشاؤه كما هو تمامًا لجميع بيئات Python، فيمكن استخدامه عبر بيئات Python بأمان. ولكن يجب على المستخدمين توخي الحذر لأن أي تحديث للحزمة يمكن أن يقدم تبعيات تعتمد على البيئة، مما يجعل أي requirements.txt
تم إنشاؤه حديثًا يعتمد على البيئة أيضًا. كقاعدة عامة، يُنصح بأنه يجب على المستخدمين دائمًا تنفيذ pip-compile
على كل بيئة Python مستهدفة لتجنب المشكلات.
تعد pip-tools
أداة رائعة لتحسين إمكانية تكرار النسخ. ولكن هناك بعض الأشياء التي يجب وضعها في الاعتبار.
pip-compile
نتائج مختلفة في بيئات مختلفة كما هو موضح في القسم السابق.pip
مع متغير البيئة PIP_CONSTRAINT
لقفل التبعيات في بيئات الإنشاء كما هو موثق في #8439. باستكمال مثال pyproject.toml
السابق، يمكن إنشاء ملف قفل واحد كما يلي:
$ pip-compile --all-build-deps --all-extras --output-file=constraints.txt --strip-extras pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.9
# by the following command:
#
# pip-compile --all-build-deps --all-extras --output-file=constraints.txt --strip-extras pyproject.toml
#
asgiref==3.5.2
# via django
attrs==22.1.0
# via pytest
backports-zoneinfo==0.2.1
# via django
django==4.1
# via my-cool-django-app (pyproject.toml)
editables==0.3
# via hatchling
hatchling==1.11.1
# via my-cool-django-app (pyproject.toml::build-system.requires)
iniconfig==1.1.1
# via pytest
packaging==21.3
# via
# hatchling
# pytest
pathspec==0.10.2
# via hatchling
pluggy==1.0.0
# via
# hatchling
# pytest
py==1.11.0
# via pytest
pyparsing==3.0.9
# via packaging
pytest==7.1.2
# via my-cool-django-app (pyproject.toml)
sqlparse==0.4.2
# via django
tomli==2.0.1
# via
# hatchling
# pytest
قد تطلب بعض الواجهات الخلفية للبناء أيضًا تبعيات البناء ديناميكيًا باستخدام خطافات get_requires_for_build_
الموضحة في PEP 517 وPEP 660. وستتم الإشارة إلى ذلك في المخرجات باستخدام إحدى اللواحق التالية:
(pyproject.toml::build-system.backend::editable)
(pyproject.toml::build-system.backend::sdist)
(pyproject.toml::build-system.backend::wheel)
pip-compile-multi - برنامج تجميع أوامر pip-compile لملفات متطلبات الإسناد الترافقي المتعددة.
pipdeptree لطباعة شجرة التبعية للحزم المثبتة.
تسليط الضوء على بناء الجملة requirements.in
/ requirements.txt
:
يسرد هذا القسم ميزات pip-tools
التي تم إهمالها حاليًا.
--allow-unsafe
افتراضيًا (#989). استخدم --no-allow-unsafe
للحفاظ على السلوك القديم. يوصى بتمرير --allow-unsafe
الآن للتكيف مع التغيير القادم.--resolver=backtracking
.--strip-extras
افتراضيًا (#1613). استخدم --no-strip-extras
للحفاظ على السلوك القديم.يمكنك الاختيار من بين محلل التراجع الافتراضي أو محلل القديم المهمل.
ستفشل وحدة الحل القديمة أحيانًا في حل التبعيات. يعتبر محلل التراجع أكثر قوة، ولكن يمكن أن يستغرق وقتًا أطول للتشغيل بشكل عام.
يمكنك الاستمرار في استخدام المحلل القديم مع --resolver=legacy
على الرغم من ملاحظة أنه تم إهماله وستتم إزالته في إصدار مستقبلي.