事象
PyScript (2024.10.1)上でopenai
パッケージを使おうとすると、次のようなエラーが出て失敗します:
ValueError: Can't find a pure Python 3 wheel for: 'jiter<1, >=0.4.0'
原因
openai
パッケージはjiter
パッケージに依存しているのですが、このパッケージがPure Pythonではない(Rustで書かれている)ため、PyScript / Pyodideで使用できるパッケージに含まれていません。この問題はopenai
パッケージのgithubでissueとして挙げられているのですが、2024年10月時点では解決していません。
解決方法
自力でjiter
パッケージのwheelを作成し、これをローカルにおいてPyScriptからロードさせます。
以下のDockerfileをDOCKER_BUILDKIT=1 docker build --file Dockerfile --output out .
等で走らせると、Pyscriptで使えるwheelが出力されます。注意点として、Pyodideのコンパイルに使用されたものと同じバージョンのPythonとEmscriptenを使う必要がありますので、ご自身が用いたいバージョンに応じて変更してください。
# wasm32 compiler of jiter-python
# For PyScript 2024.10.1 - Required Pyodide 0.26.3,Python 3.12 and Emscripten 3.1.58
# USAGE: DOCKER_BUILDKIT=1 docker build --file Dockerfile --output out .
FROM python:3.12 AS builder
# Install pyodide-build
RUN pip install pyodide-build==0.26.3
# Install Latest Rust using rustup
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal
ENV PATH $PATH:/root/.cargo/bin
# Add Rust WASM target (Nightly version is required for wasm32-unknown-emscripten)
RUN rustup toolchain install nightly
RUN rustup target add --toolchain nightly wasm32-unknown-emscripten
# Install Emscripten
RUN git clone https://github.com/emscripten-core/emsdk.git
WORKDIR /emsdk
RUN ./emsdk install 3.1.58
RUN ./emsdk activate 3.1.58
# ./emsdk_env.sh (Fails when use emsdk_env.sh directly)
ENV PATH $PATH:/emsdk:/emsdk/upstream/emscripten:/emsdk/node/20.18.0_64bit/bin
ENV EMSDK /emsdk
ENV EMSDK_NODE /emsdk/node/20.18.0_64bit/bin/node
WORKDIR /
# Set environment variables for Emscripten
ENV PYO3_CROSS_PYTHON_VERSION 3.12
ENV PYO3_CROSS_LIB_DIR /usr/local/lib
# Get jiter
RUN git clone --depth 1 https://github.com/pydantic/jiter.git
# Build
WORKDIR /jiter/crates/jiter-python
RUN pyodide venv .venv-pyodide
RUN . .venv-pyodide/bin/activate \
&& RUSTUP_TOOLCHAIN=nightly pyodide build
# Export
FROM scratch AS export-stage
COPY --from=builder /jiter/crates/jiter-python/dist .
pyscript.tomlへの記述方法
完成したwheelをPyScriptを用いたWebアプリと同じフォルダ以下に置きます。wheelの名前には意味があるので、名前を変更してはいけません。
例えば./packages/
に置いた場合、以下のように記述するとopenai
が使えるようになります。
packages = [
"ssl",
"./packages/jiter-0.7.0-cp312-cp312-pyodide_2024_0_wasm32.whl",
"openai"
]
注意事項
PyScriptやPyodideでOpenAI APIを用いる場合、API Keyをユーザから隠すことができないので、API Keyを窃取される可能性が高いです。Sharepoint環境に置く場合のように、アクセス権限を信頼できるユーザに限定できる場合に限って使用することをお勧めします。
参考文献
以下は途中経過で参考にしましたが、jiter
のケースではうまくいきませんでした。
- https://zenn.dev/termoshtt/articles/rust-wasm-wheel-maturin
- https://qiita.com/grafi/items/de804ebff4f50f28577b
- https://blog.pyodide.org/posts/rust-pyo3-support-in-pyodide/
類似のケースで、openai
のバージョンをjiter
に依存しない1.39.0まで下げて解決した事例もありました。