Web周りのライブラリについておさらいしています。
その他のおさらい事項にについては、以下ご参照ください。
[ざっくりPythonのおさらい その1。基本文法など]
https://qiita.com/48hands/items/31b7ac2b49addbb8658c
[ざっくりPythonのおさらい その2。おもにデータ保存]
https://qiita.com/48hands/items/ab86b7463268e669d216
[ざっくりPythonのおさらい その3。Numpy, Pandas]
https://qiita.com/48hands/items/b1a71000533e129b27f2
勉強に使っている教材は、酒井潤さんがUdemyで提供しているこちらの講座です。
Pythonに入門するときに一度通しで勉強したのですが、入門書として私の中ではベストでした。
[講座名]
Python3入門 + 応用 + アメリカのシリコンバレー流コードスタイルを学び、実践的なアプリ開発の準備をする
https://www.udemy.com/python-beginner/
入門〜応用までかなり幅広く網羅しているので、市販で売ってる入門書籍よりも個人的にかなりおすすめです。
一方で他言語を学んでいない初心者には中半〜後半は難しいかもしれません。
説明は非常にわかりやすいです。
今回は酒井先生の講義の丸パクリになってしまいました。
Web
HTTPリクエスト
Webに対してのリクエストサードパーティのrequests
ライブラリがいい感じとのこと。
import requests
で利用する。
GET
import requests
# URLストリングパラメータ
# 以下と同様
# http://httpbin.org/get?key1=value1&key2=value2
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('http://httpbin.org/get', params=payload, timeout=1)
print(r.status_code)
print(r.headers)
print(r.json())
POST
import requests
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.post('http://httpbin.org/post', data=payload, timeout=1)
print(r.status_code)
print(r.headers)
print(r.json())
PUT
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.put('http://httpbin.org/put', data=payload, timeout=1)
print(r.status_code)
print(r.headers)
print(r.json())
DELETE
import requests
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.delete('http://httpbin.org/delete', data=payload)
print(r.status_code)
print(r.headers)
print(r.json())
ソケット通信
TCPソケット通信
サーバ側
import socket
# TCPソケット通信
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('127.0.0.1', 50000)) # 50000番ポートで待受ける
s.listen(1) # コネクション数を1に設定している
while True:
# クライアントが接続してきたらconn,addrを取得する
conn, addr = s.accept()
with conn:
while True:
# チャンクサイズを1024byteにしている
data = conn.recv(1024)
# データがなくなったら
if not data:
break
# 受け取ったデータとアドレスアドレス情報を表示
print('data: {}, addr: {}'.format(data, addr))
# クライアントにデータを送信している
conn.sendall(b'Received: ' + data)
クライアント側
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
# サーバに接続
s.connect(('127.0.0.1', 50000))
# メッセージを送信
s.sendall(b'Hello')
# サーバからメッセージを受信
data = s.recv(1024)
print(repr(data))
UDPソケット通信
サーバ側
import socket
# socket.SOCK_DGRAMを使う
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.bind(('127.0.0.1', 50000))
while True:
data, addr = s.recvfrom(1024)
print('data: {}, addr: {}'.format(data, addr))
クライアント側
import socket
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.sendto(b'Hello by UDP', ('127.0.0.1', 50000))
Flask
軽量Webフレームワーク。
簡単なAPIを作るときに向いてそうです。
驚くほど簡単。
超基本
from flask import Flask
from flask import g
from flask import render_template
from flask import request
from flask import Response
# グローバルでファイル名を指定している
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello world!'
@app.route('/goodbye')
def goodbye_world():
return 'good-bye world!'
def main():
app.debug = True
app.run(host='localhost', port=5000)
if __name__ == '__main__':
main()
起動方法は以下。
export FLASK_APP=main_app.py
flask run
これだけで、以下のURLにGETメソッドでアクセスして表示までできる。
テンプレート
Rubyのerbみたいなテンプレートにも対応している。
テンプレートファイルtemplate/hello.html
を作成する。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
{% if username %}
Hello {{ username }}
{% else %}
Hello
{% endif %}
</body>
</html>
/hello/username
、もしくは/hello
にアクセスしたときのルーティングを定義する。
from flask import Flask
from flask import g
from flask import render_template
from flask import request
from flask import Response
app = Flask(__name__)
@app.route('/hello')
@app.route('/hello/<username>')
def hello_user(username=None):
# return 'Hello {}'.format(username)
return render_template('hello.html', username=username)
def main():
app.debug = True
app.run(host='localhost', port=5000)
if __name__ == '__main__':
main()
Method
from flask import Flask
from flask import g
from flask import render_template
from flask import request
from flask import Response
app = Flask(__name__)
# GET, POST, DELETE, PUTを受け付けるようにしている
# methodsにリストで渡すだけでいい。
@app.route('/hoge', methods=['GET', 'POST', 'DELETE', 'PUT'])
def show_hoge():
# リクエストで受け取ったusernameリターン
return str(request.values['username'])
def main():
app.debug = True
app.run(host='localhost', port=5000)
if __name__ == '__main__':
main()
試しに、以下のコードを実行する。
import requests
r1 = requests.get(
'http://localhost:5000/hoge', params={'username': 'Makio'}
)
print(r1.text)
r2 = requests.post(
'http://localhost:5000/hoge', data={'username': 'Hanako'}
)
print(r2.text)
r3 = requests.put(
'http://localhost:5000/hoge', data={'username': 'Satoshi'}
)
print(r3.text)
r4 = requests.delete(
'http://localhost:5000/hoge', data={'username': 'Taro'}
)
print(r4.text)
実行結果
Makio
Hanako
Satoshi
Taro
DB接続
DB接続のFlaskアプリコード
import sqlite3
from flask import Flask
from flask import g
from flask import render_template
from flask import request
from flask import Response
app = Flask(__name__)
# DBのコネクションを取得するメソッド
# g._databaseでグローバルな変数としてセットしているのだと思われる
def get_db():
db = getattr(g, '_database', None) # g._databaseを呼び出している?
if db is None:
db = g._database = sqlite3.connect('dev_sqlite.db')
return db
# アプリケーションが終了したらクローズする
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.close()
@app.route('/employee', methods=['POST', 'PUT', 'DELETE'])
@app.route('/employee/<name>', methods=['GET'])
def employee(name=None):
db = get_db()
curs = db.cursor()
curs.execute('CREATE TABLE IF NOT EXISTS persons('
'id INTEGER PRIMARY KEY AUTOINCREMENT,'
'name STRING)')
db.commit()
name = request.values.get('name', name)
if request.method == 'GET':
curs.execute('SELECT * FROM persons WHERE name = "{}"'.format(name))
person = curs.fetchone()
if not person:
return "No", 404
user_id, name = person
return '{}: {}'.format(user_id, name), 200
if request.method == 'POST':
curs.execute('INSERT INTO persons(name) values("{}")'.format(name))
db.commit()
return 'created {}'.format(name), 201
if request.method == 'PUT':
new_name = request.values['new_name']
curs.execute(
'UPDATE persons set name = "{}" WHERE name = "{}"'.format(new_name,
name))
db.commit()
return 'updated {}: {}'.format(name, new_name), 200
if request.method == 'DELETE':
curs.execute('DELETE FROM persons WHERE name = "{}"'.format(name))
db.commit()
return 'deleted {}'.format(name), 200
# GET, POST, DELETE, PUTを受け付けるようにしている
@app.route('/hoge', methods=['GET', 'POST', 'DELETE', 'PUT'])
def show_hoge():
# リクエストで受け取ったusernameリターン
return str(request.values['username'])
def main():
app.debug = True
app.run(host='localhost', port=5000)
if __name__ == '__main__':
main()
接続確認用のコード
import requests
# GETリクエスト
r_get = requests.get('http://localhost:5000/employee/taro')
print(r_get.text)
# POSTリクエスト
r_post = requests.post('http://localhost:5000/employee',
data={'name': 'taro'})
print(r_post.text)
r_get = requests.get('http://localhost:5000/employee/taro')
print(r_get.text)
# PUTリクエスト
r_put = requests.put('http://localhost:5000/employee',
data={'name': 'taro', 'new_name': 'makio'})
print(r_put.text)
r_get = requests.get('http://localhost:5000/employee/makio')
print(r_get.text)
実行結果
No
created taro
2: taro
updated taro: makio
2: makio
deleted makio
No
業務都合上、Flaskを使うにしても大した用途で使う気がしないので、この程度にしておいてあとはドキュメント見ながら必要に応じて使って行く感じでいいかなと..
簡単な事がわかったので御の字。
時間があるときにでも追記していきます。