簡単にテクニカル分析を行うことができるTA-Lib
をPythonで使うためには、
TA-Lib
本体をインストール(brew install ta-lib
)TA-Lib
のPython用ラッパーをインストール(pip install TA-Lib
)
という手順を行う必要がある。
元々Pythonは環境構築が面倒な上に、Homebrewによってインストールされたものに依存してしまうのでDockerで全て環境構築をしてしまおうという話。
結論だけを知りたい場合は、結論の項目に必要なファイルとその内容を記載している。
注意点
- Dockerの環境構築については割愛する
pipenv
を使った環境構築を行っているが、pip
でも十分(むしろ楽)である
Python用のDockerイメージを検索する
Pythonが使えるDockerイメージをdocker search
コマンドを使って検索する。
もちろん、Docker Hubを使って検索しても良い。
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
python Python is an interpreted, interactive, objec… 5754 [OK]
django Django is a free web application framework, … 1038 [OK]
pypy PyPy is a fast, compliant alternative implem… 260 [OK]
nikolaik/python-nodejs Python with Node.js 57 [OK]
joyzoursky/python-chromedriver Python with Chromedriver, for running automa… 56 [OK]
このようにDocker Hubに公開されているPythonに関係あるイメージを取得することができる。
STARS | ユーザーからのお気に入りの件数 |
OFFICIAL | 公式イメージかどうか |
AUTOMATED | Dockerfileを元に自動生成されたイメージかどうか |
Docker Hubで公開されているイメージは全て安全なものとは限らないので、
公式イメージかDockerfileがきちんと公開されているものを利用するのがよい。
今回は、python
イメージを利用する。
利用するタグは3.8
とする。
Dockerfileを作成する
ここからはDockerの使い方を学びつつ進める。
Dockerfileの基本書式
Dockerfileは
命令 引数
というシンプルな書式で記述される。
よく利用する命令は以下の通り。
FROM | ベースイメージの指定 |
RUN | コマンド実行(イメージを作成するために実行するコマンド) |
CMD | コンテナの実行コマンド(イメージを元に生成されたコンテナ内で実行するコマンド) |
ENV | 環境変数 |
また、Dockerfileにはシェルスクリプトの知識が多少必要になるので、覚えておくと良い。
ベースイメージのみで作成してみる
Pythonのベースイメージのみを指定し、Dockerイメージを作成し、起動する。
「Dockerfile」という名前のファイルを作成し、下記のように記載する。
Dockerfile
# Python3.8をベースイメージにする
# FROM イメージ名:タグ名
FROM python:3.8
DockerfileからDockerイメージを作成する。
# 「docker build -t 生成するイメージ名:タグ名 Dockerfileの場所」の形式で記載
$ ls
Dockerfile
$ docker build -t python-sample:1.0 .
Sending build context to Docker daemon 184.3kB
Step 1/1 : FROM python:3.8
3.8: Pulling from library/python
6c33745f49b4: Pull complete
ef072fc32a84: Pull complete
c0afb8e68e0b: Pull complete
d599c07d28e6: Pull complete
f2ecc74db11a: Pull complete
26856d31ce86: Pull complete
2cd68d824f12: Pull complete
7ea1535f18c3: Pull complete
2bef93d9a76e: Pull complete
Digest: sha256:9079aa8582543494225d2b3a28fce526d9a6b06eb06ce2bac3eeee592fcfc49e
Status: Downloaded newer image for python:3.8
---> f5041c8ae6b1
Successfully built f5041c8ae6b1
Successfully tagged python-sample:1.0
初回はpython:3.8
イメージをダウンロードする所から始まることがわかる。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
python-sample 1.0 f5041c8ae6b1 6 days ago 884MB
python 3.8 f5041c8ae6b1 6 days ago 884MB
docker image ls
でイメージの一覧を確認でき、
- Docker Hubからダウンロードされた「python」イメージ
- 「python」イメージをベースイメージとして、今作った「python-sample」イメージ
が存在することがわかる。
また、今作った「python-sample」イメージの中身は「python」イメージと全く同一のため、
イメージIDが一致していることが確認できる。
ホストマシンのディレクトリを共有する
Pythonを利用する時、
- ホストマシンにあるPythonのソースコードを読み込みたい
- コンテナが消えても、プログラムによって出力されたファイルが消えないようにしたい
という要求が自然と発生する。
これを実現するためにはホストマシンのディレクトリをDockerコンテナと共有(マウント)する必要がある。
まずは下記のようなディレクトリ構成にする。hello.py
には「hello, world」を出力するPythonのスクリプトが記述されている。
この時のsrc/
ディレクトリごとDockerコンテナに共有していく。
$ tree .
.
├── Dockerfile
├── README.md
└── src
└── hello.py
1 directories, 3 files
次にDockerfileを下記のように書き換え、src/
ディレクトリ配下のファイルが読み込まれていることを確認できるようにする。
# Python 3.8をベースイメージとする
FROM python:3.8
WORKDIR /workspace
# ディレクトリを表示し、Pythonファイルを実行する
CMD ls -la \
&& python hello.py
実際にディレクトリをマウントする時、docker container run
コマンドの--mount
オプションを利用する。
(--volume
オプションでも同様のことが可能だが、ここでは違いなどは割愛する)
実行結果
# まずはDockerイメージを「python-sample」という名前でビルドする
$ docker build -t python-sample:1.0 .
# Dockerイメージから、実際にコンテナを起動する
# --name "python-container":起動するコンテナ名を「python-container」とする
# --mountオプションで利用する「source」には、ホストマシンの共有したいディレクトリを指定
# --mountオプションで利用する「target」には、対応するDockerコンテナのディレクトリを指定する
$ docker container run -it --name "python-container" --mount type=bind,source="$(pwd)"/src,target=/workspace python-sample:1.0
total 8
drwxr-xr-x 3 root root 96 Dec 29 05:35 .
drwxr-xr-x 1 root root 4096 Dec 29 14:21 ..
-rw-r--r-- 1 root root 24 Dec 29 05:34 hello.py
hello, world.
コンテナ起動の実行結果を確認すると、ls -la
コマンドの実行結果とpython hello.py
の実行結果が表示されていることがわかる。
必要なモジュールをインストールする記述を追加する
Pythonで利用するモジュールをインストールするコマンドを追加する。
また、ここではpipenv
を使ってモジュール管理をすることを想定する。
- TA-Libのインストールに必要なコマンドをインストールする
- TA-Libのインストールを行う
- pipenvコマンドをインストールする
# 必要なコマンドのインストールを行う
RUN apt-get -y update && apt-get install -y wget vim git curl make sudo
# TA-Libのインストールを行う
RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \
tar -xzf ta-lib-0.4.0-src.tar.gz && \
cd ta-lib/ && \
./configure --prefix=/usr && \
make && \
sudo make install
# pipenvを使えるようにする
RUN pip install pipenv
TA-Libのインストール方法は下記のLinux用インストール方法を参考にする。
PipfileにはTA-Libを使えるように
TA-Libを利用するように記述されたPipfileを用意する。
pipenv install TA-Lib
でインストールしながら作成しても良い。
Pipfile
// (省略)
[packages]
ta-lib = "*"
[requires]
python_version = "3.8"
// (省略)
Dockerfileにてモジュールの初期インストールと実行コマンドを記載する
- pipenvで使うモジュールの初期インストール(
pipenv install
) - main.pyの実行用スクリプト(自分で適当に決めてOK)を実行
Dockerfile
# (省略)
# pipenvを使えるようにする
RUN pip install pipenv
# 作業ディレクトリを決める
WORKDIR /workspace
# ディレクトリを表示し、Pythonファイルを実行する
CMD pipenv install && \
pipenv run dev
main.pyの実行用スクリプトはもちろんPipfileに記載しておく必要がある。
Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[packages]
ta-lib = "*"
[requires]
python_version = "3.8"
[scripts]
dev = "python main.py"
結論
ディレクトリ構成
$ tree .
.
├── Dockerfile
├── README.md
└── src
├── Pipfile
├── Pipfile.lock
└── main.py
1 directories, 5 files
./Dockerfile
# Python 3.8をベースイメージとする
FROM python:3.8
# 必要なコマンドのインストールを行う
RUN apt-get -y update && apt-get install -y wget vim git curl make sudo
# TA-Libのインストールを行う
RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \
tar -xzf ta-lib-0.4.0-src.tar.gz && \
cd ta-lib/ && \
./configure --prefix=/usr && \
make && \
sudo make install
# pipenvを使えるようにする
RUN pip install pipenv
WORKDIR /workspace
# ディレクトリを表示し、Pythonファイルを実行する
CMD pipenv install && \
pipenv run dev
./src/Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[packages]
ta-lib = "*"
[requires]
python_version = "3.8"
[scripts]
dev = "python main.py"
./src/main.py
import talib as ta
def main():
print(ta.get_function_groups)
if __name__ == '__main__':
main()
実行結果
$ docker build -t python-sample:1.0 .
# イメージビルド時のログが出力される(省略
Successfully built a55d1417182f
Successfully tagged python-sample:1.0
$ docker container run -it --name "python-container" --mount type=bind,source="$(pwd)"/src,target=/workspace python-sample:1.0
Creating a virtualenv for this project...
Pipfile: /workspace/Pipfile
Using /usr/local/bin/python3.8 (3.8.7) to create virtualenv...
⠏ Creating virtual environment...created virtual environment CPython3.8.7.final.0-64 in 592ms
creator CPython3Posix(dest=/root/.local/share/virtualenvs/workspace-dqq3IVyd, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/root/.local/share/virtualenv)
added seed packages: pip==20.3.1, setuptools==51.0.0, wheel==0.36.1
activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
✔ Successfully created virtual environment!
Virtualenv location: /root/.local/share/virtualenvs/workspace-dqq3IVyd
Installing dependencies from Pipfile.lock (7fbe10)...
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 18/18 — 00:00:27
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
<function get_function_groups at 0x7f715b0b2a60>
まとめ
- ベースイメージにはPythonのイメージを利用する
- TA-LibはLinuxへのインストール方法を参考にDockerfileにスクリプトを記載する
- pipもしくはpipenvの初期設定とPythonスクリプト実行の記載をする
- Dockerイメージをビルドする
- コンテナ起動時に任意のディレクトリをマウントしながら起動する
補足
- モジュールの初期インストール(
pipenv install
)のタイミングを工夫するともう少し効率的になる - Dockerイメージの作成とコンテナの起動コマンドは長いので、シェルスクリプトでまとめるともう少しスマートになる
- 私は
pipenv
が好きなのでpipenv
を使ったが、普通にpip
使っても良い(むしろそっちの方が良いかも) - 全体を通した実行速度を考えると、普通にTA-Libインストールして
pipenv
使った方が速い