ユーザのリクエストに応じてグラフを生成して返すPython webアプリ

# coding=utf-8

from sanic import Sanic
from sanic import response
import jinja2_sanic
import jinja2
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import io
import base64
import numpy as np
import asyncio


app = Sanic("sanic_jinja2_render")

template="<html><head></head><body><h1>{{graph_title}}</h1>" \
         "<div><img src='{{graph}}'> </div></body></html>"
jinja2_sanic.setup(
    app,
    loader=jinja2.DictLoader(
        {
            "templates.jinja2": template
        }
    )
)

@app.route("/")
async def func(request):
    return response.html("# /point_num で散布図を作成")

def draw_graph(point_num):
    img = io.BytesIO()

    # 乱数を生成
    x = np.random.rand(point_num)
    y = np.random.rand(point_num)

    # 散布図を描画
    plt.scatter(x, y)
    plt.savefig(img, format='png')
    plt.close()
    img.seek(0)

    plot_url = base64.b64encode(img.getvalue()).decode()
    graph = 'data:image/png;base64,{}'.format(plot_url)
    return graph

@app.route('/<number>')
@jinja2_sanic.template("templates.jinja2")
async def show_user_network(request, number):

    graph = draw_graph(int(number))

    return {
        "graph_title":  number,
        "graph": graph,
    }


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    app.run(host="127.0.0.1", port=8000, debug=True)
    try:
        loop.run_forever()
    except:
        loop.stop()

Webエンジニアのための学習リソース(適宜追加)

スキルチェック

Linux

  • (e-book)Linux標準教科書(e-pub, PDFが無料でダウンロード可能)

Docker

Git

SQL

  • SQLZOO
    • 問題ときながらSQLが学べて素晴らしい

Javascript

アルゴリズム/coding面接

Scala

プログラミング言語を学ぶ

完全に初めて

文法をある程度学んだ後

学習全般サイト

  • Udemy
  • Udacity
  • Codecademy
  • coursera
  • JMOOC
  • インターネットセキュリティ基礎 2019, Webで学ぶJavascript 2019, 未経験者のためのPHPMySQLを用いたWebデータシステム入門 2019

画像処理

Deep Learning

 

暗号技術

  • (書籍)結城先生の暗号技術入門

ネットワーク

  • (書籍)ゼロからわかるネットワーク超入門TCP/IP基本のキホン
  • (書籍)ネットワークはなぜつながるか
  • (書籍)OpenSSH[実践]入門
  • (書籍)Real World HTTPミニ

データ分析

Google Cloud Platform

  • gcpugのslackに入る
  • 公式のドキュメントが充実しているので読む、tutorialやる
  • BigQuery
  • DataFlow
  • (book)プログラマのためのGoogle Cloud Platform入門

タッチタイピング

機械学習

学び方について

  • 言葉の定義と概念を抑える
  • 抽象化と具体化の往復
    • で、ようするに一言でいうと?で一言でまとめるを階層ごとに繰り返す
    • で、実際にどうやるの?で実際に実行するを広いフィールドで繰り返す
    • 繰り返して身体に覚え込ませる
    • 現場で使う
  • プログラマの知的生産術
  • Gitの学び方(引用元:https://blog.takanabe.tokyo/2014/12/13/74/)
    ステップ1:Gitの概念がわかる資料を読む
    ステップ2:Gitの簡単な使い方を説明した資料を読む
    ステップ3:Gitの操作パターンを学べる問題集を解く
    ステップ4:Gitを使った実践的な開発をする

GitHubからcloneしたレポジトリを別のリモートレポジトリにpushする


サンプル用のレポジトリをベースに自分のレポジトリをお試しで作りたいときなどに使おうと思って調べた

Python Sanic アプリを Herokuでデプロイする

Sanicとは?

Sanic — Sanic 19.03.1 documentation

  • FlaskやresponderのようなPython用マイクロWeb開発フレームワークの一つ
  • asyncioを使用しているのでPython3.5以上が必要
  • uvloopを使っているので通常のasyncioの2倍以上早い

なぜFlaskでなくSanicなの?

ノンブロッキングな非同期処理(asyncio)を使うのが楽とのことだったので。またuvloopは通常のasyncioよりも高速だから。

ただ現在(2019-04-26)ならresponderという選択肢もあるのかもしれない。

公式sample

from sanic import Sanic
from sanic.response import json

app = Sanic()

@app.route("/")
async def test(request):
    return json({"hello": "world"})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

Herokuとは?

PaaS(Platform as a Service)の代表的なサービス。VPSなどを借りずにwebアプリすぐに立ち上げることができる。小規模な利用なら無料枠で利用できる。セールスフォースのサービス。類似サービスとしてGoogleのFirebaseがある。

tutorialが丁寧なので、とりあえずどんなものかを知るにはtutorialやるといい。

Herokuのデプロイに必要なファイルを準備する

  • アプリケーションのプログラム
  • Prockfile
  • requirements.txt
  • runtime.txt

Prockfile

Prockfileは起動時にアプリによって実行されるコマンドを記述するファイルのこと。 Prockfileは次のように書く。 <process type>: <command>

SanicのアプリをHerokuにデプロイする用のProckfile

# Prockfile
web: gunicorn your_app_name:app --worker-class sanic.worker.GunicornWorker

gunicorn とはGreen Unicornのことで、UNIX用のPython WSGI HTTPサーバーのこと。Sanicではgunicornの引数として--worker-class sanic.worker.GunicornWorker が必要なので注意。Green UnicornRubyUnicornプロジェクトから移植された。またWSGIはWeb Server Gateway Interface (WSGI; ウィズギー) の略で、Pythonにおいて、WebサーバとWebアプリを接続するための標準化されたインタフェース定義。

requirements.txt

Pythonモジュールを記述するファイル。pip freezeで現在の環境にインストールされたパッケージとバージョンを出力して作る。なお、今回anaconda環境でアプリ作っていてpip freezeしたらanacondaのモジュールが全て書き込まれた。。仮想環境で必要なライブラリだけで開発しないとだめですね。

$ pip freeze > requirements.txt
# requirements.txt
gunicorn==19.9.0
networkx==2.2
sanic==19.3.1
jinja2==2.10.1
jinja2_sanic==0.1.2
matplotlib==3.0.3
aiohttp==3.5.4

runtime.txt

# runtime.txt 
python-3.7.3

Herokuへデプロイ

おおまかな手順

  1. Herokuに登録

  2. cliツールのインストール

  3. heroku login

  4. heroku create your_app_name

  5. gitリポジトリの生成

    bash git ini git add . git commit -m 'first commit'

    (これだけだと6でエラーがでた気がするが、error logみて直した。忘れてしまった。。)

  6. git push heroku master pushできない。。

fatal: 'heroku' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

こちらの記事に書いてあるように、リモートのリポジトリが参照できていなかったので、リモートにherokuを追加する。

Herokuにpush時にdoes not appear to be a git repository出た時の対処 - Qiita

  • エラーがでたときはログみる
heroku logs

GitHubにあるレポジトリからherokuにデプロイする場合

全体の参考資料