本地分发_2020年分发Python应用程序的12个热门途径
2019年P(guān)ython生態(tài)系統(tǒng)中比較流行的主題之一是關(guān)于打包和分發(fā)的。隨著這一年的結(jié)束,我想總結(jié)一下我們目前可用來分發(fā)用Python構(gòu)建的應(yīng)用程序的多種途徑。雖然其中一些也適用于任何語言。
無論你交付的是可執(zhí)行文件、虛擬環(huán)境、打包的代碼還是完整的應(yīng)用程序,下面的列表都包括了標(biāo)準(zhǔn)系統(tǒng)和一些在進入2020年時需要記住的新事物。
應(yīng)用程序
要發(fā)布一個應(yīng)用程序,你需要的不僅僅是一個從PyPI進行pip-install的庫。你需要一種萬無一失的在所有支持的操作系統(tǒng)中安裝它及其依賴項的方式。這些依賴項可以包括其他非Python包以及像二進制文件或映像之類的外部資源。
下面是一些幫助你跨平臺安裝和分發(fā)代碼的選項。
Docker
Docker使用操作系統(tǒng)中的基本功能來隔離進程,使其不知道系統(tǒng)的其余部分。它可以在你的主機內(nèi)運行不同操作系統(tǒng)的內(nèi)核進程,非常類似于虛擬化,但不使用虛擬硬件。
它的文件系統(tǒng)是分層的,因此占用的空間很小,只包含運行所需的文件,而不是典型的虛擬磁盤,虛擬機中還包括空閑空間。
使用一個最小程度打包的根文件系統(tǒng),我們會看到整個操作系統(tǒng)的映像只占用幾十MB,而不是虛擬機所需的GB,這并不少見。
你可以在一個公共注冊中心(如DockerHub)或你的組織內(nèi)部的一個私有注冊中心分發(fā)這些容器。用戶會在自己的計算機上安裝Docker守護進程,然后使用它來獲取你的映像并在本地運行它。
由于Docker映像只不過是一個根文件系統(tǒng),所以你也可以將它們作為一個文件分發(fā),并使用Docker導(dǎo)入它。
要構(gòu)建一個映像,你可以從一個rootfs開始,或者在一個現(xiàn)有的注冊表映像的基礎(chǔ)上進行添加。大多數(shù)操作系統(tǒng)供應(yīng)商在DockerHub中都維護了官方的精簡映像,這些映像通常都很小。
其他組織也為他們的應(yīng)用程序的新版本制作了官方映像,比如構(gòu)建在Debian之上的Python映像。Postgress、MySQL、Redis、Nginx和許多其他標(biāo)準(zhǔn)服務(wù)也都是這樣做的。
Docker現(xiàn)在可以在Linux、OSX和Windows上運行。這種跨平臺支持意味著你構(gòu)建的任何映像都具有廣泛的分布,并且復(fù)雜性最小。你不僅可以控制應(yīng)用程序,還可以控制它所運行的環(huán)境,從而使兼容性問題變得不那么嚴(yán)重。
然而,在配置網(wǎng)絡(luò)或持續(xù)性存儲時仍然可能存在復(fù)雜性。典型的應(yīng)用程序只需要處理端口轉(zhuǎn)發(fā),但是有時候我們很難想象抽象層是如何工作的,所以編寫良好的文檔依然很重要。
使用Docker,你可以控制Python發(fā)行版、支持的OS包(如各個模塊所需的C庫)和你的虛擬環(huán)境。
由于啟動一個容器只需要幾毫秒的時間,所以每次當(dāng)你想要執(zhí)行應(yīng)用程序時運行一個新的容器是完全可以接受的,甚至是推薦的。
有些人甚至使用Docker作為虛擬環(huán)境的替代品。由于它啟動很快,并且可以提供一個交互式shell,所以當(dāng)你需要處理一個特定的項目時,創(chuàng)建一個新容器并不是一個壞主意。
一旦你有了一個配置了基礎(chǔ)環(huán)境的運行容器,你就可以保存該映像以便重用,或者甚至可以將其導(dǎo)出到文件中。
例如,下面的命令會啟動一個新的Python容器,將當(dāng)前工作目錄掛載為/work,并將你放入一個bash shell中。容器目錄中的更改反映在基礎(chǔ)目錄中。
一旦進入容器,你就可以安裝任何需要的Apt或PyPI包。
退出shell后你將會返回到主機。此時,你可以運行下一條命令將任何的更改保存為一個新的Docker映像,你可以稍后重用它或?qū)⑵渫扑偷紻ockerHub進行分發(fā):
你可以在你組織內(nèi)部的私有Docker 注冊表中共享此新映像,或者運行以下命令將該容器導(dǎo)出為一個文件,任何人都可以下載它并將其導(dǎo)入他們的本地Docker環(huán)境中:
然而,分發(fā)的真正工作流程是創(chuàng)建一個Dockerfile,任何人都可以使用它來創(chuàng)建自己的映像。換句話說,你提供了一個帶有Docker守護進程指令的小型文本文件,而不是整個文件系統(tǒng)的副本。
任何人都可以使用該文件克隆你的repo,并運行此命令去創(chuàng)建一個此映像的本地版本:
一個典型的Dockerfile如下所示,請查看他們的文檔以獲取更多信息:
更過詳情:https://docs.docker.com/?
虛擬機和Vagrant
容器的下一步是分發(fā)一個完整的虛擬機。自從虛擬化得到廣泛應(yīng)用和硬件支持以來,這種類型的系統(tǒng)已經(jīng)存在了一段時間了。
交付一個“虛擬設(shè)備”是很有吸引力的,因為你幾乎可以完全控制你的應(yīng)用程序運行的環(huán)境。所有東西都是可配置的:操作系統(tǒng)、它的包、磁盤和網(wǎng)絡(luò),甚至空閑空間的大小。
使用虛擬機的缺點是發(fā)行版的大小,通常是在GB級。另外,你還得想辦法讓客戶得到你的映像。Amazon S3 或 Digital Ocean Spaces之類的東西就是一個很好的起點。
一開始,只有服務(wù)器硬件支持運行虛擬機,但是現(xiàn)在每個處理器都有這個能力,而且所有主要的操作系統(tǒng)都支持它。還有一些免費的應(yīng)用程序可以幫助你管理和配置虛擬機,比如Oracle的VirtualBox。
Vagrant是在VirtualBox等管理器上配置和運行虛擬機的另一個系統(tǒng)。它的功能很像Docker,你可以在一個文件中指定虛擬機所需要的所有東西,它可以為你構(gòu)建和運行該虛擬機。
與前一節(jié)中的Dockerfile類似,Hashicorp的Vagrant使用一個Vagrantfile,其中包含有關(guān)如何啟動和配置虛擬機的指令。
就像Docker映像提供了運行容器的基本文件系統(tǒng)一樣,Vagrant box也為虛擬機提供了基礎(chǔ)文件系統(tǒng)。
下面的示例Vagrantfile與上一節(jié)中的Dockerfile所做的事情類似:
使用這個文件克隆你的存儲庫,并運行這些命令來啟動VM,然后你就會進入它的shell:
Vagrant確實通過使用Vagrant Box catalog提供與DockerHub類似的體驗來幫助我們解決分發(fā)問題。
有了它,你可以得到你的基礎(chǔ)映像或上傳新的映像與他人分享。你甚至可以將一個Vagrantfile指向內(nèi)部的URL去下載一個box。
更多詳情:https://www.vagrantup.com/intro/index.html
PyInstaller
我們之前已經(jīng)介紹過這個模塊。PyInstaller負責(zé)綁定運行你的應(yīng)用程序所需的所有資源,包括Python發(fā)行版。在爬取你的代碼時,它會指出要打包哪些Python依賴項,同時仍然允許你指定其它要包括在bundle中的資源。
它的打包結(jié)果是一個適用于Windows、Linux或OSX的可安裝應(yīng)用程序。在執(zhí)行期間,它會將該程序與綁定的解釋器一起解壓到一個文件夾中,并運行你的入口點腳本。
它足夠靈活,可以讓你控制Python發(fā)行版和執(zhí)行環(huán)境。我甚至成功地使用它將瀏覽器與我的Python包綁定在一起。
但使用它確實會帶來麻煩。在提取自身時,它將更改應(yīng)用程序運行的基本目錄。這意味著,任何依賴__file__來確定當(dāng)前執(zhí)行路徑的代碼現(xiàn)在都需要使用PyInstaller配置的內(nèi)部環(huán)境。
分發(fā)你的bundle完全取決于你。對于這種類型的設(shè)置,大多數(shù)人選擇對象存儲和CDN。
在以這種方式分發(fā)時要記住一點,即檢查你的代碼是否需要驗證它所運行的操作系統(tǒng)環(huán)境。
換句話說,與使用Docker或Vagrant不同,如果你需要安裝特定的apt包,那你就無法保證該包在執(zhí)行期間就已經(jīng)存在。
更多詳情:https://www.pyinstaller.org/?
Briefcase
Briefcase是這類產(chǎn)品的后起之秀。它是Beeware項目的一部分,該項目旨在將Python應(yīng)用程序打包分發(fā)給所有操作系統(tǒng)和設(shè)備,包括Android和iOS。
它與PyInstaller處于類似的領(lǐng)域,這意味著它可以將你的模塊及其依賴項綁定到一個可安裝的應(yīng)用程序中。但它也增加了對移動設(shè)備和帶有AppleTV或tvOS的電視的支持。
不幸的是,其文檔仍然有點松散,而且主要是以示例的形式。然而,該項目很有前景,并且仍在積極開發(fā)中。頗受歡迎的編輯器Mu就將它用于打包。
你可以將使用Briefcase構(gòu)建的應(yīng)用程序提交到Android和Apple應(yīng)用商店進行分發(fā)。
更多詳情:https://beeware.org/project/projects/tools/briefcase/?
虛擬環(huán)境
有時,我們可以假設(shè)你的用戶擁有一個標(biāo)準(zhǔn)的操作系統(tǒng)。也許他們都是從公司內(nèi)部的IT部門構(gòu)建的庫存映像運行的。也許你的應(yīng)用程序很簡單,根本不必擔(dān)心操作系統(tǒng)或解釋器的復(fù)雜性。
如果你只需要考慮Python代碼及其依賴關(guān)庫,那么這個類別適合你。
Pex
Pex是由Twitter的員工構(gòu)建的,它是一種將整個虛擬環(huán)境與你的Python應(yīng)用程序一起發(fā)布的方法。它被設(shè)計為使用一個預(yù)先安裝的Python解釋器,它利用了為Python Zip應(yīng)用程序構(gòu)建的標(biāo)準(zhǔn)(在PEP-441中有概述)。
從Python 2.6開始,解釋器就能夠?qū)⒛夸浕騴ip格式的歸檔文件作為腳本執(zhí)行。
Pex構(gòu)建在此基礎(chǔ)之上,簡化了復(fù)制單個文件的分發(fā)過程。這些文件可以在不同的平臺(OSX、Linux、Windows)以及不同的解釋器上工作。盡管在使用帶有C綁定的模塊時存在一些限制。
在你的基本系統(tǒng)中安裝Pex之后,你可以使用它生成一個包含整個Python環(huán)境的文件。
將該文件傳遞到你同事的計算機,你將能夠在那里執(zhí)行該文件,而不需要安裝除基本Python解釋器之外的任何東西。
你甚至可以在解釋器模式下運行一個文件,這樣它就會打開一個Python REPL,其中包含你的環(huán)境中可以導(dǎo)入的所有必要模塊。
將你的虛擬環(huán)境凍結(jié)為一個.pex文件相當(dāng)簡單:
然后你可以執(zhí)行該文件來打開一個帶有你的環(huán)境的REPL:
你還可以在創(chuàng)建文件時指定入口點,以便它可以在你的模塊中執(zhí)行特定的函數(shù),就像你直接運行python命令一樣。
目前沒有系統(tǒng)可以為你分發(fā)Pex文件,因此,就像前面的項目一樣,你只能使用公共對象存儲和CDNs。
更多詳情:https://github.com/pantsbuild/pex
Shiv
與Pex類似,LinkedIn的人員建立了一個不同的模塊,稱為Shiv。他們構(gòu)建一些不同的東西的主要原因是試圖在Pex可執(zhí)行文件的開始期間嘗試并解決一個問題??紤]到存儲庫和依賴項的復(fù)雜性,他們希望以不同的方式處理環(huán)境設(shè)置。
代替將各種輪子與應(yīng)用程序一起打包,Shiv會包含一個完整的由pip安裝的site-packages目錄。這讓所有的東西都能開箱即用,并且速度幾乎是Pex的兩倍。
這里是一個如何使用Shiv生成一個.pyz文件的例子,它做了一些與Pex部分類似的事情:
然后,你就可以使用以下命令直接執(zhí)行它:
需要注意的是,打包帶有OS依賴項的庫在平臺之間是不交叉兼容的。正如在Pex部分中提到的,這主要是依賴于底層C庫的模塊的問題。你必須為每個平臺生成不同的文件。
同樣,目前還沒有讓你分發(fā)這些文件的構(gòu)建系統(tǒng),所以你必須依賴AWS、DO、CDNs或其他應(yīng)用商店,如JFrog的Artifactory或Sonatype的Nexus。
更多詳情:https://github.com/linkedin/shiv
Pipx
雖然不是構(gòu)建應(yīng)用程序或分發(fā)它們的方法,但Pipx提供了一種不同的方式來安裝它們。它與你的操作系統(tǒng)一起工作,以隔離虛擬環(huán)境及其依賴項,更接近于Homebrew等系統(tǒng)對OSX的作用。
Pipx提供了一種簡單的方法,可以讓你將包安裝到隔離的環(huán)境中,并全局地公開它們的命令行入口點。它還提供了一種機制來列出、升級和卸載這些包,而不涉及虛擬環(huán)境的細節(jié)。
一個很好的例子就是linter的使用。假設(shè)你在多個python應(yīng)用程序上工作,每個應(yīng)用程序都有一個單獨的virtualenv,你希望使用flake8在所有應(yīng)用程序上執(zhí)行相同的linting操作。
代替將flake8模塊安裝到每個virtualenv中,你可以使用Pipx來安裝一個全系統(tǒng)范圍的flake8命令,該命令在每個環(huán)境中都可用,但運行在它們自己完全獨立的環(huán)境中。
更多詳情:https://pypi.org/project/pipx/?
單文件可執(zhí)行文件
有時,你希望為客戶提供一個不需要預(yù)裝庫即可運行的可執(zhí)行文件,就像你使用Docker或Pex一樣。
這里描述的機制可以幫助你完成此任務(wù)。和前面的類別一樣,它們都需要某種形式的對象或應(yīng)用商店來幫助分發(fā)。
PyInstaller
雖然我們已經(jīng)討論了PyInstaller,但是在這個類別中還是值得再次提及它,因為這是它的主要功能之一。
它可以生成整個應(yīng)用程序的單個可執(zhí)行文件,并綁定所有依賴項。你可以為每個操作系統(tǒng)創(chuàng)建一個,它就可以像任何其他本機應(yīng)用程序一樣運行。
PyOxidizer
作為打包和分發(fā)領(lǐng)域的最新產(chǎn)品之一,PyOxidizer非常有前途。它利用了為Rust編程語言創(chuàng)建的打包工具。
與PyInstaller非常相似,你可以完全控制想要綁定到其中的所有內(nèi)容,但它也可以允許你執(zhí)行類似Pex或Shiv的代碼。這意味著你可以創(chuàng)建你的包,使它作為一個REPL運行,其中的所有依賴項都已預(yù)先安裝。
分發(fā)一個包括REPL的完整Python環(huán)境會產(chǎn)生一些令人興奮的應(yīng)用程序,特別是對于需要多個包來進行數(shù)據(jù)探索的研究團隊或科學(xué)計算。
與PyInstaller相比的一個優(yōu)點是,它不是提取到文件系統(tǒng),而是將自身提取到內(nèi)存中,從而大大縮短了實際的Python應(yīng)用程序的啟動時間。
這個特性與PyInstaller有類似的缺點。你必須將任何內(nèi)部引用調(diào)整為__file__或類似的操作,因此它們依賴于運行時PyOxidizer配置的環(huán)境。
更多的細節(jié)可以在他們的官方文檔中找到,但我們也在這篇文章中對此做了很多的介紹。
Nuitka
除了使用一個綁定的解釋器執(zhí)行Python代碼之外,你還可以選擇將代碼編譯為C。這帶來了幾個好處,包括更快執(zhí)行的可能性,因為C編譯器可以執(zhí)行解釋器無法執(zhí)行的優(yōu)化。
Nuitka是為將Python代碼編譯成C而構(gòu)建的系統(tǒng)。雖然這個概念類似于更廣為人知的Cython,但它不是一種單獨的語言。它還能做Cython做不到的事情,比如抓取依賴項并將所有東西編譯成一個二進制文件。
生成的可執(zhí)行文件能在本地代碼中以更快的速度運行,并且不需要提取。
編譯可能會變得很復(fù)雜,尤其是考慮到平臺的復(fù)雜性時。但是如果你為它安排好了時間,你就能獲得好處。我以前成功地做過幾次。
更多詳情:https://nuitka.net/?
應(yīng)用商店體驗
我們幾乎每天都在使用的其他應(yīng)用程序分發(fā)系統(tǒng):應(yīng)用商店。此軟件用于安裝和維護其他應(yīng)用程序。
就像Apple App Store或谷歌Play Store一樣,在Linux中也有類似的機制來支持簡單的集成。
Snapcraft
Snapcraft提供標(biāo)準(zhǔn)的應(yīng)用商店體驗。你可以將你的應(yīng)用程序發(fā)布到他們的商店,用戶可以在那里發(fā)現(xiàn)并安裝它。
安裝是獨立的,以避免與其他應(yīng)用程序發(fā)生沖突,并且它可以跨Linux發(fā)行版工作,包括庫依賴項。
安裝后,應(yīng)用商店會自動將應(yīng)用程序保持在最新的穩(wěn)定版本,并提供一種機制來在保留數(shù)據(jù)同時恢復(fù)到以前的狀態(tài)。
Ubuntu管理著這個商店,所以你在打包了你的應(yīng)用程序(或者他們所說的snap)之后,你必須用一個注冊的Ubuntu One帳號將這個snap發(fā)布到商店。
更多詳情:https://snapcraft.io/?
Flatpak
另一個與Snapcraft非常相似的概念是Flatpak。
它還通過使用容器技術(shù)為應(yīng)用程序提供隔離來提供與FlatHub.org類似的存儲體驗。不過,您也可以托管自己的私有hub,或者在單個文件中分發(fā)包。
Flatpak包還可以利用一些桌面集成功能。它們提供了諸如位置檢測、訪問應(yīng)用程序外部資源的能力(很像您的手機請求權(quán)限去打開文件或URL)、通知、窗口裝飾等信息。
更多創(chuàng)建您的第一個Flatpak的細節(jié)和說明,請查看這里:http://docs.flatpak.org/en/latest/first-build.html#?
總結(jié)
我們擁有一個完整的、功能豐富的應(yīng)用程序打包和分發(fā)機制生態(tài)系統(tǒng)。其中大多數(shù)都不是特定于Python語言的,但是很容易與它進行集成。
雖然分發(fā)應(yīng)用程序看起來有很多選擇,但我希望這里應(yīng)用的分類能幫助您根據(jù)你可以控制的部分選擇最適合您需要的方式。
英文原文:https://tryexceptpass.org/article/distributing-python-applications/?譯者:Nothing
總結(jié)
以上是生活随笔為你收集整理的本地分发_2020年分发Python应用程序的12个热门途径的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux如何查看硬盘的使用情况
- 下一篇: python asyncio理解_深入理