# PYENV + POETRY/PIPENV ## Pyenv ### 1. pyenv install curl https://pyenv.run | bash the folder **`.pyenv`** have generated at `~/` ![image](https://hackmd.io/_uploads/rJfnu6S8T.png) ### 2. add the commands to `~/.bashrc` by running the following in your terminal: ```script= echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc echo 'eval "$(pyenv init -)"' >> ~/.bashrc ``` **Then, update `.bashrc`** ```python= source .bashrc ``` **Finally, check pyenv** ```python= pyenv ``` ![image](https://hackmd.io/_uploads/SyF8ZaH86.png) ### 3. Install specific version of python ```ubuntu= # install dependencies sudo apt update sudo apt install \ build-essential \ curl \ libbz2-dev \ libffi-dev \ liblzma-dev \ libncursesw5-dev \ libreadline-dev \ libsqlite3-dev \ libssl-dev \ libxml2-dev \ libxmlsec1-dev \ llvm \ make \ tk-dev \ wget \ xz-utils \ zlib1g-dev ``` ```ubuntu= # install specific version of python pyenv install <python version> ``` ![image](https://hackmd.io/_uploads/HyigMprUT.png) ```ubuntu= # check installed python version pyenv versions ``` ![image](https://hackmd.io/_uploads/SJgpBupB86.png) 如果想針對某個資料夾指定切換 Python 版本的話,可以在該資料夾內使用指令 **`pyenv local <版本>`** 指令指定版本,該指令會在該資料夾內建立一個 **`.python-version`** 檔案,如果未來再進入該資料夾, pyenv 就會根據 **`.python-version`** 的內容自動切換 Python 版本,例如: ```ubuntu= cd my-python-3.10.9-project pyenv local 3.10.9 python --version Python 3.10.9 ``` ## Poetry ### Installat Poetry ```ubuntu= curl -sSL https://install.python-poetry.org | python3 -poetry --version ``` or ```ubuntu= curl -sSL https://install.python-poetry.org | python3 - ``` **Optional: Tell poetry to create virtual environments in the current project directory** ```ubuntu= poetry config virtualenvs.in-project true poetry config virtualenvs.in-project # true ``` **PATH** ```script= # exporting export PATH="/home/smg/.local/bin:$PATH" ``` ![image](https://hackmd.io/_uploads/rJAp2aBLa.png) ```ubuntu= # update .bashrc source .bashrc # 查看poetry env資訊 poetry env info ``` ![image](https://hackmd.io/_uploads/rJAh2H0_6.png) ### Poetry 指令 ```ubuntu= poetry init # 於專案資料夾初始化 poetry config --list # 查看config 內容 poetry env use/remove python # 建立/移除虛擬環境 可另外指定Python 版本 poetry shell # 啟動虛擬環境,需先移至專案目錄下,使用exit 即可退出 # 相當於pip install/uninstall,會更改pyproject.toml & poetry.lock 內容 poetry add/remove <package> # -G dev, --group dev 將只在開發環境使用的套件放置於dev-dependencies 區塊中 # 若有手動更改pyproject.toml,需使用此指令同步更新poetry.lock 內容。 poetry lock # 此指令僅會更新poetry.lock,並「不會安裝」套件至虛擬環境。 # 安裝套件至虛擬環境 poetry install # 更新全部可能可以更新的套件 poetry update # 更新特定套件 poetry update <package> # 使用樹狀結構呈現poetry.lock 的套件內容 poetry show --tree # 使用樹狀結構呈現poetry.lock 的特定套件內容 poetry show <package> --tree # 相當於pip freeze poetry export -f requirements.txt -o requirements.txt --without-hashes ``` **Switching an existing project to poetry** ```ubuntu= pyenv shell 3.8.1 poetry init # install from requirement.txt cat requirements.txt | perl -pe 's/([<=>]+)/:$1/' | xargs -t -n 1 -I {} poetry add '{}' #or cat requirements.txt | grep -E '^[^# ]' | cut -d= -f1 | xargs -n 1 poetry add ``` ## Pyenv + Poetry Work Flow ```pytho== git clone <git url> # 複製Project cd <project folder> # 進入Project 資料夾 pyenv install <Python version> # (Optional) 如果沒安裝過該Python 版本 pyenv local <Python version> # 指定py版本 poetry env use <Python version> # 於Project folder 中創建Python 虛擬環境 poetry shell # 進入venv shell poetry install # 依照poetry.lock 安裝套件至虛擬環境 ``` 1. poetry env use python 預設會統一建立在特定目錄Cache中,建議將虛擬環境綁定在專案上。 ```ubuntu= poetry config virtualenvs.in-project true ``` 2. `poetry add` 相當於 `pip install` 3. `poetry.lock` 相當於 `requirements.txt` ### Self project 1. install python version `pyenv install 3.12` ![image](https://hackmd.io/_uploads/rJvrZeDIa.png) 2. enter to project folder `cd <project>` 3. set python version `pyenv local 3.12.1` 4. poetry init `poetry init` ![image](https://hackmd.io/_uploads/BkT8flDIa.png) 5. poetry env use python 預設會統一建立在特定目錄Cache中,建議將虛擬環境綁定在專案上。 ```ubuntu= poetry config virtualenvs.in-project true # poetry use the specific python poetry env use 3.12.1 ``` ![image](https://hackmd.io/_uploads/SyJ-leZDA.png) 6. check python ```ubuntu= # activate shell poetry shell which python ``` ![image](https://hackmd.io/_uploads/r1TOhxGYp.png) 7. virtual env `poetry shell` ### Git project ``` git clone <git url> # 複製Project cd <project folder> # 進入Project 資料夾 pyenv install <Python version> # (Optional) 如果沒安裝過該Python 版本 poetry env use <Python version> # 於Project folder 中創建Python 虛擬環境 poetry install # 依照poetry.lock 安裝套件至虛擬環境 ``` ![image](https://hackmd.io/_uploads/HkizA6rLT.png) ## Pipenv ### Pipfile & Pipfile.lock Pipfile是用來替代原來的requirements.txt的。 內容類似下面這樣。source部分用來設置倉庫地址,packages部分用來指定項目依賴的包,dev-packages部分用來指定開發環境需要的包,這樣分開便於管理。 ``` [[source]] url = "https://pypi.python.org/simple" verify_ssl = true name = "pypi" [packages] requests = "*" parsel = "==1.3.1" celery = "*" [dev-packages] pymysql = "*" ``` * `[[source]]` 是比較少人會更動到的,基本上可以保留不要動。 * `url` 此處宣告你之後要透過 pipenv 「去哪裡」下載套件們,default 是官方網站 PYPI。 * `verify_ssl` 是可以調整是否要使用 SSL 安全防護機制。 `[dev-packages]` 和 `[packages]` 是未來你透過 `pipenv install` 安裝套件時會把安裝的套件名稱與版本紀錄在此,管控這個專案的套件版本。 其中`[dev-packages]` 和 `[packages]` 顧名思義取決於在開發的環境到底是 production 還是 development * development 開發環境會使用到比較多的套件輔助測試、debug 或團隊協同 * production 開發環境則會使用最後產品要上線所需之套件 `[requires]` 是用來管控此專案的 python 版本。比大小的 prefix 不只一種,有: `*` 、`>`、 `>=`、 `<`、 `<=` 、`==` (和不加 prefix 相同)。例如: * `python_version = ">=3.6"` * `python_version = "==3.5.2"` * `python_version = "3.2.5"` * `python_version = "*"` (允許全部版本) 注意「比較版本的大小」如果限制式只有到第一位版本號那麼第二位以下就不管,如果限制式只有到第二位版本號,那麼第三位就不管。例如: `"python>=3.5"` 那麼所有 3.5.x 以上的都可以使用 `"python<=3"` 那麼所有 2.x.x 和 3.x.x 都可以使用(以2018年來說,就是全部版本xD) 此外,有一點必須注意,此處的 `[[requires]]` 乍看單字意思好像也可以套用在套件版本限制上,但這是錯的!目前這個地方有用的只是控制 python 版本而已,要限制 python 套件版本是寫在前面 `[[packages]]` 和 `[[dev-packages]]` 。 ### Install `pip install pipenv` `pipenv install --python=$(which python)` ### Create environment `cd <target folder>` `pipenv --python 3.11.1` ![image](https://hackmd.io/_uploads/rJchBRwIa.png) ### 進入 / 退出環境 `pipenv shell` `exit` ### 安裝 / 更新 / 卸載依賴 安裝項目已有的所有依賴,加--dev表示包括 Pipfile 的 dev-packages 中的依賴。 安裝現有的requirements.txt `pipenv install -r path/to/requirements.txt` 安裝某個包。 `pipenv install --dev` 安裝指定版本的包,安裝時加--dev表示加入到 dev 環境。 `pipenv install requests` 從項目中更新某個包 `pipenv install parsel==1.3.1` 或更新所有的包 `pipenv update requests` 從項目環境中移除某個包 `pipenv update` 另外,Pipefile 和 Pipefile.lock 都會按照你的操作進行自動的更新,如果需要手動修改包的依賴條件,手工編輯 Pipefile 並進行安裝即可。 `pipenv uninstall requests` 在 Dockerfile 中安裝依賴,加--system參數表示使用 pip 直接安裝相應依賴,不創建虛擬環境。 `RUN pipenv install --deploy --system` ### 打印環境中已安裝的包 **查看目前依賴包** `pipenv graph` **輸出requirements.txt** `pipenv run pip freeze > requirements.txt` `pipenv lock -r --dev > requirements.txt` ### 鎖定版本 **更新 lock 文件鎖定當前環境的依賴版本** `pipenv lock` ### 環境變量管理 如果你開發調試時需要配一堆環境變量,可以寫到.env文件中,在pipenv shell進入虛擬環境時,它會幫你把這些環境變量加載好,非常方便。 例如寫一個.env文件 `echo "FOO=23333" > .env` 之後`pipenv shell`進入虛擬環境,`echo $FOO`就能看環境變量的值23333已經設置好了。