Morikatron Engineer Blog

モリカトロン開発者ブログ

Docker + VSCode(Remote Container)でSphinx環境を作り、構造化されたドキュメントを快適に書く

こんにちは。モリカトロンでエンジニアをしている馬淵です。

最近Sphinxというドキュメント作成ツールに関して書かれた下の書籍に興味を持ち、衝動買いしてしまいました。

www.oreilly.co.jp

こちらの書籍を読み進める際に環境を用意したのですが、自分なりに工夫を行ったのでこれを共有、メモを兼ねて今回はブログを書こうと思います。

基本的にVSCodeやDockerを既にインストールしている方、または複数人でドキュメントを編集する作業を行う方が対象となります。

Sphinxとは

SphinxはreStructuredTextと呼ばれるマークアップ言語を採用したドキュメント作成ツールです。もともとPythonの公式ドキュメントを作成するために開発されました。最終的にHTMLやEPUB、TexLive環境を追加することでPDFにも変換することができるため、Webサイトや技術ドキュメント、電子書籍の執筆等に利用されています。Pythonの公式ドキュメントSphinxの公式ドキュメントもSphinxを利用して書かれています。

Sphinxで書かれたWebサイトを見ると分かりやすいですが、Sphinxは構造化された文書を書くことに長けています。また、変換元となる文書を分割することも可能なので分量が多くなるような文書を作成することにも優れています。

何故DockerとVSCodeで環境を作ったか

Sphinxを利用するためにはPythonが必要となります。ここからさらにpipコマンドを利用して、Sphinxや画像処理ライブラリを入れ、テーマを変化させたければ必要に応じてインストールし、PDFに変換したいのであればさらにTexLiveを入れて...となると手元の環境が大きく汚れることになります。仮想環境を利用することも出来ますが、ドキュメントを作成するために仮想環境を作成するのは腰が重い……となりました。

自分は普段、Githubにあるコードをお試しで動かしてみたいと思ったときはDockerを利用して環境構築を行い、不要になれば廃棄、本格的に利用する場合は仮想環境を作成するという手段をとっています。また、プログラムを編集する際にはVisual Studio Code(以下VSCode)を利用していますが、VSCodeには「Remote Container」というDockerを利用しやすくする拡張機能や、reStructuredTextを書きやすくするためのための拡張機能が開発されています。

そこでDockerを利用して手軽にSphinx環境を作成したり廃棄出来れば気楽であり、VSCodeと連携させれば拡張機能などが編集の手助けしてくれるため、快適な環境が作成できると考えました。また、前述のようにSphinxは分量が多いドキュメントを作成することに優れていますが、複数人でドキュメントを作成する際にも、Dockerで構築することで環境を揃えやすいといった恩恵が受けられます。

事前準備

以下のツールをあらかじめインストールして利用できるようにしてください。

  • Docker
  • VSCode

Dockerに関してはWindowsの場合、WSL2を有効化するといった作業が必要になりますが、それらの説明は省略します。

また、VSCodeをインストール後は以下の手順を踏み、Remote Containersの拡張機能をインストールしておいてください。

  1. VSCodeを開く
  2. 拡張機能の検索画面(Ctrl + Shift + X)を開いて、「Remote Containers」で検索
  3. 下画像のRemote Containersをインストール

設定ファイルを書く

Remote Containerを利用するためにDocker関連の設定ファイルを書く必要があります。今回は最終的に以下のようなディレクトリ構成になりました。

/
├.devcontainer/
│ ├Dockerfile
│ └devcontainer.json
└requirements.txt

とりあえず動かしてみたい方はこちらまで飛ばしていただいても大丈夫です。

Dockerfile

コンテナを作成するためのDockerfileは以下のようになっています。

FROM python:3

# RUN apt-get update \
#     && apt-get install -y texlive-latex-extra \
#     latexmk \
#     texlive-lang-japanese

RUN mkdir /code
WORKDIR /code
COPY ../requirements.txt /code/
RUN pip install -r requirements.txt

ベースイメージとしてpython3を利用し、pip install -r requirements.txtで必要なpythonモジュールをインストールする形となっています。

コメントアウトした部分はTexLiveの部分となっており、PDFに変換する必要がなければコメントアウトしたままで大丈夫です。

requirements.txt

コンテナ内でSphinxやreStructuredText用のLinter,言語サーバーを導入するためにrequirements.txtを書いていきます。 今回は以下のようにしました。

Pillow
sphinx
esbonio
rstcheck

docs.restructuredtext.net

上のリンクを参考に必要なモジュールを入れています。 Pillow及びsphinxがSphinxを利用するために必要なモジュールとなっています。esbonioはreStructuredText用の言語サーバー、rstcheckはLinterとなっています。 rstcheckの代わりにdoc8を選択することも可能です。

devcontainer.json

最後にdevcontainer.jsonを書きます。ここではコンテナ内で利用する拡張機能や、コンテナ内でのVSCodeの設定を書いていきます。

{
    "name": "Sphinx",
    "context": "..",
    "dockerFile": "Dockerfile",
    // Set *default* container specific settings.json values on container create.
    "settings": {
        "python.pythonPath": "/usr/local/bin/python",
        "esbonio.server.enabled": true,
        "restructuredtext.linter.rstcheck.executablePath": "/usr/local/bin/rstcheck",
        "editor.bracketPairColorization.enabled": true,
        "esbonio.sphinx.confDir": ""
    },
    "extensions": [
        "lextudio.restructuredtext-pack"
    ]
}

ここでは、Pythonやesbonio向けのパスを設定しています。

また、extensionsキーの値に拡張機能のIDを書くことでコンテナに入った際に拡張機能がインストールされます。 今回は以下のreStructuredText用に開発された拡張機能群を導入しています。

VSCodeで実際に動かしてみる

ここまで作成したものをこちらのGithubに置いておきました。

ここからは実際にVSCodeでコンテナを起動して、Sphinxで文書を作れるか確認してみます。 Gitでクローンを行い、該当のフォルダをVSCodeで開いておいてください。

Remote Containerをインストールしていた場合、VSCodeのウィンドウの左下が下画像のようになっていると思います。

こちらの緑色の部分をクリックするとコマンドパレットが開くので[Reopen in Container]を選択してください。

するとRemote Containerが./devcontainer下のDockerfileを読み込んてコンテナをビルドから立ち上げまで行ってくれます。

これでコンテナ内にVSCodeで入ることが出来たと思うので、実際にSphinxを利用して文書を書きHTMLに変換してみましょう。 コンテナに入ったVSCode内でターミナルを立ち上げて以下のコマンドを打ちます。

sphinx-quickstart

続いてプロジェクトに必要な質問をされるので適当に答えていけば、index.rstというファイルが生成されていると思うのでこれをVSCodeで編集してみると

このようにreStructuredTextの文法が間違っていればLinterがチェック、記法の候補を表示してくれます。 また、Ctrl + Shift + Rでプレビューを見ることも可能です。

初めてコンテナを立ち上げた際の編集時にはエンターやバックスペースを押した際、まれに

  • command 'restructuredtext.editor.listEditing.onEnterKey' not found
  • command 'restructuredtext.editor.listEditing.onBackspaceKey' not found

といったエラーが発生することがありますが、これはVSCode側のバグで拡張機能の読み込みが出来ていないことが原因のようです。 その際には一度

  • VSCodeをリスタートする
  • Dockerコンテナを閉じて再度開く
  • しばらく放置してみる

などの操作を行うことで直ると思います。また、

make html

と打てばHTMLに変換できます。

Dockerコンテナで環境が出来ているので、ここから好きなモジュールを入れたり、テーマを変更することも可能ですし、 不要となったらDockerコマンドで気楽に廃棄して作り直すことが可能です。

これでSphinxを書く環境が整いました。

juliaをコンパイルして実行可能ファイルを作る

こんにちは、モリカトロン株式会社・AIエンジニアの舒(ジョ)と申します。

最近、社内の研究で経路探索のアルゴリズムを実装していたのですが、Pythonで実装すると非常に遅かったので、Pythonに似ているけどより高速に 処理できそうな「Julia」というプログラミング言語を使って実装しなおすことがありました。

ということで今回は最近使い始めた「Julia」を紹介します。

以下の内容は Windows 環境を想定しています。

Juliaとは

Julia は、高度な計算や数値解析のために開発されたプログラミング言語で、マサチューセッツ工科大学の研究者 Jeff Bezanson らによって2009年に開発され、2012年にオープンソース化されました。
開発者によると、C言語の速さやR言語の統計の扱いやすさ、Perlの自然な文字列処理、Matlabの線形代数など他の言語のいいところだけを組み合わせることを目指した言語だそうです。

julialang.org

Python との大きな違いはプログラムを JIT コンパイルするところで、これにより Python よりも高速な処理に期待できます。

Juliaのインストール

下記の公式サイトにアクセスしてJuliaのインストーラーをダウンロードできます。 自分が使っているVersionはVersion 1.6.5です。

julialang.org

インストール後、インストールしたフォルダのパスなどを環境変数に設定して下さい。 (例)

 JULIA_PATH="C:(Juliaインストールフォルダ)"
 PATH=%JULIA_PATH%\bin;%PATH%

JuliaのショートカットをダブルクリックしてJuliaを起動します。

以下のようにJuliaのプロンプト画面が起動しますので、ここにコマンドを入力して処理を実行させます。

VS Code上で開発環境を整える

コマンドプロンプトで直接処理を記述するだけというのは扱いづらいので、VSCodeを使った開発環境も構築しました。

Julia拡張を導入する

  1. VS CodeでJuliaを扱うための拡張機能をインストール
  2. VS Code内、左のバーから拡張機能をクリックし、「Julia」で検索を行うと、画像のような拡張機能が見つかるので、こちらをインストール
  3. 設定ページ内にExexutable Pathという項目があるので、こちらに先ほどインストールしたJuliaのpathを設定
  4. VS Code上で Test.jl を開いた状態で Shift+Enter を押す( VS Code上でREPLというJuliaのコマンドラインが現れ、実行結果が表示されます。)

パッケージの導入方法

JuliaにはPythonにおけるpipのようなパッケージ管理の機能が用意されています。 Juliaでプログラミングする際にはほぼ必須の機能なのでこれについても軽く紹介しておきます。

  1. Juliaを起動
  2. using Pkg」と入力して、Pkgツールを呼び出す
  3. kg.add("package")」のように入力して指定のパッケージをインストール

パラメータ 詳細
Pkg.add( package ) 指定された登録パッケージをダウンロードしてインストールします。
Pkg.checkout( package branch ) 指定された登録済みパッケージのブランチを調べてください。 branchはオプションで、デフォルトは"master"です。
Pkg.clone( url ) 指定されたURLのGitリポジトリをパッケージとしてパッケージ化します。
Pkg.dir( package ) 指定されたパッケージのディスク上の場所を取得します。
Pkg.pin( package version ) 指定したバージョンにパッケージを残します。 versionはオプションで、デフォルトはパッケージの現在のバージョンです。
Pkg.rm( package ) 指定されたパッケージを必要なパッケージのリストから削除します。

PythonとJuliaの連携

PythonではなくJuliaで記述する方が処理が高速になる可能性が高いですが、プログラムのすべてをPythonからJuliaに置き換えるというのは非常に大変な作業になってしまいます。 今まで書いたコードは出来るだけそのまま使い、高速に処理する必要がある部分だけJuliaで記述できる方がありがたいです。

このような場合、pyjuliaというPythonモジュールを使う事で簡単にPythonとJuliaの連携を行うことが可能です。

PythonからJuliaのコードを呼び出すモジュールがpyjuliaで、JuliaからPythonを呼び出すJuliaPyというパッケージもあります。

github.com

事前処理

  1. pip install julia でPyJuliaをインストール

     pip install julia   
    
  2. Python 上で下記コマンドを実行

     import julia  
     julia.install()  
    

PythonからJuliaを呼び出す

  1. 呼び出すJuliaのプログラムを用意 (ファイル名は Test.jl )

     function test_function(text)  
         println(text)  
     end  
    
  2. Python側プログラムでJuliaのプログラムをインクルードして実行

     from julia import Main as jl  
     jl.include("Test.jl")  
     jl.test_function("hello world!")  
     jl.close  
    

このプログラムの実行結果は以下のようになります。

julia> "hello world!"

注意点

マルチスレッドとの相性が悪い

pyjuliaはスレッドセーフではないため、複数のスレッドで使用することが出来ません。

github.com

pyinstallerでビルドすることができない

pyinstallerを利用してPythonプログラムを配布しようとする場合にpyjuliaは利用できないようです。
このような場合にはjuliaファイルを別途コンパイルしておき、それをPythonから呼び出すようにする必要があります。

stackoverflow.com

Juliaのソースコードをコンパイルする

先ほど少し書きましたが、Pythonのプログラムを配布したい場合にpyinstallerを使う場合があります。 そういった場合に必要になるJuliaのソースコードのコンパイル方法も紹介しておきます。

github.com

Juliaのプログラムを準備

事前に、コンパイルしたいJuliaのプログラムを用意しておきます。 (ファイル名は Test.jl とします)

function test_function(text)
   println(text)
end
test_function("hellow world!")

PackageCompilerインストール

次にコンパイラ「PackageCompiler」をインストールします。

  1. Juliaを起動
  2. using Pkg と入力して、Pkgツールの呼び出す
  3. Pkg.add("PackageCompiler") と入力して、PackageCompilerをインストール

Juliaのソースコードをコンパイルする

  1. Juliaを起動
  2. pwd()関数を使用して、作業ディレクトリを確認

    作業ディレクトリを変更したい場合は cd()関数を使用してディレクトリを変更してください julia> cd("path") # 作業ディレクトリを変更できます

  3. パッケージ化されたファイルのサイズを減らすために、独立した環境を作成

    • 上記命令を実行すると、作業ディレクトリに「 Hello 」フォルダが生成されます。
  4. キーボードの「 ] 」キーを押して、Pkgツールに入ります。
  5. 環境を先ほど作成した「 Hello 」に切り替えます。
  6. Pkgの状態で、必要な外部パッケージを「 Hello 」環境に追加します。
  7. 作業ディレクトリ\Hello\ 以下にある「 Project.toml 」を開き、コンパイル情報を編集
  8. 作業ディレクトリ\Hello\src\ 以下にある「 Hello.jl 」に、最初に作成した「 Test.jl 」の内容をコピーしてビルド用ファイルを準備

    ここでは元のすべてのコードを1つの関数の内部に置く必要があります。

  9. Juliaのプロンプト画面に以下のコードを入力してビルドを実行

     create_app("pkg_ob_name", "path_name")
    

  10. 作業ディレクトリ\Hello_build\src\bin\Hello.exe」が生成されるので、実行を確認

参考

https://qiita.com/syoyo/items/5b8639b206b232984ffa https://github.com/JuliaPy/pyjulia https://qiita.com/ttabata/items/b05bb43d06239f968035 https://qiita.com/ttabata/items/3afc8cef40d1e98a7b17 https://qiita.com/SatoshiTerasaki/items/9d775c294a10c1f2edfe https://www.youtube.com/watch?v=jjJ2xHpxwHg https://www.kimoton.com/entry/20210414/1618372800

Dear PyGui チートシート(Ver.1.1.3 対応版)

どうも、モリカトロン株式会社でエンジニアおじさんを営んでいる岡島です。

以前「PythonのGUIフレームワーク「Dear PyGui」の紹介」という記事で Dear PyGui という Python の GUI フレームワークを紹介してから社内でも使用する人が増えてきました。
そんな Dear PyGui を使い始めた他のエンジニアに使用感を聞いてみたところ「情報が少なくて最初大変でした。 チートシートみたいなものがあるとよかった んですが…」という声が! 自分が触り始めた時には Example が充実していてそんなことなかったのに何故?と思って調べてみると、最近はドキュメントが刷新され、以前にあった Example に相当する資料がなくなっているようです。

既に使い方が分かっている自分は困らないのですが、確かに新しく使おうと思った人にとっては気軽に機能を確認できるようなサンプルコードやインターネット上の情報は重要! ちょっと調べて情報が出てこないようなライブラリは流行らない!

ということで、今回は社内向けの資料を兼ねて Dear PyGui の チートシートみたいなもの を用意してみました。

  • Install
  • Github
  • Document
  • Example
    • Window
    • Input Text
    • Tooltips & Popup
    • Image
    • Plot
    • File Dialog
    • File Dialog (tkinterを利用する場合)
    • Font
    • Widget
続きを読む

GeneralTalker APIを使ったLINE botの作り方

モリカトロンの宮本です。

弊社では、AIとの雑談を実現する GeneralTalker API を公開しています。
雑談を必要とする様々なシステムに組み込んで延々と無駄話を繰り広げていただくことが可能です。

前回はこのAPIを使った Twitterボットの作り方をご紹介しましたが、今回はLINEボットの作り方をご紹介します!

続きを読む

GeneralTalker APIを使ったSlack botの作り方

こんにちは、モリカトロンの山田です。

弊社では、AIとの雑談を実現するGeneralTalker APIを公開しています。
雑談を必要とする様々なシステムに組み込んで延々と無駄話を繰り広げていただくことが可能です。

今回はこのAPIを使ったSlack botの作り方をご紹介します。

続きを読む

GeneralTalker APIを使ったTwitter botの作り方

モリカトロンの宮本です。

弊社では、AIとの雑談を実現する GeneralTalker API を公開しています。
雑談を必要とする様々なシステムに組み込んで延々と無駄話を繰り広げていただくことが可能です。

今回はこのAPIを使ったTwitterボットの作り方をご紹介します。

続きを読む