tkomakiのメモ帳

気が向いたときにLinuxだったり、プログラミングだったり、適当なメモを書いてます。

CentOS6系にpython3系インストール & Flaskを少し触ってみる

CentOS6.9はpython2系がデフォルトでインストールされています。

python3系を使いたいのですがデフォルトの2系を消して3系に変えてしてしまうと、yumとかpythonで動いているものが動かなくなる可能性があります。

ということで、2系のパス(/usr/bin/python)とは別パス(/usr/bin/python3.5)で3系インストールします。

あと、インストールだけだとつまらないので、pythonウェブアプリケーションフレームワークのFlask(ふらすく)を少し触ってみます。

Welcome | Flask (A Python Microframework)

python3系インストール手順

centosデフォルトのレポジトリにはpython3系は無いので、iusレポジトリ入れます

# yum install https://centos6.iuscommunity.org/ius-release.rpm

必要なときだけ明示的に有効化にしたいので、disableに設定。

# vi /etc/yum.repos.d/ius.repo
----
enabled=1 となっている箇所を変更 enabled=0 に変更
----

iusレポジトリを有効化してpython3系インストール

# yum install --enablerepo=ius  python35u python35u-libs python35u-devel python35u-pip

確認(元から入っていたバージョンには影響なし)

# python --version <--元から入ってたやつ
Python 2.6.6
#
# python3.5 --version <--新規インストールしたやつ
Python 3.5.5
#

これでpython3系インストール完了です。それでは、次にFlaskを使うための準備をしていきます。

Flaskインストール

先ほどインストールしたpython3系にFlaskをいれていきます。pythonのパッケージ管理システムのpipを使ってインストールします。

# pip3.5 install flask

pip listでインストールされたことを確認します。

# pip3.5 list|grep -i flask
Flask (1.0.2)
# 

コレでFlaskのインストール完了です。

FlaskでHello World!

インストールが完了したので、ためしに公式のQuickstartガイドのプログラム(hello world!)を書いてみます。

Quickstart — Flask 1.0.2 documentation

# vi hello.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

ファイルを作り終わったので実行してみます。

まずは、作ったプログラムを変数FLASK_APPに指定します。

$ export FLASK_APP=hello.py
$ echo $FLASK_APP
hello.py
$ 

実行してみます。エラーがでました。

$ flask run
Traceback (most recent call last):
  File "/usr/bin/flask", line 11, in <module>
    sys.exit(main())
  File "/usr/lib64/python3.5/site-packages/flask/cli.py", line 894, in main
    cli.main(args=args, prog_name=name)
  File "/usr/lib64/python3.5/site-packages/flask/cli.py", line 557, in main
    return super(FlaskGroup, self).main(*args, **kwargs)
  File "/usr/lib/python3.5/site-packages/click/core.py", line 676, in main
    _verify_python3_env()
  File "/usr/lib/python3.5/site-packages/click/_unicodefun.py", line 118, in _verify_python3_env
    'for mitigation steps.' + extra)
RuntimeError: Click will abort further execution because Python 3 was configured to use ASCII as encoding for the environment.  Consult http://click.pocoo.org/python3/for mitigation steps.

This system lists a couple of UTF-8 supporting locales that
you can pick from.  The following suitable locales where
discovered: aa_DJ.utf8, aa_ER.utf8, aa_ET.utf8, af_ZA.utf8, am_ET.utf8, an_ES.utf8, ar_AE.utf8, ar_BH.utf8, ar_DZ.utf8, ar_EG.utf8, ar_IN.utf8, ar_IQ.utf8, ar_JO.utf8, ar_KW.utf8, ar_LB.utf8, ar_LY.utf8, ar_MA.utf8, ar_OM.utf8, ar_QA.utf8, ar_SA.utf8, ar_SD.utf8, ar_SY.utf8, ar_TN.utf8, ar_YE.utf8, as_IN.utf8, ast_ES.utf8, az_AZ.utf8, be_BY.utf8, ber_DZ.utf8, ber_MA.utf8, bg_BG.utf8, bn_BD.utf8, bn_IN.utf8, bo_CN.utf8, bo_IN.utf8, br_FR.utf8, bs_BA.utf8, byn_ER.utf8, ca_AD.utf8, ca_ES.utf8, ca_FR.utf8, ca_IT.utf8, crh_UA.utf8, cs_CZ.utf8, csb_PL.utf8, cv_RU.utf8, cy_GB.utf8, da_DK.utf8, de_AT.utf8, de_BE.utf8, de_CH.utf8, de_DE.utf8, de_LU.utf8, dv_MV.utf8, dz_BT.utf8, el_CY.utf8, el_GR.utf8, en_AG.utf8, en_AU.utf8, en_BW.utf8, en_CA.utf8, en_DK.utf8, en_GB.utf8, en_HK.utf8, en_IE.utf8, en_IN.utf8, en_NG.utf8, en_NZ.utf8, en_PH.utf8, en_SG.utf8, en_US.utf8, en_ZA.utf8, en_ZW.utf8, es_AR.utf8, es_BO.utf8, es_CL.utf8, es_CO.utf8, es_CR.utf8, es_DO.utf8, es_EC.utf8, es_ES.utf8, es_GT.utf8, es_HN.utf8, es_MX.utf8, es_NI.utf8, es_PA.utf8, es_PE.utf8, es_PR.utf8, es_PY.utf8, es_SV.utf8, es_US.utf8, es_UY.utf8, es_VE.utf8, et_EE.utf8, eu_ES.utf8, fa_IR.utf8, fi_FI.utf8, fil_PH.utf8, fo_FO.utf8, fr_BE.utf8, fr_CA.utf8, fr_CH.utf8, fr_FR.utf8, fr_LU.utf8, fur_IT.utf8, fy_DE.utf8, fy_NL.utf8, ga_IE.utf8, gd_GB.utf8, gez_ER.utf8, gez_ET.utf8, gl_ES.utf8, gu_IN.utf8, gv_GB.utf8, ha_NG.utf8, he_IL.utf8, hi_IN.utf8, hne_IN.utf8, hr_HR.utf8, hsb_DE.utf8, ht_HT.utf8, hu_HU.utf8, hy_AM.utf8, id_ID.utf8, ig_NG.utf8, ik_CA.utf8, is_IS.utf8, it_CH.utf8, it_IT.utf8, iu_CA.utf8, iw_IL.utf8, ja_JP.utf8, ka_GE.utf8, kk_KZ.utf8, kl_GL.utf8, km_KH.utf8, kn_IN.utf8, ko_KR.utf8, kok_IN.utf8, ks_IN.utf8, ku_TR.utf8, kw_GB.utf8, ky_KG.utf8, lg_UG.utf8, li_BE.utf8, li_NL.utf8, lo_LA.utf8, lt_LT.utf8, lv_LV.utf8, mai_IN.utf8, mg_MG.utf8, mi_NZ.utf8, mk_MK.utf8, ml_IN.utf8, mn_MN.utf8, mr_IN.utf8, ms_MY.utf8, mt_MT.utf8, my_MM.utf8, nb_NO.utf8, nds_DE.utf8, nds_NL.utf8, ne_NP.utf8, nl_AW.utf8, nl_BE.utf8, nl_NL.utf8, nn_NO.utf8, no_NO.utf8, nr_ZA.utf8, nso_ZA.utf8, oc_FR.utf8, om_ET.utf8, om_KE.utf8, or_IN.utf8, pa_IN.utf8, pa_PK.utf8, pap_AN.utf8, pl_PL.utf8, ps_AF.utf8, pt_BR.utf8, pt_PT.utf8, ro_RO.utf8, ru_RU.utf8, ru_UA.utf8, rw_RW.utf8, sa_IN.utf8, sc_IT.utf8, sd_IN.utf8, se_NO.utf8, shs_CA.utf8, si_LK.utf8, sid_ET.utf8, sk_SK.utf8, sl_SI.utf8, so_DJ.utf8, so_ET.utf8, so_KE.utf8, so_SO.utf8, sq_AL.utf8, sq_MK.utf8, sr_ME.utf8, sr_RS.utf8, ss_ZA.utf8, st_ZA.utf8, sv_FI.utf8, sv_SE.utf8, ta_IN.utf8, te_IN.utf8, tg_TJ.utf8, th_TH.utf8, ti_ER.utf8, ti_ET.utf8, tig_ER.utf8, tk_TM.utf8, tl_PH.utf8, tn_ZA.utf8, tr_CY.utf8, tr_TR.utf8, ts_ZA.utf8, tt_RU.utf8, ug_CN.utf8, uk_UA.utf8, ur_IN.utf8, ur_PK.utf8, ve_ZA.utf8, vi_VN.utf8, wa_BE.utf8, wal_ET.utf8, wo_SN.utf8, xh_ZA.utf8, yi_US.utf8, yo_NG.utf8, zh_CN.utf8, zh_HK.utf8, zh_SG.utf8, zh_TW.utf8, zu_ZA.utf8
$ 

エラー出力内容と下記ページを読んでみると、UTF-8の設定が必要なようです。

http://click.pocoo.org/5/python3/

私のLANG設定はCだったので、ja_JP.utf8に設定してみます。

元々の設定確認。

$ echo $LANG
C
$ 

utf8に変更。

$ LANG="ja_JP.utf8"

utf8に変更されたか確認。

$ echo $LANG
ja_JP.utf8
$ 

再度実行してみます。成功しました。

$ flask run
 * Serving Flask app "hello.py"
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

上記の通りlocalhostに5000番ポートでLISTENしたようです。別ターミナルを開いて確認してみます。

LISTEN確認。確かに5000番ポートがpython3.5プロセスでLISTENされています。

# netstat -nltp|grep 5000
tcp        0      0 127.0.0.1:5000              0.0.0.0:*                   LISTEN      2369/python3.5      
# 

LISTEN確認できたので、curlでアクセスしてみます。

# curl http://127.0.0.1:5000/
Hello, World!# 
# 

Hello World!と表示されました!先ほど起動していたターミナルでもアクセスログが出力されました。

$ flask run
 * Serving Flask app "hello.py"
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   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 - - [11/Jun/2018 03:31:42] "GET / HTTP/1.1" 200 -        <---アクセスログが追加出力

止めるときは出力にある通り、Ctrl+cで止めちゃってOKです。

HelloWorld! 説明

HelloWorldプログラムの説明を簡単にします。

from flask import Flask 

flaskモジュール内のFlaskクラスのみimportしてます。

app = Flask(__name__) 

Flaskクラスのインスタンスをappという名前で作成してます。

@app.route('/') 
def hello_world():
    return 'Hello, World!'

routeデコレーターでhello_world関数をデコレート。('/')はURLを表します。ここでアプリケーションのURLを指定することができます。

例えばapp.routeを @app.route('/test')に変更すると、 http://127.0.0.1:5000/ にアクセスしても404ステータス(みつからないよ)となり、http://127.0.0.1:5000/testにアクセスするとHello, World!と返答するようになります。

$ curl   http://127.0.0.1:5000/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title> <--- / にアクセスしても404で見つからない
<h1>Not Found</h1>
<p>The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.</p>
$ 
$ curl   http://127.0.0.1:5000/test
Hello, World!$   <---/test にアクセスすると返答する
$ 

以上でFlaskのHelloWorldおわりです。Flaskは思ってた以上に手軽に書けそうでいいかんじです。