404 ?
HTTP Status Code
HTTP is 仕様
• クライアントはこういうリクエストを送れ
• サーバはこういうレスポンスを返せ
要求
応答
HTTP Status Code
• 3桁の数字がサーバでの結果を示している
• 200 -> 「あるから送るわ(`・ω・́)」
• 404 -> 「そんなものない(́・ω・`)」
• 503 -> 「悪い俺今日体調悪いわ (́
☓
ω☓
`)」GAEでは対応を明示しなければ
「存在しない」
import webbapp2
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world!') app = webapp2.WSGIApplication([
('/', MainHandler) ], debug=True)
• http://ti-hello.appspot.com/example -> 不在
いつでも”Hello World”
を表示させたい
• 「正規表現」で/exampleも受け入れるようにする例
import webbapp2
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world!') app = webapp2.WSGIApplication([
(‘/.*’, MainHandler) ], debug=True)
正規表現?
(#́・ω・`#)
注: プログラミングについて勉強すると おそらくWebサーバ云々よりも前に
「正規表現」という言葉が先に登場します。
原稿執筆時点ではこのあたりの重要性を 見落としてました。サーセン
正規表現
• 「こういう感じの文字列じゃない?」と
プログラムに聞ける仕組み
• さっきの例: ʼ
/.*
ʼ• 「スラッシュで始まり」
• 「何か文字が」「続くかもしれない」
「続かなければならない」
は 「+」
正規表現は定番ツール
• プログラミングでよく使う
• 文字列の一部をルールに基づいて抽出する
• テキストファイル、ログファイル、HTML……
• GAEはPythonの正規表現エンジンを使っただけ
/path1/path2 …
• フォルダと仕組みは概ね同じ
• フォルダ構造 = 「木」構造
• 木の枝先に「資源」がある
注: 本授業では正直
余計なスライドだった気がします。
資源の構造が木である、というのは 割と重要なんですが……
Webサーバ
• HTTPというプロトコルを介して
• フォルダ構造(木構造)になってるリソースを
• クライアントとやりとりする、サーバ
• GET … ください
• POST … あげます
• ↑ 主語はクライアント側 (Android, ブラウザ)
資源 resource
デモ: 締め切りを抜き取る
注: PythonとRubyを用いて
Tech Instituteのトップページから 締め切りに関する<span>タグ内の
中身を取り出しました。
(次スライド)
授業で使用したスクリプト
import urllib import re
r = re.compile('<span style="color:red;">(.*)</span>')
m = r.search(urllib.urlopen(‘http://techinstitute.jp/').read()) print m.group(1)
結果:
<big>東京、大阪 ともに 第2期受講 11月12日(水) 〆切迫る!!</big>
このデモ数日後、
文字列が書き換わったことを 確認しました( ー̀дー́)キリッ
正規表現だけで授業できる
• 例: メールアドレスかどうかを「ラフに」チェック
•
“^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]
+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}
[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$”
• これでも実は全然ちゃんとチェックできてない
• 学んどくとじわじわ便利です
これ以上は割愛
いつでも”Hello World”
を表示
• http://ti-hello.appspot.com/example もOK
import webbapp2
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world!') app = webapp2.WSGIApplication([
(‘/.*’, MainHandler) ], debug=True)
バグってると、
503はGAEが出す
• 「503 悪い俺今日体調悪いわ (́
☓
ω☓
`)」 by GAEimport webbapp2
class MainHandler(webapp2.RequestHandler):
def get(self):
突然のコメントでも何でもない日本語 app = webapp2.WSGIApplication([
(‘/.*’, MainHandler) ], debug=True)
注: 状況によっては出ないこともあるようです……
本質的な部分は あとひとつあった
import webbapp2
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world!') app = webapp2.WSGIApplication([
('/', MainHandler) ], debug=True)
理解してほしいポイント
import webbapp2
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world!') app = webapp2.WSGIApplication([
('/', MainHandler) ], debug=True)
HTTP GETを実装している
• 第14章「ネットワークプログラミング」で登場
• Android側 -> GETリクエストを送る側
• 第14章はこっち
• サーバ -> GETレスポンスを返す側
• 今回はこっち
HTTPには
リクエストが数種類ある
• 今回は(第2,3回含めて)GETとPOSTだけ扱う
• GET … データ取る
• POST …… データ送る
• 他にもあるし使うこともある。
• 「Ruby on Rails」など別の仕組みだと見るかも
ホスト名についての処理は GAEがやってくれている
• http://ti-hello.appspot.com/example
import webbapp2
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello world!') app = webapp2.WSGIApplication([
(‘/.*’, MainHandler) ], debug=True)
Google AppEngine
Google AppEngine
• GAEではそれぞれに関数(メソッド)を割り当てる
• GET -> get(), POST -> post()
• ヘンなもんが来たらGAEが対処する
• その他の環境では自力で実装する必要があるかも
仕様と実装
• GAEという特定技術についての知識は
今回はそれほど重要ではない
• 状況によって変わるから
• GAEはプロトコルをプログラムの皮に
上手く包み込んでいる
• ここまでOSのコマンドは出て来なかった!
• パッケージをインストールもしなかった!
技術要素は分けて理解する
• 言い方を変えると: 何が使いまわせる?
• HTTPの仕様は存在し公開されている。GAEは否。
• そうでないものには痛い未来があるかもしれない……
• GAEがなくならないか心配
• Pythonはオープンだから、まだ大丈夫
• ……2020年にどうなるかな??
デモ
HTTPの仕様(RFC)を 眺めてみる
注: 正直、ここは尻切れトンボでした