pip が 19.02 で pyproject.toml から pip install できるようになった

結論

Poetry + pip 19 で快適!setup.py 書かなくても大丈夫!

背景

pip install 可能な python module を作るには、setup.py を作るやり方がある。(他にもあるらしいがよく知らない)
参考:
Packaging Python Projects — Python Packaging User Guide
pythonのsetup.pyについてまとめる - Qiita

setup.py の書き方もよく理解していないので、package を作るのはめんどいなーというぐらいの認識だった。ところが最近 pip 19.0 で pyproject.toml からのインストールに対応したらしい
Release Notes — pip 19.0.3 documentation
> Implement PEP 517 (allow projects to specify a build backend via pyproject.toml). (#5743)

これによって、
flit やpoetry など pyproject.toml を使って管理するパッケージ管理ツールを使うと、何もしなくても pip install できるようになる!
poetry 好きとしては大歓喜
pyproject で記述されたプロジェクトに対して

pip install git+https://github....

とすればインストールできる。setup.py は不要。以降では Poetry を使った簡単な例を作ってみる。

例

Poetry Project

以下のようにプロジェクトを作る

python -m venv venv
poetry init
git init .

プロジェクト名などは適当に。できたレポジトリはこちら。
GitHub - ororog/pip-poet-test
このプロジェクトには setup.py が無い。でも pip install できる。 pyproject.toml があるから。

pip install してみる

適当な venv を作って pip install してみる。この際、pip を 19 以上にするのを忘れずに。

pip install --upgrade pip
pip install git+https://github.com/ororog/pip-poet-test

これで、コンソールからライブラリを呼び出してみる

>python
Python 3.7.2 (default, Mar 22 2019, 18:18:35)
[Clang 10.0.0 (clang-1000.10.44.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from pip_poet_test import pip_poet
>>> pip_poet.hello()
hello

setup.py をつくらなくてもよくなった🤗

fish に移行した感想

今まで zsh を使っていたけど、突然移行したくなったので fish に移行した。移行には1日ほどかかって、思ったよりすんなり移行できたので感想をまとめる。移行手順とかは対象外。

良いところ

script が書きやすい

POSIX は なぜ if .. fi になってしまったのか。fish は圧倒的に直感的だった。
fish のスクリプトを書く上で気に入っていたのが、イベントへのハンドラが書きやすいこと。
function:【中核】イベントハンドラも別名も関数定義! にまとまっているけど、スクリプト実行直前に関数を実行などが簡単に定義できるので、tmux などで window タイトルの制御が簡単にできる。zsh でも当然できる(と思う)けど、あまり調べる気も起きなかった。
シェルでコマンドの実行前後をフックする - Hibariya 調べたところ、fish ほど簡単ではなさそう。

環境変数は別ファイルで設定

環境変数は set -U でプロンプトから直接永続的に定義できて、fish_variables ファイルにまとまっている。この fish_variables ファイルにまとまっているのが個人的に嬉しくて、zsh とかだと下手に export $PATH=/hoge:$PATH とかすると、再読込(source .zshrc)するたびにPATHが長くなっていく。もちろん zsh でも回避方法はあるけど、fish のほうがずっとスマートに感じる。

plugin manager が使いやすい

自分が oh-my-zsh などをちゃんと使いこなせなかったのが悪いけど、あまり良くわからんかった。それに比べれば全然わかりやすい。使いやすい。
良いプラグインがあるかどうかは、よくわからない。けど、試すのは楽。

悪いところ

fish 未対応なライブラリなどがある

コマンドの補完など、fish は対応してない場合がある。例えば kubernetes の kubectl は bash, zsh の補完は用意されているけど fish は未対応だった(issueはあるのでそのうち追加されると思う)。
対応してない場合は、今の所諦めて待つ。

fish 関係のバグ?に遭遇する

zsh でできたけど fish で動かなかったのは今の所2点

  • tmux + fish で window-status-current-format が設定できない

どうも pwd が tmux を実行した path を返すみたいで、pwd したり #{pane_current_path} を使っても現在のディレクトリが取れない。

  • tmux + direnv で日本語が export できない

fish + direnv を使ってると export HOGE="ほげ" のようにすると以下のようなエラーが出る

from sourcing file -
called on line 61 of file /usr/local/Cellar/fish/3.0.0/share/fish/functions/eval.fish

in function 'eval'
called on line 6 of file ~/.config/fish/conf.d/plugin-direnv_init.fish

in function '__direnv_export_eval'
called on line 5 of file /usr/local/Cellar/fish/3.0.0/share/fish/functions/cd.fish
with parameter list 'VARIABLE SET PWD'

in event handler: handler for variable 'PWD'

他にも、direnv allow としてもなんか動かなかったり、ちょっと挙動が変。
fish の設計に依存する問題だったら、この先も悩むかもしれない。

全体として

全く問題ないわけじゃないけど、今の所解決できないわけでもないので満足している。なにより、zsh は正直よくわからんけど fish のほうが調べる気力が出るのが違う。楽しさがあるので、基本 fish にしようと思う。

EKS を簡単に構築するための CloudFormation

結論

AWS EKS 環境を簡単に構築するための CloudFormation を書いた。

動機

AWS で Kubernetes、EKS のチュートリアルは結構手間が多い
Amazon EKS の使用開始 - Amazon EKS
aws-cli を駆使して自動化する試みもある
qiita.com
が、そもそも VPC だの Role だのは CloudFormation としてまとめて作ってしまえば良いのではないかと思い CloudFormation を書いた。

CloudFormationファイル

github からダウンロードできる
https://raw.githubusercontent.com/ororog/eks-cloudformation/master/eks.yml

この CloudFormation を使った場合のインストール手順

こちらを開いてスタックの作成を選ぶ。
https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks?filter=active

テンプレートを Amazon S3 にアップロードを選択して、先程の yaml ファイルを選択する

f:id:ororog:20181210190940p:plain
アップロード

次の画面では、以下の赤枠の箇所を埋める

f:id:ororog:20190103223316p:plain

スタックの名前は任意の名前で、eks-stack とでもしておけばよい。
KeyName は事前に作っておく必要がある。
Amazon EC2 のキーペア - Amazon Elastic Compute Cloud
ここなどを参考に、先に作っておく。
NodeImageId は、リージョンによって変更する。東京であればデフォルトのまま、それ以外であれば説明に従って選べばいい。
ちなみに、東京リージョンの AMI はなかったのでコピーして作った。

NodeAutoScalingGroupMaxSize はあとで変更するので、最初は0で良い。
クラウドフォーメーション作成時は EKS が立ち上がっていないため、Node を追加することができないため、このようにしている。

以後のページは特に変更する必要はない。そのまま作成。しばらくするとステータスが CREATE_COMPLETE になる
f:id:ororog:20190103224050p:plain

CREATE_COMPLETE になったあとは、スタックの更新から NodeAutoScalingGroupMaxSize の数を変更する
f:id:ororog:20190103224703p:plain
「テンプレートの選択」では、そのまま次へを選択し、
次の画面の「パラメータ」で、数を変更。とりあえず1で良いと思う。
f:id:ororog:20190103224938p:plain

これで以下の手順のステップ1はすべて終わる。あとはステップ2以降に従って進めれば良い。
Amazon EKS の使用開始 - Amazon EKS

まとめ

EKS に必要なリソースを簡単に作成できるようにした

AWS の Fargate のロードバランサーの設定でめちゃくちゃハマった

AWS のFargate でめちゃくちゃハマった

結論からいうと動かない原因は、ロードバランサーのターゲットの種類はipである必要があった。

f:id:ororog:20181018181507p:plain

これは公式ドキュメントにも当然書いてある
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/AWS_Fargate.html

awsvpc ネットワークモードを使用するタスクを含むサービス (例: 起動タイプが Fargate のサービス) では ... ターゲットタイプとして instance ではなく、ip を選択する必要があります。

この問題にハマるポイントは2つあって、

  • ターゲットの種類のデフォルトは instance なので、特に何も考えずに設定すると instance になってしまう
  • サービスを Fargate で構築する時、ターゲットグループが instance のロードバランサーも選択できてしまう

と、いう問題がある。特に二番目は検出して警告なり出してほしい。

ちょろっとハマったところ

ロードバランサーのアベイラビリティ〜ゾーンは、サービスと合わせる

ここと

f:id:ororog:20181018182229p:plain

ここ

f:id:ororog:20181018182420p:plain


ヘルスチェックのパスはちゃんと応答するところにする(404とかじゃだめ)
つまり当たり前かもしれないけど、Fargate はHTTP(S)サーバーじゃないとだめ。
f:id:ororog:20181018182630p:plain

パブリックIP の自動割当は ENABLED のほうが良さそう。
サービスをコンテナから作る前提で、docker pull するためには public ip が必要だと思われるので。でももしかしたら VPC 内から docker pull できれば public ip 必要ない気もする。セキュリティ的にアクセスできないほうがいいし。

どうしても動かないときは

公式のチュートリアルにそって動かせばとりあえず動くと思うので、動くものと動かないものを比較して考えるか、公式のドキュメントを1から読むのがいいと思う(動かないときにググるのが難しい)
https://ap-northeast-1.console.aws.amazon.com/ecs/home?region=ap-northeast-1#/firstRun

牛耕式ビューワー

ブログを取得したドメインに移行したいけど何もできてない。。。

牛耕式?

先日こんなツイートで牛耕式というのを知った。

牛耕式文章とは、簡単に説明すると読む方向を左、右、左、右と1行ごとに変え、右から読む列は文字自体も反転して鏡文字になっている文章のこと。

牛耕式 - Wikipedia

慣れたら早く読めるかも!というの気になったので試してみたいと思って作ってみた。

牛耕式ビューワー

作ってみた感想

なんだろう。。。思ったより読みづらい。ツイートの画像はきれいに読めるのに。
思うに、一行が長いのでスラスラ慣れが必要だと思う。あとフォントが小さめだったり文章自体が長かったり文字自体が小さかったりしている。ツイートの画像は文章量が少ないからそれなりに読める気分になっているかも。
あと、英語は対称にすると b, d とか p q とかがマヂ無理なので結構向かないかも。日本語も ちとさ に問題があるけど、英語ほど辛くは無い気がする。結局なれかも。

実装とか

実装の要点は、一行を 1 div に収めること。1div に収まれば、その div を transform: rotateY(180deg); することで反転できます。それを1行ごとに交互にするだけ。

1行1div に収めるには、文字を足したり減らしたりして高さが変わるところで一行としてました。
イメージ的には

var text = "this is a pen.";
var dom = new Div();
var index = 0;
while (height(dom) < 2行分の高さ) {
  dom.text += text[i++];
}
// 一文字余計なので、dom.text から一文字消す

くわしくは
GitHub - ororog/vue-boustrophedon


ついでなので新しい技術をいくつか試していて、 github.io を使って静的ページを公開してみたり、vue + vuetifyjs をつかってた。dom の操作は jquery を使っているけど、せっかくなので jquery を使わないで書きたい。その場合普通に js 書くのかな? vue でオブジェクトを変更して、オブジェクトに連動して view が変わるのが正当な使い方だと思うけど、今回のように dom を操作したい場合なにでやるのがいいのかな?

alpine に lxml をインストールした docker を構築する

alpine に lxml をインストールしようとするとこんなエラーが出る。

...
** make sure the development packages of libxml2 and libxslt are installed **
...
*********************************************************************************
Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed
*********************************************************************************
error: command 'gcc' failed with exit status 1
...
Command "/usr/local/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-96bb0z1d/lxml/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-i0hoswq1/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-install-96bb0z1d/lxml/

結論としては Dockerfile を次のようにしてインストールできた。

FROM python:3-alpine
RUN apk --no-cache add gcc libc-dev libxml2-dev libxslt-dev
RUN pip3 install lxml

libxml2-dev と libxslt-dev は本家に必要と書いてあった
https://lxml.de/installation.html
また g++ と gcc をインストールしてたが、こちらの stackoverflow によるとlibc-dev と gcc でよさそう
https://stackoverflow.com/questions/35931579/how-can-i-install-lxml-in-docker

Docker を調べるのに使ったリンク集

Docker を調べるのに使ったリンクをまとめておく

docker コマンドまとめ
https://qiita.com/voluntas/items/68c1fd04dd3d507d4083
https://qiita.com/curseoff/items/a9e64ad01d673abb6866

起動中のコンテナのシェルに入る
https://qiita.com/sekizo/items/27cc9b406332afc674f6
alpine の場合は
https://qiita.com/yutaChaos/items/56dd7ea09d7e2b0d9173

docker-compose コマンドまとめ
https://qiita.com/wasanx25/items/d47caf37b79e855af95f#down
https://qiita.com/zembutsu/items/9e9d80e05e36e882caaa

Docker コンテナとイメージを消す
https://qiita.com/tifa2chan/items/e9aa408244687a63a0ae

Docker イメージをいろいろと小さくする工夫
https://qiita.com/pottava/items/970d7b5cda565b995fe7

ベストプラクティス。あとで読み返したい。
http://docs.docker.jp/engine/userguide/eng-image/dockerfile_best-practice.html#add-copy

docker のタイムゾーンを設定
http://yoru9zine.hatenablog.com/entry/2017/01/12/224637

ここらへんを読んでなんとなーく Docker を構築できるようになった