python37のGoogle App Engine でもバーコードを作る


PHPでバーコードを作ったばかりなのに……
何が自分を駆り立てるのだろうか

今回はpyBarcodeというライブラリを使ってみました。

実装物!

内容!

そんなに難しいことはしていないのです。
Flaskがわかれば簡単かな?

pybarcode.py
import barcode
from barcode.writer import ImageWriter
from flask import Flask, send_file

@app.route('/', defaults={'_': ''})
@app.route('/<path:_>')
def index(_):
    byte_io = BytesIO()

    ean = barcode.get_barcode('ean13', '4902102072618', writer=ImageWriter())
    ean.write(byte_io)

    byte_io.seek(0)

    return send_file(
        byte_io,
        as_attachment=True,
        attachment_filename='barcode.png',
        mimetype='image/png',
    )

byte_io = BytesIO()

ファイルを実際に書き出さずにレスポンスとして返してあげたいので書き込み先を用意してあげています。

ean = barcode.get_barcode('ean13', '4902102072618', writer=ImageWriter())
ean.write(byte_io)

pyBarcodeの使い方に則って、コカコラーのバーコードを作ってます。
作ったものは、先ほど用意した変数に書き込んでいますね。

byte_io.seek(0)

ここでシーク位置を元に戻してあげないと、次のdownload処理でゼロバイトのデータが帰ってきてしまうので戻してあげましょう。

return send_file(
byte_io,
as_attachment=True,
attachment_filename='barcode.png',
mimetype='image/png',
)

Flaskのファイルダウンロード処理を実行させて完成です!

実際に作成されるもの!


https://neko-tech-test.appspot.com/gae-py37-barcode

今回、本当に確認したかったもの

はい、バーコードは作れたんですが、じゃあこれが本来の目的か? と言われると少し違っていて。
pyBarcodeって、pythonの画像処理系のライブラリ、PILを使っているんですね。

Google App Engineってstandard環境に、python27を提供していたんですが、PILとかのライブラリってそのままだと使えなかったんですよ。
third-party-libaryとして使用するのであれば、app.yamlに使用するように書いてね?っていう。
そうすると、GAE側でインストール済みのものを提供するんで、参照・使用できるよーっていう。

使えるならいいではないか。という話ではあるんですが、ただこれって、利用できるバージョンは制限されてしまうし、逆にPILを使用するようにrequirements.txtとかに書こうものなら今度は動かなくなるみたいな色々と問題があったりして。
デフォルトのものではないので、Google提供のものを使用すると上手く動かないッ!? みたいなものもポツポツあったりと。

そもそもなんで使えないんだろう?となると、PILを使用する処理の中にgoogleのコンテナの中で動かされると、よろしくないものがある……ので、対策をほどこしたものを提供しているのかな?とは推測しているんですが、そこは確認も取っていないので一回置いておきます。

ただ今回のpython37 runtimeのGoogle App Engineでは、そこが問題にならずにサクッとバーコードを作成できてしまっている。
そう、python37ではこのあたりの問題がクリアされているのです。
gVisorを使用したものでGoogle App Engineを動かしている……らしいんですが、そこのおかげでだいぶ便利になってきたなと。

このまま、もっともっと便利になって貰えることを祈るばかりです