ऑफलाइन पायथन इंस्टॉलेशन के लिए व्हीलहाउस बनाना और उपयोग करना
व्हीलहाउस व्हील्स की एक पूर्व-निर्मित निर्देशिका है जिसे नेटवर्क-कनेक्टेड मशीन पर बनाया जाता है और टारगेट मशीन पर ऑफलाइन इंस्टॉल किया जाता है। इसके लिए रिक्वायरमेंट्स फाइल को पिन करें, pip wheel चलाएं, tar से आर्काइव करें, और फिर --no-index --no-deps --force-reinstall के साथ इंस्टॉल करें।
इस पृष्ठ पर
संक्षिप्त उत्तर
व्हीलहाउस पूर्व-निर्मित व्हील फाइलों की एक निर्देशिका है जिसे आप नेटवर्क एक्सेस वाली मशीन पर बनाते हैं और फिर एक अलग आइसोलेटेड टारगेट मशीन पर ट्रांसफर करते हैं। बिल्ड मशीन एक पिन की गई रिक्वायरमेंट्स फाइल को पढ़ती है, हर डिपेंडेंसी को कंपाइल करने के लिए --wheel-dir के साथ pip wheel चलाती है, और निर्देशिका को tar के साथ पैकेज करती है। टारगेट मशीन पर, आप आर्काइव को एक्सट्रैक्ट करते हैं और --no-index --no-deps --force-reinstall के साथ pip install चलाते हैं ताकि pip कभी भी PyPI से संपर्क न करे और केवल बंडल किए गए व्हील्स को इंस्टॉल करे। रिक्वायरमेंट्स फाइल में --hash प्रविष्टियों को शामिल करके हैश-चेकिंग जोड़ी जा सकती है, जो बिल्ड स्टेप के दौरान पैकेज की अखंडता को सत्यापित करती है। यह तरीका तब उपयुक्त होता है जब टारगेट के पास नेटवर्क एक्सेस न हो, आप टारगेट पर दोबारा कंपाइल करने से बचना चाहते हों, और आप OS और आर्किटेक्चर को नियंत्रित कर सकते हों। यह प्राइवेट इंडेक्स का विकल्प नहीं है क्योंकि आर्काइव एक स्टेटिक स्नैपशॉट है, आमतौर पर OS और आर्किटेक्चर-विशिष्ट होता है, और निरंतर उपलब्धता या एक्सेस कंट्रोल प्रदान नहीं करता है।
pip wheel के साथ व्हीलहाउस बनाना
मुख्य वर्कफ्लो एक पिन की गई रिक्वायरमेंट्स फाइल से शुरू होता है। हर डिपेंडेंसी को व्हील में कंपाइल करने और उसे व्हीलहाउस निर्देशिका में स्टोर करने के लिए python -m pip wheel -r requirements.txt --wheel-dir=/tmp/wheelhouse चलाएं। बिल्ड मशीन कंपाइलेशन करती है, इसलिए टारगेट मशीन को कंपाइलर या बिल्ड टूल्स की आवश्यकता नहीं होती है। कमांड पूरी होने के बाद, व्हीलहाउस निर्देशिका में ट्रांजिटिव डिपेंडेंसी सहित प्रति पैकेज एक व्हील फाइल होती है। अगला कदम उस निर्देशिका को आर्काइव करना है ताकि इसे ट्रांसफर किया जा सके। एक आधुनिक यूनिक्स सिस्टम पर, एक सिंगल कंप्रेस्ड आर्काइव बनाने के लिए tar -cjvf wheelhouse.tar.bz2 -C /tmp/wheelhouse . चलाएं। यह आर्काइव वह है जिसे आप आइसोलेटेड एनवायरनमेंट में भेजते हैं। रिक्वायरमेंट्स फाइल इस स्टेप के लिए इनपुट है, इसलिए बिल्ड करने से पहले इसे सटीक और पूर्ण होना चाहिए।
mkdir -p /tmp/wheelhouse && python -m pip wheel -r requirements.txt --wheel-dir=/tmp/wheelhouse && tar -cjvf wheelhouse.tar.bz2 -C /tmp/wheelhouse .व्यावहारिक सुझाव
बिल्ड मशीन पर pip freeze के साथ रिक्वायरमेंट्स फाइल जेनरेट करें, फिर pip wheel चलाने से पहले सत्यापित करें कि पिन की गई फाइल में हर ट्रांजिटिव डिपेंडेंसी शामिल है। यह ऑफलाइन इंस्टॉलेशन के विफल होने के कारणों को रोकता है।
नेटवर्क एक्सेस के बिना व्हीलहाउस से इंस्टॉल करना
टारगेट मशीन पर, आर्काइव को एक अस्थायी निर्देशिका में एक्सट्रैक्ट करें, फिर तीन महत्वपूर्ण फ्लैग्स के साथ pip install चलाएं। --no-index pip को बताता है कि वह किसी भी पैकेज इंडेक्स से संपर्क न करे, ताकि वह PyPI पर वापस न जा सके। --no-deps pip को बंडल के बाहर डिपेंडेंसीज को रिज़ॉल्व या इंस्टॉल करने से रोकता है, जो सुरक्षित है क्योंकि रिक्वायरमेंट्स फाइल में पहले से ही हर पैकेज सूचीबद्ध है। --force-reinstall यह सुनिश्चित करता है कि बंडल किए गए व्हील्स इंस्टॉल हों, भले ही मैचिंग वर्जन पहले से मौजूद हो। कमांड python -m pip install --force-reinstall --no-index --no-deps /tmp/wheelhouse/* एक्सट्रैक्ट की गई निर्देशिका से सभी व्हील्स को इंस्टॉल करता है। यह सीक्वेंस वास्तविक ऑफलाइन इंस्टॉलेशन प्राप्त करता है क्योंकि इंस्टॉल स्टेप के दौरान कोई नेटवर्क रिक्वेस्ट नहीं की जाती है। रिक्वायरमेंट्स फाइल में पहले से ही हर ट्रांजिटिव डिपेंडेंसी होनी चाहिए, अन्यथा --no-deps एनवायरनमेंट को अधूरा छोड़ देगा।
tar -xvf wheelhouse.tar.bz2 -C /tmp/wheelhouse && python -m pip install --force-reinstall --no-index --no-deps /tmp/wheelhouse/*पिन की गई रिक्वायरमेंट्स फाइल तैयार करना
एक व्हीलहाउस सटीक वर्जन पिन वाली रिक्वायरमेंट्स फाइल से बनाया जाता है। आप इस फाइल को pip freeze के साथ जेनरेट कर सकते हैं, जो वर्तमान एनवायरनमेंट में इंस्टॉल किए गए पैकेजों को रिकॉर्ड करता है, जिसमें केवल टॉप-लेवल पैकेज ही नहीं बल्कि ट्रांजिटिव डिपेंडेंसी भी शामिल होती हैं। प्रत्येक लाइन एक विशिष्ट वर्जन की आवश्यकता के लिए == ऑपरेटर का उपयोग करती है, उदाहरण के लिए SomePackage == 1.2.3। पिनिंग आपको नए रिलीज़ वर्जन में बग या असंगतियों से बचाती है क्योंकि pip बिल्ड या इंस्टॉल स्टेप के दौरान किसी भी चीज़ को अपग्रेड नहीं करेगा। रिक्वायरमेंट्स फाइल व्हील-बिल्डिंग स्टेप के लिए इनपुट है, इसलिए pip wheel चलाने से पहले इसे पूर्ण और सटीक होना चाहिए। यदि फाइल में किसी ट्रांजिटिव डिपेंडेंसी की कमी है, तो ऑफलाइन इंस्टॉलेशन विफल हो जाएगा क्योंकि --no-deps pip को इंडेक्स से उसे प्राप्त करने से रोकता है। pip wheel चलाने से पहले जेनरेट की गई फाइल की समीक्षा करें ताकि यह सुनिश्चित हो सके कि इसमें हर ट्रांजिटिव डिपेंडेंसी शामिल है।
ट्रांसफर के लिए व्हीलहाउस को आर्काइव करना
एक बार जब व्हील निर्देशिका भर जाती है, तो इसे tar का उपयोग करके एक सिंगल पोर्टेबल आर्काइव में बदलें। कमांड tar -cjvf wheelhouse.tar.bz2 -C /tmp/wheelhouse . सभी व्हील फाइलों वाला एक कंप्रेस्ड टार आर्काइव बनाता है। यह आर्काइव वह है जिसे आइसोलेटेड एनवायरनमेंट में ट्रांसफर किया जाता है। आर्काइव बिल्ड मशीन स्टेट का एक स्टेटिक स्नैपशॉट है, इसलिए यह सटीक कंपाइल किए गए पैकेजों और उनके वर्जन्स को सुरक्षित रखता है। इसमें बिल्ड स्क्रिप्ट या सोर्स कोड शामिल नहीं होते, केवल इंस्टॉल करने के लिए तैयार व्हील्स होते हैं। इंस्टॉलेशन शुरू होने से पहले आर्काइव को टारगेट मशीन पर ट्रांसफर किया जाना चाहिए। चूंकि आर्काइव एक सिंगल फाइल है, इसे मशीनों के बीच ले जाना आसान है, लेकिन यह अलग-अलग ऑपरेटिंग सिस्टम या CPU आर्किटेक्चर के बीच पोर्टेबल नहीं है।
व्हीलहाउस वर्कफ़्लो में हैश सत्यापन जोड़ना
हैश-चेकिंग को व्हीलहाउस पद्धति के साथ जोड़ा जा सकता है क्योंकि दोनों एक रिक्वायरमेंट्स फ़ाइल का उपयोग करते हैं। आप रिक्वायरमेंट्स फ़ाइल में --hash प्रविष्टियाँ जोड़ते हैं, उदाहरण के लिए FooProject == 1.2 --hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824। जब pip wheel पैकेज डाउनलोड करता है, तब इन हैश की पुष्टि की जाती है, जो सोर्स इंडेक्स या HTTPS सर्टिफिकेट चेन के साथ छेड़छाड़ से सुरक्षा प्रदान करता है। यह उन इंडेक्स पर पैकेज के बदलने से भी बचाता है जो बिना वर्जन नंबर बदले पैकेज बदलने की अनुमति देते हैं। यह ऑफलाइन बंडल के ऊपर एक अखंडता परत (integrity layer) है। हैश मान्य होने चाहिए और आर्काइव में मौजूद पैकेज से मेल खाने चाहिए। यदि हैश मेल नहीं खाते हैं, तो pip पैकेज का उपयोग करने से इनकार कर देगा, जो बिल्ड को चुपचाप होने वाले बदलावों से बचाता है। हैश-चेकिंग मोड एक अखंडता परत है, न कि प्राइवेट इंडेक्स सर्वर चलाने का कोई श्रम-बचत विकल्प, क्योंकि यह प्राइवेट इंडेक्स या वेंडर्ड लाइब्रेरी की उपलब्धता के लाभ प्रदान नहीं करता है।
pyproject.toml में बिल्ड डिपेंडेंसी घोषित करना
pyproject.toml में [build-system] टेबल उन पायथन स्तर की डिपेंडेंसी को घोषित करता है जिन्हें प्रोजेक्ट के बिल्ड सिस्टम को चलाने के लिए इंस्टॉल किया जाना चाहिए। 'requires' की (key) उन डिपेंडेंसी की सूची देती है, उदाहरण के लिए requires = [setuptools]। ये बिल्ड-टाइम आवश्यकताएं प्रभावित करती हैं कि pip wheel क्या कंपाइल करता है क्योंकि बिल्ड बैकएंड को व्हील बनाने के लिए इनकी आवश्यकता होती है। इस टेबल को समझने से यह सुनिश्चित करने में मदद मिलती है कि व्हीलहाउस संकलन (compilation) की सफलता के लिए सभी आवश्यक बिल्ड-टूल डिपेंडेंसी को कैप्चर करता है। यदि बिल्ड सिस्टम को अतिरिक्त पैकेज की आवश्यकता है, तो उन्हें 'requires' में सूचीबद्ध किया जाना चाहिए ताकि बिल्ड मशीन pip wheel चलाने से पहले उन्हें इंस्टॉल कर सके। जब pyproject.toml फ़ाइल मौजूद नहीं होती है तब डिफ़ॉल्ट सिमेंटिक्स लागू होते हैं, लेकिन एक स्पष्ट टेबल बिल्ड आवश्यकताओं को स्पष्ट और पुनरुत्पादनीय (reproducible) बनाती है।
पोर्टेबिलिटी सीमाएं और जब व्हीलहाउस पर्याप्त न हो
एक व्हीलहाउस में कंपाइल किए गए पैकेज होते हैं जो आमतौर पर OS और आर्किटेक्चर-विशिष्ट होते हैं, इसलिए आर्काइव अनिवार्य रूप से मशीनों के बीच पोर्टेबल नहीं होते हैं। एक ही व्हील बिना पुन: संकलन (recompilation) के अलग ऑपरेटिंग सिस्टम या CPU आर्किटेक्चर पर काम नहीं करेगा। इस पद्धति के लिए नेटवर्क एक्सेस वाली बिल्ड मशीन की आवश्यकता होती है; यदि कोई भी मशीन PyPI तक नहीं पहुँच सकती है, तो यह मदद नहीं करता है। जब आपको क्रॉस-प्लेटफ़ॉर्म समर्थन या एक स्थिर आर्काइव से परे एक जीवित ऑडिट ट्रेल की आवश्यकता होती है, तो व्हीलहाउस प्राइवेट इंडेक्स का विकल्प नहीं हो सकता। केवल हैश-चेकिंग अखंडता प्रदान करती है लेकिन उपलब्धता नहीं, और एक व्हीलहाउस केवल उन्हीं सटीक पैकेजों और प्लेटफ़ॉर्म के लिए उपलब्धता प्रदान करता है जिन्हें इसमें शामिल किया गया है। यदि आपको कई प्लेटफ़ॉर्म का समर्थन करना है, तो आपको प्रत्येक लक्षित वातावरण के लिए अलग-अलग व्हीलहाउस बनाने होंगे। आर्काइव एक स्नैपशॉट है, कोई सेवा नहीं, इसलिए यह निरंतर उपलब्धता या एक्सेस कंट्रोल प्रदान नहीं कर सकता।
जब व्हीलहाउस सही टूल होता है
व्हीलहाउस तब सही टूल होता है जब लक्षित वातावरण (target environment) के पास PyPI के लिए नेटवर्क एक्सेस नहीं होता है, आप लक्षित मशीन पर समय लेने वाले पुन: संकलन से बचना चाहते हैं, और आप OS और आर्किटेक्चर को नियंत्रित कर सकते हैं। यह सभी संकलन कार्यों को एक एकल आर्काइव में पैक करता है, जो केवल वर्जन पिनिंग करने या केवल हैश-चेकिंग का उपयोग करने से अलग है। पिनिंग नए वर्जन के बग्स से बचाती है, और हैश-चेकिंग अखंडता जोड़ती है, लेकिन इनमें से कोई भी व्हीलहाउस जैसी उपलब्धता या ऑफलाइन इंस्टॉलेशन की सुविधा प्रदान नहीं करता है। व्हीलहाउस प्री-बिल्ट व्हील्स का एक बंडल है जिसे लक्षित मशीन किसी भी इंडेक्स से संपर्क किए बिना इंस्टॉल करती है। यह दृष्टिकोण विभिन्न OS और आर्किटेक्चर पर केवल तभी काम करता है जब बिल्ड और टारगेट मशीनें एक ही प्लेटफ़ॉर्म साझा करती हैं। यह उन अलग-थलग परिनियोजन (isolated deployments) के लिए एक व्यावहारिक समाधान है जहाँ नेटवर्क एक्सेस अनुपलब्ध या प्रतिबंधित है।
क्या जाँचें
- रिक्वायरमेंट्स फाइल में हर पैकेज को == के साथ पिन करना चाहिए और इसमें केवल टॉप-लेवल पैकेज ही नहीं, बल्कि ट्रांजिटिव डिपेंडेंसी भी शामिल होनी चाहिए।
- आर्काइव करने से पहले सभी डिपेंडेंसीज को डाउनलोड और कंपाइल करने के लिए बिल्ड मशीन के पास नेटवर्क एक्सेस होना चाहिए।
- व्हील्स के संगत होने के लिए टारगेट मशीन का OS और CPU आर्किटेक्चर बिल्ड मशीन के समान होना चाहिए।
- नेटवर्क एक्सेस और बाहरी डिपेंडेंसी रिज़ॉल्यूशन को रोकने के लिए इंस्टॉलेशन कमांड में --no-index, --no-deps, और --force-reinstall शामिल होना चाहिए।
- ट्रांसफर से पहले व्हील निर्देशिका से tar के साथ आर्काइव बनाया जाना चाहिए, और इंस्टॉलेशन से पहले एक्सट्रैक्ट किया जाना चाहिए।
- रिक्वायरमेंट्स फाइल में हैश-चेकिंग प्रविष्टियाँ मान्य होनी चाहिए और आर्काइव में मौजूद पैकेजों से मेल खानी चाहिए।
- व्हीलहाउस में कंपाइल किए गए पैकेज होते हैं और यह अलग-अलग ऑपरेटिंग सिस्टम या आर्किटेक्चर के बीच पोर्टेबल नहीं है।
- व्हीलहाउस निरंतर उपलब्धता, एक्सेस कंट्रोल या ऑडिट प्रबंधन के लिए प्राइवेट इंडेक्स की जगह नहीं लेता है।
उपयोग की सीमाएँ
एक व्हीलहाउस में कंपाइल किए गए पैकेज होते हैं जो आमतौर पर OS और आर्किटेक्चर-विशिष्ट होते हैं, इसलिए आर्काइव जरूरी नहीं कि मशीनों के बीच पोर्टेबल हों। इस दृष्टिकोण के लिए नेटवर्क एक्सेस वाली बिल्ड मशीन की आवश्यकता होती है; यदि कोई भी मशीन PyPI तक नहीं पहुँच सकती है तो यह मदद नहीं करता है। कंपाइल किए गए व्हील्स में प्लेटफॉर्म-विशिष्ट बाइनरी कोड हो सकता है, इसलिए केवल इस तरीके से क्रॉस-कंपाइलेशन समर्थित नहीं है। आर्काइव एक स्टेटिक स्नैपशॉट है और प्राइवेट इंडेक्स सर्वर की तरह निरंतर उपलब्धता या ACL प्रबंधन प्रदान नहीं करता है। --no-deps का उपयोग करने का अर्थ है कि ऑपरेटर को यह सुनिश्चित करना होगा कि रिक्वायरमेंट्स फाइल में पहले से ही हर ट्रांजिटिव डिपेंडेंसी सूचीबद्ध है।