Rest Term

Blog

GitHubのユーザープロフィールを表示するWordPressプラグインを作った

WordPressの勉強目的にプラグインを1つ作ってみました。

WP GitHub Card

GitHubのユーザープロフィールをカード形式でWordPressのページに貼り付けるだけのプラグインです。以下のように使います。

上記のコードをWordPress上の任意の場所に貼り付けます。WordPressのショートコード形式となっているのでウィジェットに限定しません。どこでもOKです。

* 表示例

上記スクリーンショットの通り、以下の情報が表示されます。

  • GitHubアカウント名とアバター画像
  • 最近コミットしたリポジトリ
  • よく使うプログラミング言語トップ3(リポジトリのスター数でソート)
  • パブリックなリポジトリとgist数
  • フォロワー数
  • 全てのリポジトリのスター数の合計

データ取得にはGitHubの公式APIを利用しており、取得した各種データはWordPressのDB内に一定時間キャッシュして非機能面も考慮していまう(Transientsのキャッシュ機構を利用)。

公式プラグインページとソースコードは以下にあります。

目的

元々はGitHub Badgeというサービスの機能を自分のサーバでホスティングしたいという動機からプラグイン開発を始めました。GitHub Badgeのように外部コンテンツをiframeで自分のサイトに埋め込む方式だと性能面やセキュリティ面で問題を感じており、また、サービスとして提供すると不特定多数の人が利用するためGitHub APIのリクエスト数制限にもひっかかる頻度が高くなります。それらの問題を解決するために、自分のサーバでコンテンツ配信しつつ適切にデータをキャッシュすることにしたという経緯です。

WordPressについて

このサイトはWordPressで数年運用していますけど、これまでWordPress本体についての知識はほとんどなかったです。まぁプラグインを作った程度ではWordPressのほんの一部しか理解できないと思いますが、良い勉強になりました。

ところで2018年現在、インターネット全体(厳密にはtop10 millionのサイトが集計対象)の約30%のWebサイトがWordPress製サイトであるという統計結果があります。

2015年時点では25%程度だったそうなので、そこから3年弱で5%も上がったということですか。大昔にみんながMovable TypeからWordPressに移転してた頃に現在のこの状況を想像できたでしょうか。

また、GoogleもWordPressエキスパートの求人をしているようです。それほどWordPressは現在のWebにおいて重要な位置に鎮座しているということでしょうか。最近まで転職活動をしてた知人のWebデザイナーも面接でWordPressが使えるかどうか聞かれたことがあると言っていました。

長年WordPressを触っていたにもかかわらず、これまで全くと言っていいほどWordPressについて無知でした。遅いスタートになりますが今後もプラグインやテーマを作ってみる機会を増やしてWordPressの学びを増やしていきたいと思います。

 

Tags: , ,

常時SSL化とHTTP/2対応しました

ドメイン rest-term.com の常時SSL化とHTTP/2に対応しました。

本サイトのコンテンツはCloudflareで配信しているので常時SSL化自体は簡単でした。後はコンテンツ内でのhttp/https混在(mixed content)を解消したり、パフォーマンス改善のためにWordPressプラグインを整理したり、一部は自作したものに置き換えたりとか細かい作業をしていました。SSL化関連の作業メモについてはWikiの方に書いてますので興味があれば。CloudflareだけでなくLet's Encryptの証明書発行作業等についても触れています。

現在、RSSフィードは旧URLと新URL(https://rest-term.com/feed/atom/)の両方を配信してます。いずれは新URLの方だけにする予定です。

HTTPS化したのでHTTP/2対応も併せて行いました。早くHTTP/2が当たり前の世界になって欲しいですね。

HTTPS化するとはてなブックマークなどのSNSへのシェア数がリセットされる問題は有名かと思いますが、SNS Count Cacheプラグインを利用すればHTTP時代の数値を合算表示させるのは簡単に実装できました。あとはGitHubバッジのウィジェットが重いのでセルフホスティングできるタイプのプラグインを自作しようかと思っています。

近い内に各Webブラウザが非HTTPSサイトを警告表示する取り組みが実施されるかと思いますが、常時SSL化が間に合って良かったです。まだ一部不具合が残っているページもあるかもしれませんが確認次第対応していきます。

 

Tags: ,

PythonのWebアプリケーションフレームワーク Sanicを試す

PythonのWebアプリケーションフレームワークについて、Flaskからの移行先としてSanicが有力そうなので調べています。

Sanic is a Flask-like Python 3.5+ web server that's written to go fast.

Sanicは著名なイベントループライブラリであるuvloopを利用しており、Node.jsのように非同期I/Oによる高効率なHTTPリクエスト処理が可能です。また、SanicはFlaskとよく似たシンタックスを提供しているため、他のフレームワークよりも移行コストを抑えることができそうです。

環境

サーバ環境

  • Ubuntu 16.04 (x86_64)
  • CPU 3.30GHz 4core / 8GB RAM
  • Python 3.6.4
  • Sanic 0.7.0 / Flask 0.12

クライアント環境

  • macOS High Sierra 10.13.4 (x86_64)
  • CPU 1.70GHz 4core / 8GB RAM

ネットワーク環境

注意点としてはSanicは asyncio および async/await 機能を利用しているためPython3.5以降が必要です。Python3移行は2018年現在なら世間的にもけっこう進んでいるとは思いますが、3.5以降となると業務で使っている人はまだ少ないかもしれません。

使い方

公式でFlask-likeと謳っているとおりインタフェースはFlaskとよく似ているので移行作業自体は楽だと思います。

Flaskでhello, world

Sanicだと以下のようになります。まさにFlask-likeですね。

上記SanicのコードではPython3.5以降で正式に利用できるasyncキーワードが現れています。C#やNode.JSなど他言語におけるasync/awaitと同等の機能が言語標準で提供されるようになりました。Sanicを使う場合は、個人的にNode.js開発でよくやってしまうawaitの置き忘れも気にしなくて良いのは助かります。

JSON対応

JSONレスポンスを返すには以下のように書きます。FlaskもSanicどちらも使いやすいと思います。パッケージ構成はSanicの方が整理されてる気はしますがどうでもいいレベル。

ちなみにJSONパーサーは独自実装ではなく外部モジュールが使われています。Flaskを使う場合はsimplejsonをセットで入れておくと良いです。Sanicはujsonが必須となっています。

  • Flask: simplejson or json
  • Sanic: ujson

JSONモジュールのベンチマークに関しては以下のサイトが参考になります。

ujson優勢みたいなのでJSONレスポンスを含めたベンチマークだとFlaskが不利だと思うので、テキスト("hello,world")のみを返すシンプルなコードで計測します。ただ、有利不利とか言ってしまうとuvloopに乗っかっているSanicはズルいという話になってしまいますけども。。

ベンチマーク

前述のサンプルコード('hello, world'文字列を返却)で組み込みHTTPサーバのベンチマーク。同一LAN内でクライアント/サーバの2台用意して計測、ツールはwrk2を利用しました。

ネットワーク周りのカーネルパラメータは以下の通りです。TCPのsyn backlogをsomaxconnの値と合わせて増やす程度のチューニングはしてあります。TCP接続を使い回す設定にもしていますが、今回のベンチマークでは意味ないですね。

まずは4スレッド同時100コネクション、2000rpsで30秒間負荷を与えました。

レイテンシ周りの計測値を見てみるとわかりますが、これだけでもかなり性能差があることが読み取れますね。低スペックのサーバで動かしているのですがSanicの方はまだまだ余裕がありそうです。次は4スレッド同時200コネクション、4000rpsで30秒間負荷を与えました。

Flaskの方は限界が見えてますね。タイムアウトも発生しています。ネットワーク周りのカーネルパラメータが未調整だと他のソケット関連エラー等も併せて出てくるはずです。一方でSanicの方は安定した性能です。uvloopすごい。

(横軸の数値が見えてないですが、1/ (1 - Percentile) 刻みの対数表示となっています)

おわりに

Pythonのasyncioに対応したフレームワークはSanic以外にもいくつかありますが、既存のFlask製アプリケーションの移行コストを最小化するために、Flask-likeなSanicを採用するのは悪くない選択だと思います。2,3年前にFlaskの代替として、Falconというフレームワークに移行する作業もやったことがあるのですが、使い方がFlaskと結構違うので移行コストが高かったです。その点、Sanicを使えばその辺りの面倒を省くことができますね。Flaskプラグインの移植性も高く、ベストプラクティスの流用も行いやすいのではないでしょうか。

また、Sanicはasyncioのdrop-in replacement実装としてuvloopを組み込んでおり、uvloop自体はlibuvをベースにしているので実績も十分、性能も保証されています。Python3.5以降が必要なので実業務で採用するのはまだ少しネックになりそうですが、そこは時間が解決してくれる部分でしょう(スタートアップのサービスとかなら勢いで採用しても良いかも?)。他にuvloopをベースにしたフレームワークとしてはjaprontoというのもあります。Flask-likeでなくても良いならこちらも選択肢としてアリですね。

まずはプライベートワークで作っているPython製WebAPIはSanicに移行してみようと思いました。前回紹介した pyvips(libvips) を利用すれば高速な画像処理サーバもPythonで簡単に書けそうです。

参考

 

Tags: ,

libvipsで高速省メモリな画像処理

今回は高速省メモリな画像処理ライブラリである libvips を使ってみます。

libvips is a demand-driven, horizontally threaded image processing library. Compared to similar libraries, libvips runs quickly and uses little memory. It has around 300 operations covering arithmetic, histograms, convolution, morphological operations, frequency filtering, colour, resampling, statistics and others. - libvips: A fast image processing library with low memory needs.

libvips自体は著名な画像処理プロダクトですが、各スクリプト言語のバインディングライブラリや公式サイトが2017年に刷新されたようで、今後はさらに利用が普及することが予想されます。また、PythonバインディングのpyvipsはTop 10 Python libraries of 2017でも紹介されており、注目度も高くなっています。今回はこのpyvipsを使って簡単な使い方を学びます。

環境

  • Ubuntu 16.04.3 LTS (Bash on Ubuntu on Windows10 Pro)
  • Python 3.6.3 (conda 4.3)
  • libvips 8.6.1
  • pyvips 2.0.4

導入

* apt を利用する場合

aptでインストールするのは簡単ですが、バージョンがけっこう古いようなので注意してください。それに必須ではない依存パッケージもいろいろインストールされるようなのでミニマリストの方にはあまり印象は良くないかも。最新版かつ好きな構成で使いたいならgithubからソースをダウンロードしてきて手動でコンパイル・インストールします。

* ソースからインストールする場合

./configure時に対応ファイルフォーマットが標準出力に表示されるので、必要な依存ライブラリ(libjpeg、libpngなど)も併せてインストールしておいてください。

* 確認

libvips本体のインストールが完了したら続けてPythonバインディングのpyvipsをインストールします。こちらはpipを使えば簡単に入ります。

libvips本体が事前にインストールされていない場合、pyvipsのimport時にOSErrorが出ます。

使い方

今回は動作確認を兼ねて画像入出力や簡単な画像処理を試してみます。以降はJupyter Notebookで書いたドキュメントを貼り付けます。

上記のように、pivipsとnumpy間のデータ相互変換(pyvips.Image <-> numpy.ndarray)が可能なので、OpenCVとの連携も簡単に行うことができそうですね。

おわりに

libvipsは比較的簡単な画像処理用途に特化したプロダクトで、高速省メモリな処理が特徴となっています(Speed and memory use)。もし画像処理を手軽に行いたいだけならOpenCVを導入するのは大袈裟なので、要件に応じて適切なプロダクトを採用したいですね。今回は導入部分の紹介でしたが、次回はより深掘りして調査できればと思います。

ちなみに今回のエントリーからJupyter Notebookで書いたドキュメントを時々記事に貼ろうと考えているので、GitHubにNotebook用のリポジトリを作りました。こちらも興味があれば。

 

Tags: ,