はじめに
以前作成したpythonスクリプトをWebアプリにして公開してみました。
URL:~~http://ysuzuki.pythonanywhere.com/~~←現在停止中
プログラム自体は気軽に作れるのですが、それをWebアプリにするのは少しハードルが高かったです。同じような人が多くいると思い、公開するまでの過程を記しました。
「こんなPythonスクリプト作ったよ!Webアプリにしたい!」という方は、よかったら参考にしてみてください。
Webアプリにするプログラム
画像内の英文を和訳するPythonスクリプトを作りました
に掲載したプログラムをWebアプリにする。
使用したもの
- macbook pro
- python3 (cv2, PIL, pyocr, googletrans)
- flask
- pythonanywhere
Flaskをはじめる
~$ pip3 install Flask
~$ mkdir flask-ws
~$ cd flask-ws
こちらに最小規模のソースコードが載っている。以下、引用。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return "Hello World!"
if __name__ == '__main__':
app.run()
このプログラムを実行すると、
~/flask-ws $ python3 simple.py
* Serving Flask app "simple" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
と、ローカルサーバが完成する。最下行にURL(http://127.0.0.1:5000/
)が記載されており、ここにアクセスすることでWebアプリにアクセス(?)することができる。ターミナルはこのままにして、好みのブラウザのURL入力欄にhttp://127.0.0.1:5000/
と入力すると、
アクセスできた。この時、先ほどのターミナルを見てみると、
~/flask-ws $ python3 simple.py
* Serving Flask app "simple" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [22/Jul/2019 02:07:00] "GET / HTTP/1.1" 200 -
と一番下にGETが追加された。
ここまでで、Flaskそのものの動作確認ができた。
自分のプログラムをFlaskアプリにする
画像取得はこちらが非常に勉強になった。この方のソースコードに上乗せする形で作成することになった。
主な変更部分
- 変換部分を削除
- image_process.pyは使わずに
app.py
に直書き - 保存したプログラムをpyocrのtoolから開く
- 読み取った後はファイルを削除する
- return でリダイレクトではなくてプレーンテキストを返す(ダサいけど)
-
template/index.html
に<h1>title</h1>, <h3>message</h3>
で文字を追加(ダサいけど)
完成したpythonスクリプトは以下。
# coding: utf-8
from flask import Flask, render_template, request, redirect, url_for, send_from_directory
import numpy as np
import cv2
from image_process import canny
from datetime import datetime
import os
import string
import random
from PIL import Image
import pyocr
import pyocr.builders
from googletrans import Translator
SAVE_DIR = "./images"
if not os.path.isdir(SAVE_DIR):
os.mkdir(SAVE_DIR)
app = Flask(__name__, static_url_path="")
def random_str(n):
return ''.join([random.choice(string.ascii_letters + string.digits) for i in range(n)])
@app.route('/')
def index():
title = "画像内の英文を和訳するページです"
message = "英文の入った画像をアップロードしてください"
return render_template('index.html', title=title, message=message)
@app.route('/images/<path:path>')
def send_js(path):
return send_from_directory(SAVE_DIR, path)
@app.route('/upload', methods=['POST'])
def upload():
if request.files['image']:
stream = request.files['image'].stream
img_array = np.asarray(bytearray(stream.read()), dtype=np.uint8)
img = cv2.imdecode(img_array, 1)
dt_now = datetime.now().strftime("%Y_%m_%d%_H_%M_%S_") + random_str(5)
save_path = os.path.join(SAVE_DIR, dt_now + ".png")
cv2.imwrite(save_path, img)
tools = pyocr.get_available_tools()
if len(tools) == 0:
sys.exit(1)
tool = tools[0]
langs = tool.get_available_languages()
lang = langs[0]
txt = tool.image_to_string(
Image.open(save_path),
lang=lang,
builder=pyocr.builders.TextBuilder()
)
translator = Translator()
translated = translator.translate(txt, src='en', dest='ja')
os.system('rm ' + save_path.replace(' ', '\ '))
return '<h1>和訳ができました!</h1><h2>英文</h2>' + txt + '<h2>和訳</h2>' + translated.text
if __name__ == '__main__':
app.debug = True
app.run(host='0.0.0.0', port=8888)
完成したindex.html
は以下。
{% extends "layout.html" %}
{% block content %}
<h1>画像内の英文を和訳するページです</h1>
<h3>英文の入った画像をアップロードしてください</h3>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="image" accept="image/png, image/jpeg">
<button type="submit">submit</button>
</form>
{% if images %}
{% for path in images %}
<div>
<img src="images/{{ path }}" style="margin-top: 10px; vertical-align: bottom; width: 200px;">
{{ path }}
</div>
{% endfor %}
{% endif %}
{% endblock %}
以上の結果、画像を受け取って、画像内の英文を抽出して和訳するWebアプリが完成した。完成したWebアプリについては下の方で紹介する。
ここまでは先ほどのhttp://127.0.0.1:5000/
のローカルサーバで確認しながら作業を進めた。
pythonanywhereに自分のWebアプリを移す
これまでの作業のプログラムをGithubリモートリポジトリにプッシュしておいた。ここでの作業は基本的にこちらのページを参考にした。なので、ここでは概要だけを記載する。実際に作業する方はリンク先を参考にしてほしい。
- pythonanywhereに登録→こちら
- bashコンソールを開く
- 'git clone https://github.com//`でクローン
- bash上で動作確認(しなくてよい)
-
pip install
はpip install user
にしないとエラーが発生する
-
- dush board上でWeb apps内のの「Open Web Tab」をクリック
- 「Code」という見出しの
/var/www/<user name>_pythonanywhere_com_wsgi.py
を調整-
project_home
変数を自分のプロジェクトホームに変更 -
from app ...
行の先頭のapp
のみを自分のプログラム名に変更
-
- Web appページの上の方の「Reload .pythonanywhere.com」をクリック
ブラウザからhttp://<user name>.pythonanywhere.com
へアクセスすると、自分で作成したWebアプリを使用することができた。
完成したWebアプリ
ここまで来て、ついに自分のWebアプリが完成した。是非試してみてほしい。
URL:http://ysuzuki.pythonanywhere.com/
上記URLへアクセスすると、
アップロードを促すページが表示された。 今回は、Wikipediaのホームのスクリーンショットである以下を和訳してみようと思う。 「ファイルを選択」をクリックして上の画像を選択すると、 「submit」をクリックして少し待つと、 おお!英文と和訳が出力された!困ったエラーの解消について
ひとつ困ったエラーがあり、応急処置した。これはどこにも載っておらず自分で考えたので邪道ではあるだろうが、一応記す。
「Reload .pythonanywhere.com」をクリックしてURLにアクセスしても
と出てきて、自分のWebアプリが表示されなかった。そこで、<user name>.pythonanywhere.com.error.log
を開いたところ、
ModuleNotFoundError: No module named 'pyocr'
ModuleNotFoundError: No module named 'googletrans'
と、pythonでおなじみのエラーが吐かれていた。(実際のlogには他の出力もあったがエラー部分はこれ)
そこで、bash console
でWebアプリを起動してみても、問題なく動作する。bash上でインストールしたpyocr,googletrans
たちはbashのユーザ(--user
)にインストールされており、そのままでは使えないようだ・・・
そこで考えた応急処置が、
「実行ディレクトリにmoduleを持ってくる」
だ。その流れは以下。
$ find / -name pyocr
/home/<user name>/.local/lib/python3.7/site-packages/pyocr
$ cp -r path/to/pyocr path/to/project_directory
$ find / -name googletrans
/home/<user name>/.local/lib/python3.7/site-packages/googletrans
$ cp -r path/to/googletrans path/to/project_directory
この結果、なんとかWebアプリは動いたのだが、カレントディレクトリにライブラリが直接おいてあるというなんとも不恰好な環境になってしまった。本来は仮想環境でやるようである。
おわりに
Webアプリについての知識が少なかったので、多くの人のページを参考にさせていただきました。
取り敢えず動くものをと開発したため、多くの粗があると思いますので、まるまる真似すると危険かもしれません!!
特に、無理矢理解決したpyocr,googletransのimportについてはなんとか改善したいと考えています。(仮想環境でできるのかな?)
参考
-
Flaskで簡単につくる、画像処理した結果を見るだけのWebサービス
- Flaskで画像を取得する部分
-
PythonAnywhere に Flask アプリをデプロイ
- PythonAnywhereでFlaskアプリを動作させる処理全般
-
Installing new modules
- pythonanywhere上のターミナルにpythonモジュールをインストールする方法
-
Flaskへ ようこそ¶
- flaskの基礎、最小規模のプログラム
-
Pythonで簡単なWebアプリ作りたいならFlaskがおすすめ
- Flaskアプリの基礎、文字をブラウザに返す方法
-
【初心者向け】HTMLの改行方法まとめ|pタグとbrタグの使い方
- プレーンテキストに改行を追加
-
Flaskの簡単な使い方
- タイトルの追加(index.html)