2025年5月10日 星期六

Python 學習筆記 : Streamlit 升版至 v1.45.0

我在 2023 年開始學習 Streamlit, 但後來因為較常使用 Gradio 因而學習停頓下來, 最近在 LangChain 的書上發現蠻多 LLM 使用 Streamlit 來開發 AI 應用, 因此決定先來把 Streamlit 認真地測試完, 所謂工欲善其事必先利其器也.

先來提升版本, 檢視 LG 筆電目前的 Streamlit 版本 : 

>>> import streamlit as st    
>>> st.__version__   
'1.27.0'

事實上兩年間它已演進到最新的 v1.45.0 了, 而且上週安裝 LangChain 時它強制將一些與 Streamlit 共用的相依套件升版, 這可能造成舊版的 Streamlit 執行時出現錯誤, 這可以透過將 Streamlit 升至最新版解決, 指令如下 : 

pip install streamlit -U

D:\python\test>pip install streamlit -U   
Requirement already satisfied: streamlit in c:\users\tony1\appdata\roaming\python\python310\site-packages (1.27.0)
Collecting streamlit
  Downloading streamlit-1.45.0-py3-none-any.whl.metadata (8.9 kB)
Requirement already satisfied: altair<6,>=4.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (5.1.1)
Requirement already satisfied: blinker<2,>=1.5.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (1.6.2)
Requirement already satisfied: cachetools<6,>=4.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (5.3.1)
Requirement already satisfied: click<9,>=7.0 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from streamlit) (8.1.8)
Requirement already satisfied: numpy<3,>=1.23 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (1.24.3)
Requirement already satisfied: packaging<25,>=20 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from streamlit) (24.2)
Requirement already satisfied: pandas<3,>=1.4.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (2.0.3)
Requirement already satisfied: pillow<12,>=7.1.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (9.5.0)
Requirement already satisfied: protobuf<7,>=3.20 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from streamlit) (5.28.1)
Requirement already satisfied: pyarrow>=7.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (13.0.0)
Requirement already satisfied: requests<3,>=2.27 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (2.31.0)
Requirement already satisfied: tenacity<10,>=8.1.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (8.2.3)
Requirement already satisfied: toml<2,>=0.10.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (0.10.2)
Requirement already satisfied: typing-extensions<5,>=4.4.0 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from streamlit) (4.12.2)
Requirement already satisfied: watchdog<7,>=2.1.5 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (2.3.1)
Requirement already satisfied: gitpython!=3.1.19,<4,>=3.0.7 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (3.1.37)
Requirement already satisfied: pydeck<1,>=0.8.0b4 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (0.8.1b0)
Requirement already satisfied: tornado<7,>=6.0.3 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from streamlit) (6.3.3)
Requirement already satisfied: jinja2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from altair<6,>=4.0->streamlit) (3.1.2)
Requirement already satisfied: jsonschema>=3.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from altair<6,>=4.0->streamlit) (4.19.0)
Requirement already satisfied: toolz in c:\users\tony1\appdata\roaming\python\python310\site-packages (from altair<6,>=4.0->streamlit) (0.12.0)
Requirement already satisfied: colorama in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from click<9,>=7.0->streamlit) (0.4.6)
Requirement already satisfied: gitdb<5,>=4.0.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from gitpython!=3.1.19,<4,>=3.0.7->streamlit) (4.0.10)
Requirement already satisfied: smmap<6,>=3.0.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from gitdb<5,>=4.0.1->gitpython!=3.1.19,<4,>=3.0.7->streamlit) (5.0.1)
Requirement already satisfied: python-dateutil>=2.8.2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pandas<3,>=1.4.0->streamlit) (2.8.2)
Requirement already satisfied: pytz>=2020.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pandas<3,>=1.4.0->streamlit) (2023.3)
Requirement already satisfied: tzdata>=2022.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pandas<3,>=1.4.0->streamlit) (2023.3)
Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests<3,>=2.27->streamlit) (3.2.0)
Requirement already satisfied: idna<4,>=2.5 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests<3,>=2.27->streamlit) (3.4)
Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from requests<3,>=2.27->streamlit) (1.26.19)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests<3,>=2.27->streamlit) (2023.7.22)
Requirement already satisfied: MarkupSafe>=2.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from jinja2->altair<6,>=4.0->streamlit) (2.1.3)
Requirement already satisfied: attrs>=22.2.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from jsonschema>=3.0->altair<6,>=4.0->streamlit) (23.1.0)
Requirement already satisfied: jsonschema-specifications>=2023.03.6 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from jsonschema>=3.0->altair<6,>=4.0->streamlit) (2023.7.1)
Requirement already satisfied: referencing>=0.28.4 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from jsonschema>=3.0->altair<6,>=4.0->streamlit) (0.30.2)
Requirement already satisfied: rpds-py>=0.7.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from jsonschema>=3.0->altair<6,>=4.0->streamlit) (0.10.2)
Requirement already satisfied: six>=1.5 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from python-dateutil>=2.8.2->pandas<3,>=1.4.0->streamlit) (1.16.0)
Downloading streamlit-1.45.0-py3-none-any.whl (9.9 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 9.9/9.9 MB 8.2 MB/s eta 0:00:00
Installing collected packages: streamlit
  Attempting uninstall: streamlit
    Found existing installation: streamlit 1.27.0
    Uninstalling streamlit-1.27.0:
      Successfully uninstalled streamlit-1.27.0
Successfully installed streamlit-1.45.0

在命令列可用 streamlit version 指令檢視目前版本 : 

D:\python\test>streamlit version  
Streamlit, version 1.45.0  

也可以進入 Python 執行環境檢查 : 

>>> import streamlit as st  
>>> st.__version__   
'1.45.0'

新版主要的功能與架構異動摘要如下 : 
  1. 新的分頁架構 :
    新版 API 引入 st.navigation() 和 st.Page() 函式讓開發者能以程式化方式定義應用的頁面與導覽功能, 使頁面可以依據使用者的操作而動態變化, 並支援在主程式中設定共用的初始化邏輯, 樣式與權限檢查. 新的側邊欄導覽也支援群組標題, Material Icons 及應用程式 Logo 等功能. 
  2. 使用者資訊存取物件 st.user : 
    st.user 是一個類似字典的物件, 可讓開發者存取目前使用者的相關資訊, 例如 IP, URL, 以及是否為嵌入式等, 這對於需要進行使用者識別或權限控管的應用特別有用.
  3. 增強元件的互動性 :
    例如 st.multiselect 和 st.selectbox 引入了可讓使用者新增自定義選項的參數; st.text_input 和 st.number_input 現在可以在輸入框左側加入圖示以提升使用者介面的可讀性與美觀性; st.components.v1.html 和 st.components.v1.iframe 新增設定 tab index 的功能, 可改善鍵盤導覽體驗. 
  4. 自訂主題與外觀 : 
    新版引入了進階的主題設定, 讓開發者無需撰寫 CSS 就可以透過設定檔自訂應用程式的字體, 顏色與圓角等外觀. 此外 st.badge 元件允許在應用中插入彩色徽章, 並可在 Markdown 中使用新的指令來加入徽章.
  5. DataFrame 資料框互動性提升 :
    使用者可以拖曳資料框的欄位以重新排序; 支援釘選功能並在滑鼠懸停時高亮顯示列; 當資料框中的欄位值與其設定的類型不一致時 Streamlit 會顯示工具提示以說明錯誤.
  6. 其他重大改變 :
    • 音訊輸入元件改為 st.audio_input, 實驗版的 st.experimental_audio_input 元件已被移除.
    • 支援 Python 3.13 並停止支援 Python 3.8.
    • st.exception 元件已可包含連結以方便開發者直接在 Google 或 ChatGPT 中查詢錯誤內容. 
新版在多頁應用架構, 使用者資訊存取, 與元件互動性與主題自訂等方面的變更可說了增進了開發者的方便與大幅提升了使用者體驗. 

2025年5月9日 星期五

露天購買 ESP32-WROVER-DEV 開發板 x 2

我在去年 10 月底在露天買了一塊 ESP32-WROVER-DEV 開發板來測試用 MicroPython v1.21 (客製版) 控制擷取影像, 結果可以順利取得影像 : 


但如果想要使用最新韌體, 就需要自行編譯包含 camera 模組的韌體, 這我目前還不會, 所以打算直接用 Arduino IDE 以 C 語言來控制, 今天上露天向原廠商回購兩塊, 價格仍然每塊 218 元 :




全家取貨免運 436 元. 

Stable Diffusion 學習筆記 (十五) : 使用者介面設定與繁體中文化

上個月春假時安裝好 Stable Diffusion 常用外掛後就暫停下來去忙 OpenAI API 測試了, 今天重新翻閱杰克艾米立的書才發現我安裝完外掛少做了兩個動作, 今天就來把它補全吧.


1. 使用者介面設定 : 

點選右上角的 "設定" 頁籤 :




頁面往下拉, 點選左方導覽列 "使用者介面" 項下的 "使用者介面" 連結 : 




在 "使用者介面" 頁面上方有一個 "快捷設定列表", 在其下方輸入框輸入 "sd_vae" 會彈出一個選單, 點選其中的 sd_vae 它就會加入列表中 : 





接著在輸入框中輸入 "CLIP", 於彈出選單中點選 "CLIP_stop_at_last_layers" 將其加入列表中 :




按上面的 "套用設定" 鈕 : 




按右邊的 "重新載入 UI" 鈕 :




在命令提示字元視窗按 Ctrl +C 輸入 Y 完全關閉 WebUI, 然後重新執行 run.bat, 這時 SD 頁面就會出現很多新的介面 : 




2. 繁體中文化設定 : 

上面的設定雖然刷新了介面, 但有幾個是很礙眼的殘體中文, 接下來要把它改成美美繁體字, 按 "文生圖" 頁籤中的地球圖形按鈕 : 




在彈出選單中點選正統的台灣繁體中文 (zh_TW) : 




然後按地球小圖右邊的設定齒輪按鈕, 這時右邊會彈出一列按鈕, 按第一個 "API" 按鈕 : 




這時會彈出一個翻譯選單, 預設是阿里翻譯, 點選翻譯接口的下拉式選單 : 




選擇 Google 翻譯 : 





將右方卷軸往下拉到底, 按最底下的 "保存" 鈕即完成設定 : 




完成以上設定就萬事俱備可以開始來玩 SD 繪圖啦! 

2025年5月8日 星期四

MAZDA MX-5 汽車險

菁菁去年底拿到駕照後買的二手 MAZDA MX-5 強制險到期, 原車主投保華南產險, 上週收到華南寄來的強制險續約單, 兩年是 1926 元, 昨晚上明台產險網站幫她試算保費, 只保兩年強制險是 1596 元, 加保任意險試算三種組合如下 : 
  1. 汽車第三人責任保險條款-傷害 (100 萬) + 汽車第三人責任保險乘客傷害責任附加條款 (100 萬) : 強制 1596 + 任意 2414=4010 





  2. 汽車第三人責任保險條款-傷害 (100 萬) + 汽車第三人責任保險乘客傷害責任附加條款 (100 萬) + 汽車第三人責任保險條款-財損 (20 萬) : 強制 1596 + 任意 6896=8492 




  3. 汽車第三人責任保險條款-傷害 (100 萬) + 汽車第三人責任保險乘客傷害責任附加條款 (100 萬) + 汽車第三人責任保險條款超額責任條款 (甲式自用車累計 1000 萬) + 汽車第三人責任保險條款-財損 (20 萬) : 強制 1596 + 任意 8891=10487





菁菁選第三個. 因為任意險期間為一年, 強制險選兩年, 所以明年保費就扣除強制險為 8891 元. 這台二人座跑車原價 152 萬, 試算時網站跳出通知說屬於高價車, 無法投保車體險與竊盜險. 此車 2017 年 4 月出廠, 排氣量 1998, 車款是 54069500 MX-5 RF 旗艦型.

好書 : 機器學習的高風險應用

今天在天瓏找到下面這本歐萊禮的好書 : 



此書吸引我的地方是在 Part 2 有專門講 XGBoost : 


好消息是市圖可借到不用買 :


2025年5月7日 星期三

市圖還書 2 本 (精通機器學習 + Python大數據特訓班)

今天市圖借的書有兩本被人預約須還 :
回程去明儀找 LangChain 的書, 覺得書店人好少啊! 如果價差不多還是要盡量跟明儀買, 社區有一間書店真的很不錯. 

關於勞保老年給付

今天久未聯絡的老同學蘇董突然給了我一個早安圖, 我回應後聊了起來, 提到說他最近起心動念想提早退休, 公保年資月退應該有 2.7K, 這讓我想到我的勞保月退有多少的問題, 找到勞保局網站的老年給付計算公式, 原來是有兩個公式擇優套用 :


如果做到 65 歲屆退的話, 我的勞保年資含以前做 IC 設計的 4 年剛好滿 30 年, 以最高投保薪資 45800 元用第一個公式計算才 13648 元而已 :




用第二個公式計算則有 21297 元 :




呵呵, 居然 22K 不到啊! 當年應該聽外婆的勸去念屏東師專才對的, 就算年金改革月退起碼還有 5~6 萬元哩 (這是回鄉務農的國中同學告訴我的, 他花師畢業當了一輩子老師, 五年前從小學總務主任職務上提早退休). 唉, 不聽老人言吃虧不會在眼前, 而是在 40 年後啊! 外婆, 我錯了 (但那個時候我只是一個 15 歲少年啊! 哪裡能知曉鈔票的輕重?). 

LangChain 學習筆記 : 在虛擬環境中安裝 LangChain

在前一篇測試中順利在系統的 Python 環境中安裝了 LangChain, 但這種方式可能因為 LangChain 強行將某些相依套件升版導致版本衝突, 使得有用到這些被升版套件的其他套件無法正常執行. 

避免版本衝突的方法是在虛擬環境中安裝 LangChain, 傳統上使用 virtualenv 來建立虛擬環境, 但我在 "LangChain 奇幻旅程" 這本書看到管理套件與虛擬環境的好工具 Poetry, 安裝方式參考 :


安裝完 Poetry 且用 poetry config virtualenvs.in-project true 指令開啟專案內的虛擬環境功能後, 就可以在目前工作目錄下用 poetry new 指令來建立一個 Python 專案 : 

D:\python\langchain>poetry new project1    
Created package project1 in project1  

這樣便建立了一個 projetc1 專案 : 




專案目錄下有一個 pyproject.toml 為專案設定檔, Poetry 利用此檔來儲存專案的 metadata, 主要用來管理套件與其依賴關係, 可用記事本開啟, 預設內容如下 : 

[project]
name = "project1"
version = "0.1.0"
description = ""
authors = [
    {name = "Your Name",email = "you@example.com"}
]
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
]

[tool.poetry]
packages = [{include = "project1", from = "src"}]


[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

其中的 requires-python 變數用來指定虛擬環境的 Python 版本, 此處 >=3.12 表示最低版本為 3.12, 也可以拿掉 ">=" 指定精確版本. dependencies 變數用來放置安裝的套件名稱, 預設是空串列表示尚未安裝任何套件, 當使用 poetry add 指令安裝套件時就會自動將套件名稱放進 dependencies 串列中了. 

接下來先用上面預設的專案設定檔來安裝虛擬環境與 LanChain. 

首先進入專案目錄 project1 : 

D:\python\langchain>cd project1     

然後執行 poetry install 指令, 這會依照專案設定檔 pyproject.toml 中 requires-python 變數所規範的 Python 版本去安裝 Python 虛擬環境 : 

D:\python\langchain\project1>poetry install  
Creating virtualenv project1 in D:\python\langchain\project1\.venv
Updating dependencies
Resolving dependencies... (0.1s)

Writing lock file 

Installing the current project: project1 (0.1.0)

完成後在專案目錄下就會多出一個 .venv 子目錄 :




用 poetry run python --version 指令檢視此虛擬環境之 Python 版本 : 

D:\python\langchain\project1>poetry run python --version    
Python 3.12.2 

接下來用 poetry add 指令安裝 LangChain : 

D:\python\langchain\project1>poetry add langchain    
Using version ^0.3.25 for langchain

Updating dependencies
Resolving dependencies... (4.8s)

The current project's supported Python range (>=3.12.4) is not compatible with some of the required packages Python requirement:
  - langchain-text-splitters requires Python <4.0,>=3.9, so it will not be installable for Python >=4.0

Because no versions of langchain match >0.3.25,<0.4.0
 and langchain (0.3.25) depends on langchain-text-splitters (>=0.3.8,<1.0.0), langchain (>=0.3.25,<0.4.0) requires langchain-text-splitters (>=0.3.8,<1.0.0).
Because langchain-text-splitters (0.3.8) requires Python <4.0,>=3.9
 and no versions of langchain-text-splitters match >0.3.8,<1.0.0, langchain-text-splitters is forbidden.
Thus, langchain is forbidden.
So, because project1 depends on langchain (^0.3.25), version solving failed.

  * Check your dependencies Python requirement: The Python requirement can be specified via the `python` or `markers` properties

    For langchain-text-splitters, a possible solution would be to set the `python` property to ">=3.12.4,<4.0"

    https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies,
    https://python-poetry.org/docs/dependency-specification/#using-environment-markers

似乎是抱怨要求的 Python 版本 >=3.12.4 與套件所需不符而無法安裝, 但上面 pyproject.toml 的預設設定是 requires-python = ">=3.12" 而非 requires-python = ">=3.12.4" 啊? 真奇怪. 我將上面訊息提交給 ChatGPT 解釋, 它的回答是 Poetry 可能在解析某些依賴時會依據目前執行 Python 版本與專案 requires-python 的交集去做更嚴格限制, 有時候會 "高估" 需求版本.

解決辦法是先將 pyproject.toml 中的 Python 版本改為 requires-python = ">=3.12.2,<4.0", 添加 <4.0 這個版本上限來形成一個範圍, 這樣 Poetry 就不會因為採取嚴格之版本判斷而不安裝 Python : 

[project]
name = "project1"
version = "0.1.0"
description = ""
authors = [
    {name = "Your Name",email = "you@example.com"}
]
readme = "README.md"
requires-python = ">=3.12.2,<4.0"   
dependencies = [
]

[tool.poetry]
packages = [{include = "project1", from = "src"}]


[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

然後利用檔案總管刪除虛擬環境目錄 .venv 與記錄完整的相依套件樹與版本的 poetry.lock 檔, 再次安裝 Python 虛擬環境就成功了 : 

D:\python\langchain\project1>poetry install  
Creating virtualenv project1 in D:\python\langchain\project1\.venv
Updating dependencies
Resolving dependencies... (1.1s)

接下來就可以安裝 LangChain 了 :

D:\python\langchain\project1>poetry add langchain    
Using version ^0.3.25 for langchain

Updating dependencies
Resolving dependencies... (4.8s)

Package operations: 29 installs, 0 updates, 0 removals

  - Installing certifi (2025.4.26)
  - Installing charset-normalizer (3.4.2)
  - Installing h11 (0.16.0)
  - Installing idna (3.10)
  - Installing sniffio (1.3.1)
  - Installing typing-extensions (4.13.2)
  - Installing urllib3 (2.4.0)
  - Installing annotated-types (0.7.0)
  - Installing anyio (4.9.0)
  - Installing httpcore (1.0.9)
  - Installing pydantic-core (2.33.2)
  - Installing requests (2.32.3)
  - Installing typing-inspection (0.4.0)
  - Installing httpx (0.28.1)
  - Installing jsonpointer (3.0.0)
  - Installing orjson (3.10.18)
  - Installing packaging (24.2)
  - Installing pydantic (2.11.4)
  - Installing requests-toolbelt (1.0.0)
  - Installing zstandard (0.23.0)
  - Installing jsonpatch (1.33)
  - Installing langsmith (0.3.42)
  - Installing pyyaml (6.0.2)
  - Installing tenacity (9.1.2)
  - Installing greenlet (3.2.1)
  - Installing langchain-core (0.3.58)
  - Installing langchain-text-splitters (0.3.8)
  - Installing sqlalchemy (2.0.40)
  - Installing langchain (0.3.25)

Writing lock file

Installing the current project: project1 (0.1.0)

這時開啟 pyproject.toml 就可以看到 dependencies 不再是空串列, 多了 langchain : 

[project]
name = "project1"
version = "0.1.0"
description = ""
authors = [
    {name = "Your Name",email = "you@example.com"}
]
readme = "README.md"
requires-python = ">=3.12.2,<4.0"
dependencies = [
    "langchain (>=0.3.25,<0.4.0)"
]

[tool.poetry]
packages = [{include = "project1", from = "src"}]


[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

然後就可以用 poetry shell 指令進入 shell 介面來管理虛擬環境, 但是卻出現下列訊息 :

D:\python\langchain\project1>poetry shell   

Looks like you're trying to use a Poetry command that is not available.

Since Poetry (2.0.0), the shell command is not installed by default. You can use,

  - the new env activate command (recommended); or
  - the shell plugin to install the shell command

Documentation: https://python-poetry.org/docs/managing-environments/#activating-the-environment

Note that the env activate command is not a direct replacement for shell command.

原來 Poetry 2.0.0 之後預設不再內建 poetry shell 指令, 須手動自行安裝 shell plugin, 指令如下 : 

poetry self add poetry-plugin-shell  

D:\python\langchain\project1>poetry self add poetry-plugin-shell    
Using version ^1.0.1 for poetry-plugin-shell

Updating dependencies
Resolving dependencies... (9.4s)

Package operations: 3 installs, 1 update, 0 removals

  - Installing ptyprocess (0.7.0)
  - Updating virtualenv (20.30.0 -> 20.31.1)
  - Installing pexpect (4.9.0)
  - Installing poetry-plugin-shell (1.0.1)

Writing lock file

重新輸入 poetry shell 指令即可進入虛擬環境的 Shell 介面了 : 

D:\python\langchain\project1>poetry shell 

我們可以在此虛擬環境用 poetry add 安裝 Python 套件, 執行 Python 程式等 :

(project1-py3.12) D:\python\langchain\project1>python --version  
Python 3.12.2

例如安裝最好用的專業級 Python Web 開發框架 streamlit : 

(project1-py3.12) D:\python\langchain\project1>poetry add streamlit    
Using version ^1.45.0 for streamlit

Updating dependencies
Resolving dependencies... (4.7s)

Package operations: 30 installs, 0 updates, 0 removals

  - Installing attrs (25.3.0)
  - Installing rpds-py (0.24.0)
  - Installing referencing (0.36.2)
  - Installing jsonschema-specifications (2025.4.1)
  - Installing markupsafe (3.0.2)
  - Installing six (1.17.0)
  - Installing smmap (5.0.2)
  - Installing colorama (0.4.6)
  - Installing gitdb (4.0.12)
  - Installing jinja2 (3.1.6)
  - Installing jsonschema (4.23.0)
  - Installing narwhals (1.38.0)
  - Installing numpy (2.2.5)
  - Installing python-dateutil (2.9.0.post0)
  - Installing pytz (2025.2)
  - Installing tzdata (2025.2)
  - Installing altair (5.5.0)
  - Installing blinker (1.9.0)
  - Installing cachetools (5.5.2)
  - Installing click (8.1.8)
  - Installing gitpython (3.1.44)
  - Installing pandas (2.2.3)
  - Installing pillow (11.2.1)
  - Installing protobuf (6.30.2)
  - Installing pyarrow (20.0.0)
  - Installing pydeck (0.9.1)
  - Installing toml (0.10.2)
  - Installing tornado (6.4.2)
  - Installing watchdog (6.0.0)
  - Installing streamlit (1.45.0)

Writing lock file

接下來安裝另一個常用的 Python Web 開發框架 gradio :

(project1-py3.12) D:\python\langchain\project1>poetry add gradio   
Using version ^5.29.0 for gradio

Updating dependencies
Resolving dependencies... (4.7s)

Package operations: 25 installs, 0 updates, 0 removals

  - Installing mdurl (0.1.2)
  - Installing filelock (3.18.0)
  - Installing fsspec (2025.3.2)
  - Installing markdown-it-py (3.0.0)
  - Installing pygments (2.19.1)
  - Installing tqdm (4.67.1)
  - Installing huggingface-hub (0.30.2)
  - Installing rich (14.0.0)
  - Installing shellingham (1.5.4)
  - Installing starlette (0.46.2)
  - Installing websockets (15.0.1)
  - Installing aiofiles (24.1.0)
  - Installing fastapi (0.115.12)
  - Installing ffmpy (0.5.0)
  - Installing gradio-client (1.10.0)
  - Installing groovy (0.1.2)
  - Installing pydub (0.25.1)
  - Installing python-multipart (0.0.20)
  - Installing ruff (0.11.8)
  - Installing safehttpx (0.1.6)
  - Installing semantic-version (2.10.0)
  - Installing tomlkit (0.13.2)
  - Installing typer (0.15.3)
  - Installing uvicorn (0.34.2)
  - Installing gradio (5.29.0)

Writing lock file

這時再次開啟專案設定檔 pyproject.toml 就可以看到 dependencies 串列內紀錄了已安裝的四個 Python 套件 : langchain, requests, streamlit, 與 gradio : 

dependencies = [
    "langchain (>=0.3.25,<0.4.0)",
    "requests (>=2.32.3,<3.0.0)",
    "streamlit (>=1.45.0,<2.0.0)",
    "gradio (>=5.29.0,<6.0.0)"
]

輸入 exit 即可離開虛擬環境 :

(project1-py3.12) D:\python\langchain\project1>exit   

D:\python\langchain\project1>

嗯, 實際動手做一遍發現 Poetry 真的蠻好用的, 安裝與管理套件的方式乾淨俐落, 也不用再面對版本互相干擾的問題了. 

2025年5月5日 星期一

Python 學習筆記 : 安裝套件與虛擬環境管理工具 Poetry

我最近在讀 "LangChain 奇幻旅程" 這本書時得知 poetry 這個管理套件與虛擬環境的工具, 它與傳統上使用 pip 管理套件安裝與使用 virtualenv 管理虛擬環境的做法相比, 有如下之優點 : 
  • Poetry 兼具套件管理與虛擬環境管理功能, 它使用單一的 project.toml 檔來管理專案配置與套件依賴, 取代傳統的 setup.py + requirements.txt 作法, 簡潔易讀且整合度高. 在專案中使用 Poetry 初始化與安裝套件時, 它會自動於專案目錄中建立一個虛擬環境. 
  • Poetry 會建立 poetry.lock 檔記錄完整的相依套件樹與版本, 可確保部署環境使用完全相同的套件版本.
  • Poetry 在安裝套件時可以用 --dev 參數使其安裝至開發環境而非生產環境, 從而達到區分主相依與開發相依的不同. 
  • Poetry 內建發佈工具可自動建置並發佈套件至 PyPI, 不用自行撰寫寫 setup.py, MANIFEST.in 等冗長檔案. 
  • 專案成員只需執行一個指令 poetry install 即可根據 pyproject.toml 與 poetry.lock 建立一致的開發環境, 降低環境配置錯誤機率.
注意, 電腦的系統 Python (全域) 版本必須是 3.8 版以上才可以安裝 Poetry, 但因 Python 3.8 已於 2024 年 10 月底 EOL, 故最好是在 Python 3.9+ 環境下安裝 Poetry. 

在 Windows 安裝 Poetry 可開啟命令提示字元視窗, 使用 curl 指令安裝 : 

curl -sSL https://install-python-poetry.org | python3 -   

或開啟 Powershell 視窗, 以下列命令安裝 :

(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -  

兩種方式都會將 Poetry 安裝到使用者資料夾下, 例如 :

C:\Users\<tony>\AppData\Roaming\Python\Scripts

今天在我的 MSI 電競筆電上開啟 PowerShaell 視窗安裝 Poetry : 

Windows PowerShell
著作權(C) Microsoft Corporation。保留擁有權利。
                                                                                                                        
安裝最新的 PowerShell 以取得新功能和改進功能!https://aka.ms/PSWindows   

PS C:\Users\USER> (Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -        
Retrieving Poetry metadata

# Welcome to Poetry!

This will download and install the latest version of Poetry,
a dependency and package manager for Python.

It will add the `poetry` command to Poetry's bin directory, located at:

C:\Users\USER\AppData\Roaming\Python\Scripts

You can uninstall at any time by executing this script with the --uninstall option,
and these changes will be reverted.

Installing Poetry (2.1.3)
Installing Poetry (2.1.3): Creating environment
Installing Poetry (2.1.3): Installing Poetry
Installing Poetry (2.1.3): Creating script
Installing Poetry (2.1.3): Done

Poetry (2.1.3) is installed now. Great!

To get started you need Poetry's bin directory (C:\Users\USER\AppData\Roaming\Python\Scripts) in your `PATH`
environment variable.

You can choose and execute one of the following commands in PowerShell:

A. Append the bin directory to your user environment variable `PATH`:

```
[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";C:\Users\USER\AppData\Roaming\Python\Scripts", "User")
```

B. Try to append the bin directory to PATH every when you run PowerShell (>=6 recommended):

```
echo 'if (-not (Get-Command poetry -ErrorAction Ignore)) { $env:Path += ";C:\Users\USER\AppData\Roaming\Python\Scripts" }' | Out-File -Append $PROFILE
```

Alternatively, you can call Poetry explicitly with `C:\Users\USER\AppData\Roaming\Python\Scripts\poetry`.

You can test that everything is set up by executing:

`poetry --version`

這樣就安裝完畢了, 檢視版本 :

PS C:\Users\USER> poetry --version   
poetry : 無法辨識 'poetry' 詞彙是否為 Cmdlet、函數、指令檔或可執行程式的名稱。請檢查名稱拼字是否正確,如果包含路徑的話
,請確認路徑是否正確,然後再試一次。
位於 線路:1 字元:1
+ poetry --version
+ ~~~~~~
    + CategoryInfo          : ObjectNotFound: (poetry:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

這表示系統的 PATH 環境變數沒有包含 Poetry 的安裝路徑, 先用下面指令檢查 Poetry 有沒有安裝成功 :

PS C:\Users\USER> dir $env:APPDATA\Python\Scripts\poetry.exe   

    目錄: C:\Users\USER\AppData\Roaming\Python\Scripts


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2025/5/5  下午 10:03         108423 poetry.exe 

這樣就確定安裝成功, 只是沒把 Poetry 所在路徑設定在 PATH 環境變數裡而已. 在 Win11 設定環境變數的方法之一是按 Windows + R, 在彈出視窗中輸入 sysdm.cpl 按 "確定" : 




切到 "進階" 頁籤, 按最底下的 "環境變數" 鈕 :  




點選上方 "使用者變數" 中的 Path 按 "編輯" : 





按 "新增" 鈕 :




在新增的列中輸入 Poetry 的安裝路徑 (此處是 C:\Users\USER\AppData\Roaming\Python\Scripts) 後按底下的 "確定" 鈕 :  




然後一路按確定結束環境變數編輯作業, 關掉 PowerShell 視窗, 重新開啟後再次檢視 Poetry 版本就不會再出現錯誤了 :

PS C:\Users\USER> poetry --version   
Poetry (version 2.1.3)

Poetry 常用指令可以區分為專案管理, 依賴管理, 虛擬環境, 發行封裝, 與其他等五類. 


 專案管理指令  說明
 poetry new <專案名稱>  建立新專案(含預設目錄結構)
 poetry init  建立 pyproject.toml(互動式設定)
 poetry config --list  查看 Poetry 設定(含虛擬環境位置)


 依賴管理指令  說明
 poetry add <套件>  安裝套件並加入 pyproject.toml
 poetry add <套件> --dev  安裝開發用套件(只在開發階段用)
 poetry remove <套件>  移除套件
 poetry update  更新所有套件至相容最新版本
 poetry lock  重新產生 poetry.lock


 虛擬環境指令  說明
 poetry install  安裝 pyproject.toml 裡的所有套件(建立虛擬環境)
 poetry shell  進入虛擬環境的互動式 shell
 poetry run <指令>  在虛擬環境中執行指令,例如 poetry run python
 poetry env info  顯示虛擬環境詳細資訊
 poetry env list  列出所有 Poetry 建立的虛擬環境
 poetry env use <Python 路徑>  切換虛擬環境使用的 Python 版本


 發行封裝指令  說明
 poetry build  產生專案的 wheel 與 source tarball 封裝檔
 poetry publish  將封裝後的檔案發佈到 PyPI(需先設定 Token)
 poetry publish --dry-run  模擬發佈流程,不實際上傳
 poetry version <版本>  設定新版本(例如:poetry version patch


 其他實用指令  說明
 poetry --version  顯示 Poetry 的版本
 poetry about  顯示關於 Poetry 的資訊
 poetry config  設定 Poetry(例如:虛擬環境路徑、自動建立環境等)
 poetry debug info  顯示除錯資訊,例如環境、依賴等
 poetry self update  更新 Poetry 本身
 poetry self remove  移除 Poetry 本身


檢視 Poetry 設定 :

PS C:\Users\USER> poetry config --list   
cache-dir = "C:\\Users\\USER\\AppData\\Local\\pypoetry\\Cache"
data-dir = "C:\\Users\\USER\\AppData\\Roaming\\pypoetry"
installer.max-workers = null
installer.no-binary = null
installer.only-binary = null
installer.parallel = true
installer.re-resolve = true
keyring.enabled = true
python.installation-dir = "{data-dir}\\python"  # C:\Users\USER\AppData\Roaming\pypoetry\python
requests.max-retries = 0
solver.lazy-wheel = true
system-git-client = false
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = "{cache-dir}\\virtualenvs"  # C:\Users\USER\AppData\Local\pypoetry\Cache\virtualenvs
virtualenvs.prompt = "{project_name}-py{python_version}"
virtualenvs.use-poetry-python = false

其中關於虛擬環境的設定 virtualenvs.in-project = null 表示預設沒有啟動再專案中使用虛擬環境, 但 Python 專案高度依賴虛擬環境以避免套件版本衝突問題, 因此要用下列指令將其修改為 true (啟動) : 

poetry config virtualenvs.in-project true

PS C:\Users\USER> poetry config virtualenvs.in-project true   

再次檢視 Poetry 設定 : 

PS C:\Users\USER> poetry config --list   
cache-dir = "C:\\Users\\USER\\AppData\\Local\\pypoetry\\Cache"
data-dir = "C:\\Users\\USER\\AppData\\Roaming\\pypoetry"
installer.max-workers = null
installer.no-binary = null
installer.only-binary = null
installer.parallel = true
installer.re-resolve = true
keyring.enabled = true
python.installation-dir = "{data-dir}\\python"  # C:\Users\USER\AppData\Roaming\pypoetry\python
requests.max-retries = 0
solver.lazy-wheel = true
system-git-client = false
virtualenvs.create = true
virtualenvs.in-project = true
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = "{cache-dir}\\virtualenvs"  # C:\Users\USER\AppData\Local\pypoetry\Cache\virtualenvs
virtualenvs.prompt = "{project_name}-py{python_version}"
virtualenvs.use-poetry-python = false

這樣專案內的虛擬環境就設定好了. 

市圖還書 3 本 (紫微攻略, 耕股, 征服臉書)

因為沒注意到爬蟲傳送的提醒訊息, 下面三本書因為逾期必須還 :
No.3 紫微攻略這本很不錯, 等懲罰期 4 天過了再回借.