Upload
phungtram
View
246
Download
2
Embed Size (px)
Citation preview
PASONA TECH ウェルカムセミナー
拡大するPythonのエコシステムとWebアプリケーションのポイント
辻 真吾(@tsjshg)2016.4.20
自己紹介❖ 1975年生まれ
❖ 東京大学先端科学技術研究センター 特任助教
❖ 研究室は癌とゲノム
❖ やっていることはPythonでデータ解析
❖ 昔はJavaでWeb開発とかしていましたが、いまは全部Python
❖ http://www.tsjshg.info/
みんなのPython勉強会
❖ http://startpython.connpass.com/
❖ 誰でも歓迎なPython勉強会
❖ 次回は5/10 19:00~の予定です
Udemy
https://www.udemy.com/python-jp/?couponCode=pasona16052016/5/31までの30%OFFクーポンはこのURLから
今日の構成❖ Pythonについて
❖ Pythonには勢いがある
❖ Pythonの環境構築
❖ 標準モジュールで始めるWeb開発
❖ HTTPサーバ、CGI、Webアプリケーションサーバ
❖ Webアプリケーションフレームワーク
❖ Djangoを使った開発の実際
Pythonには勢いがある!
http://pypl.github.io/PYPL.html
TIOBE Index for April 2016
http://www.tiobe.com/tiobe_index
なぜ?❖ There should be one-- and preferably only one --obvious way to
do it.
❖ import this で出てくる The Zen of Python
❖ なにかするとき、選択肢が1つ、出来ればそれが唯一の方法であること
❖ 他人(玄人)が書いたコードがあまり苦労無く読める
❖ バッテリー同梱(標準モジュールが充実)
❖ 機械学習分野で独壇場の立場を築きつつある
Pythonの環境構築
Pythonのインストール
❖ 2系と3系がある
❖ 後方互換性がありません
❖ 特に理由がなければ3を
❖ MacOSXやLinuxのOSにはじめからインストールされているのが2系(なのが残念)
www.python.org
Anacondaがおすすめ!
❖ Continuum Analytics社が配布するPython
❖ 標準のPythonにcondaをはじめとして多くの外部ライブラリを同梱
❖ 無料(メアド登録あり)
❖ データ解析環境の構築に最適https://www.continuum.io
実装
❖ 標準の実装(CPython)www.python.org
❖ Jython Javaによる実装 www.jython.org
❖ IronPython .NET環境 ironpython.net
❖ Cython 高速化の試み cython.org
❖ 基本的には標準の実装で
Python Package Index(PyPI)
外部モジュールが豊富 78,280個(2016年4月10日)
外部パッケージの追加方法ファイルをダウンロードして解凍後
$ python setup.py install
lib/python3.5/site-packagesのようなディレクトリにインストールされる
実際はpipが便利• Python3.4から標準装備
• PyPIから自動ダウンロード
• 削除にも対応
• 使い方(OSのシェルで)
• pip install -U django
• -U or ̶upgradeで最新版を取得
• pip freeze
• いまの状態を表示
しかし・・・❖ CやFORTRANで書かれたライブラリがその場でコンパイルされることがある
❖ Linuxは大丈夫
❖ MacOSXならXCodeのインストールで対応
❖ 開発環境を手軽に整えるのが難しいWindowsでこの問題は重い
condaが便利
❖ $ conda install django
❖ pipと同じような方法で、外部モジュールを追加
❖ PyPIではなく、Continuum Analytics社のレポジトリに接続し、Windowsでもコンパイル済みのバイナリをとってきてくれる
まとめ
❖ Python + pip + conda❖ Minicondaでこれらが揃う
❖ データサイエンスやるならAnaconda
❖ どちらもContinuum Analytics社のページからダウンロード可能
https://www.continuum.io/
IPython (Jupyter) notebookが便利
[Demo] IPython (Jupyter) notebookが便利
❖ PythonインタラクティブシェルIPython
❖ コマンドラインでipython
❖ Webブラウザで利用できるipython notebook
❖ 起動
❖ コードの入力
❖ markdown❖ 保存
標準モジュールで始めるWeb開発
PythonはWebサーバを内蔵している
❖ $ python -m http.server
❖ 3系ではこれだけで、Webサーバが起動
❖ [Demo]実際に起動してみる
http/server.pyif __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--cgi', action='store_true', help='Run as CGI Server') parser.add_argument('--bind', '-b', default='', metavar='ADDRESS', help='Specify alternate bind address ' '[default: all interfaces]') parser.add_argument('port', action='store', default=8000, type=int, nargs='?', help='Specify alternate port [default: 8000]') args = parser.parse_args() if args.cgi: handler_class = CGIHTTPRequestHandler else: handler_class = SimpleHTTPRequestHandler test(HandlerClass=handler_class, port=args.port, bind=args.bind)
testの中身def test(HandlerClass=BaseHTTPRequestHandler, ServerClass=HTTPServer, protocol="HTTP/1.0", port=8000, bind=""): """Test the HTTP request handler class.
This runs an HTTP server on port 8000 (or the first command line argument).
""" server_address = (bind, port)
HandlerClass.protocol_version = protocol httpd = ServerClass(server_address, HandlerClass)
sa = httpd.socket.getsockname() print("Serving HTTP on", sa[0], "port", sa[1], "...") try: httpd.serve_forever() except KeyboardInterrupt: print("\nKeyboard interrupt received, exiting.") httpd.server_close() sys.exit(0)
HTTP通信
❖ 普段はブラウザがやっているHTTP通信をtelnetで再現
❖ [Mac/Linux] $ telnet localhost 80
❖ GET test.html HTTP/1.0
CGIもできる
❖ cgi-binディレクトリの作成
❖ CGIスクリプトを書く
❖ [Mac/Linux] 実行可能属性を与える
❖ 試してみよう
#!/usr/bin/env python# coding: utf-8
print('Content-Type: text/plain')print('')print('こちらはCGIです。')
クライアントからの情報
#!/usr/bin/env python# coding: utf-8
import cgi
f = cgi.FieldStorage()val = f.getfirst('text', '')
print('Content-Type: text/plain')print('')print('受け取った文字列は「{}」です。'.format(val))
もちろん、GETやPOSTで情報の送信もできます。
Pythonにはデータベースもある
RDBMSと言えば❖ Relational DataBase Management System(RDBMS)と言えば
❖ Oracle / MySQL
❖ PostgreSQL
❖ DB2 (IBM)
❖ SQL Server (Microsoft)
❖ …
SQLite
https://www.sqlite.org/
[Demo] SQLiteを使って見る
❖ http://localhost:8888/notebooks/SQLite3_demo.ipynb
❖ sqlite3というコマンドラインツールもある
❖ 試してみよう
PythonとWebアプリケーション
WSGI❖ Web Server Gateway Interface
❖ PythonのおけるWebアプリケーションのための標準仕様
❖ 標準モジュールにwsgiref(WSGI Utilities and Reference
Implementation)がある
❖ WSGIに準拠したWebアプリを標準モジュールだけで作れる
❖ 多くのPython製WebアプリフレームワークやWebサーバがこの仕様に準拠
Webアプリ開発
❖ 標準モジュールだけで開発は、さすがに現代風じゃない
❖ Webアプリ開発では、フレームワークの利用が一般的
❖ Pythonにはどんな選択肢があるのか?
PythonとWebアプリ開発
❖ Python製フレームワークは選択肢が沢山ある
❖ 言語の哲学(やり方はできれば一種類がいい)と矛盾している?
❖ Webは用途が広いので、フレームワークの細分化は必要
❖ 「みんなのPython」柴田淳さん
代表例❖ Bottle (http://bottlepy.org/)
❖ 超軽量(なんと1ファイル)すぐ使える
❖ Flask (http://flask.pocoo.org/)
❖ Pyramid (http://www.pylonsproject.org/)
❖ Pylonsの流れをくむ
❖ Django (https://www.djangoproject.com/)
❖ 本日ご紹介するフルスタックフレームワーク
フレームワークの構成
View
Controller
Model
RDBMSデータベースソフトウェア
Object-Relational MappingORM(OR Mapper)
• SQLAlchemy• peewee• SQLObject• Storm• Django
Template Engine
• Mako• Jinja2• Cheetah• Bottle• Django
Webアプリケーションフレームワークは、これらの組み合わせ
Djangoは自前主義統一感があって分かり易い
Djangoチュートリアル
Djangoについて
❖ フルスタック(全部入り)Python製Webフレームワーク
❖ 比較的長い歴史があり、大規模サイトでの利用例も多い
❖ ひとたびコツを掴めば、開発スピードが相当加速する
インストール
❖ pip install django
❖ conda install django
❖ import djangoで確認
❖ コマンドラインからdjango-adminが使えるようになる
新しいプロジェクトを作る❖ コマンドラインで実行する
❖ django-admin startproject django_project
❖ [Demo]
❖ django_projectというディレクトリが出来て、中にいろいろ入ってる
❖ トップレベルの名前は変更可能
❖ manage.pyを使って新しいアプリを作る
❖ ./manage.py startapps myweb
ProjectとApplication
Project
App0 App1 App2
ApplicationはPythonのパッケージと同じディレクトリ構成うまく設計すればいろいろなProjectで使い回せる
ディレクトリ構成
Application(myweb)のディレクトリ
django_project設定用のディレクトリ
管理用スクリプトファイル
[Demo] Hello World
❖ myweb/views.py❖ 実行される関数を作る
❖ myweb/urls.py
❖ URLと関数を結びつける
❖ 「最初だけ」プロジェクトのurls.pyに追加
from django.http import HttpResponse
def index(request): return HttpResponse('こんにちはー')
from django.conf.urls import urlfrom . import views
urlpatterns = [ url(r'^$', views.index, name='index'),]
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^myweb/', include('myweb.urls')),]
01_hello_world.tar
データベースとの接続
SQLite3を使う
❖ 最初から設定されている
❖ django_project/settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }}
models.py❖ 出版社を表現するクラス(Publisher)を作る
❖ 「最初だけ」django_project/settings.py
❖ アプリを追加
from django.db import models
class Publisher(models.Model): name = models.CharField(max_length=200, help_text='出版社名') info = models.CharField(max_length=200, default='', blank=True, help_text='備考') c_date = models.DateField(auto_now=True, help_text='最終更新日')
INSTALLED_APPS = [ 'myweb.apps.MywebConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles',]
変更を反映する❖ [Demo]
❖ ./manage.py makemigrations❖ 変更を検出して準備
❖ ./manage.py migrate❖ 実際に反映
sqlite> .schema myweb_publisherCREATE TABLE "myweb_publisher" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(200) NOT NULL, "info" varchar(200) NOT NULL, "c_date" date NOT NULL);
02_models.tar
管理画面の威力
Django管理者の作成❖ ./manage.py createsuperuser
❖ django_project/settings.py
❖ LANGUAGE_CODE = ‘ja-jp'❖ 管理画面の日本語化
❖ [Demo] http://localhost:8000/admin/
Modelの追加❖ myweb/admin.pyを編集
❖ [Demo] 管理画面にモデルの編集画面が出来る
from django.contrib import adminfrom .models import *
admin.site.register(Publisher)
[Demo] 03_admin_model.tar
モデルの編集画面を作る
テンプレートの準備❖ myweb/templatesディレクトリを作る
❖ publisher.htmlを作成
❖ このテンプレートを呼ぶ関数を作る
❖ myweb/urls.pyに追加
<!DOCTYPE html><html> <head> <title>出版社</title> </head> <body> <h1>出版社</h1> </body></html>
from django.shortcuts import render
def publisher(request): if request.method == 'GET': return render(request, 'publisher.html', {})
[Demo] 04_templates_test.tar
モデルの編集フォーム❖ myweb/views.pyを改造してモデルの編集フォームを作る
❖ テンプレートを変更
05_modelform.tar
from django import formsfrom .models import *
def publisher(request): if request.method == 'GET': form = forms.modelform_factory(Publisher, fields=['name', 'info']) return render(request, 'publisher.html', {'form': form})
<!DOCTYPE html><html> <head> <title>出版社</title> </head> <body> <h1>出版社</h1> <form method="POST"> {% csrf_token %} {{ form.as_p }} <input type="submit"> </form> </body></html>
データの書き込み❖ myweb/views.pyを編集
❖ is_valid()が秀逸
def publisher(request): form = forms.modelform_factory(Publisher, fields=['name', 'info'])
if request.method == 'GET': return render(request, 'publisher.html', {'form': form})
publisher = form(request.POST)
if publisher.is_valid(): publisher.save()
return render(request, 'publisher.html', {'form': publisher})
06_savemodel.tar
Relationを作る
models.Book
いろは出版社
お酒の本レシピ本 占い本
class Book(models.Model): name = models.CharField(max_length=200, help_text='題名') author = models.CharField(max_length=200, help_text='著者') publisher = models.ForeignKey(Publisher, help_text='出版社')
管理画面に出るように、myweb/admin.pyにも追加
modelの表現❖ オブジェクトを文字列にするときの挙動を決める
__str__メソッドを書くclass Publisher(models.Model): name = models.CharField(max_length=200, help_text='出版社名') info = models.CharField(max_length=200, default='', blank=True, help_text='備考') c_date = models.DateField(auto_now=True, help_text='最終更新日')
def __str__(self): return self.name
class Book(models.Model): name = models.CharField(max_length=200, help_text='題名') author = models.CharField(max_length=200, help_text='著者') publisher = models.ForeignKey(Publisher, help_text='出版社')
def __str__(self): return '{} 「{}」'.format(self.name, self.publisher)
07_book
検索
本の検索システムを作る
json形式データを返す
SearchFormクラスfrom django import forms
class SearchForm(forms.Form): keyword = forms.CharField(label='キーワード
<!DOCTYPE html><html> <head> <title>検索</title> </head> <body> <h1>本の検索</h1> <form method="POST"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="検索"> </form> </body></html>
myweb/models.pyforms.pyなどとしてOK
myweb/templates/search.html
オブジェクトの検索
queryset = Book.objects.filter(name__contains='keyword')
SELECT ... WHERE name LIKE '%keyword%';
model→辞書→jsonfrom django.forms.models import model_to_dictimport json
dic = model_to_dict(book, ['name', ‘publisher'])
json.dumps(dic)
{'publisher': 2, 'name': 'Pythonプログラミング'}
views.search
def search(request): if request.method == 'POST': form = SearchForm(request.POST) if form.is_valid(): _keyword = form.cleaned_data['keyword'] queryset = Book.objects.filter(name__contains=_keyword) temp = [] for v in queryset: dic = model_to_dict(v, ['name', 'publisher']) temp.append(dic) return HttpResponse(json.dumps(temp)) # GETの時 return render(request, 'search.html', {'form': SearchForm()})
08_search
まとめ❖ PythonにはWebアプリ関連の豊富な標準モジュールがある
❖ WSGIという標準仕様があり、これに準拠したWebアプリ開発が可能
❖ Webフレームワークには沢山の種類があるが特色もある
❖ Djangoはとっても便利
❖ (結論) PythonはWebアプリ開発に適した言語
ありがとうございました。