flask JSONを返却する

jsonifyを使用する

from flask import Flask, render_template, request, jsonify

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
app.config['JSON_SORT_KEYS'] = False

@app.route('/hello')
def hello():
	data = [
		{"name": "山田"},
		{"age": 30}
	]
	return jsonify({
			'status' : 'OK',
			'data' : data
		})

if __name__ == "__main__":
	app.run(debug=True, host='192.168.56.10', port=8000)

flask formからPOST

formを受け取る側はmethodsを指定する必要あり

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/form')
def form(name=None):
	return render_template('post.html')

@app.route('/hello', methods=["POST"])
def hello():
	if request.method == 'POST':
		name = request.form['name']
	else:
		name = 'no name.'

	return render_template('hello.html', title='flask test', name=name)

if __name__ == "__main__":
	app.run(debug=True, host='192.168.56.10', port=8000)

queryをgetで取得する場合
=> request.args.getで取得する
http://192.168.56.10:8000/hello?name=yoko

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/hello')
def hello():
	name = request.args.get('name')

	return render_template('hello.html', title='flask test', name=name)

if __name__ == "__main__":
	app.run(debug=True, host='192.168.56.10', port=8000)

flask パラメータとルーティング

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/hello/<name>')
def hello(name=None):

	return render_template('hello.html', title='flask test', name=name)

if __name__ == "__main__":
	app.run(debug=True, host='192.168.56.10', port=8000)

flask データベース利用

MySQLにデータが入っています
mysql> select * from users;
+——–+———————-+
| number | name |
+——–+———————-+
| 2 | Achraf Hakimi |
| 4 | Manuel Ugarte |
| 5 | Marquinhos |
| 7 | Kylian Mbappé |
| 8 | Fabián Ruiz |
| 10 | Neymar |
| 11 | Marco Asensio |
| 14 | Juan Bernat |
| 18 | Renato Sanches |
| 99 | Gianluigi Donnarumma |
+——–+———————-+
10 rows in set (0.00 sec)

$ pip3 install PyMySQL

hello.py

from flask import Flask, render_template
import pymysql

app = Flask(__name__)

@app.route('/')
def hello():

	db = pymysql.connect(
			host='localhost',
			user='hoge',
			password='fuga',
			db='test',
			charset='utf8',
			cursorclass=pymysql.cursors.DictCursor,
		)
	cur = db.cursor()
	sql = "select * from users"
	cur.execute(sql)
	users = cur.fetchall()

	cur.close()
	db.close()

	return render_template('hello.html', title='flask test', users=users)

if __name__ == "__main__":
	app.run(debug=True, host='192.168.56.10', port=8000)

templates/hello.html

{% extends "layout.html" %}
{% block content %}
<h3>一覧</h3>
<ul>
{% for user in users %}
	<li>{{ user.number }} : {{ user.name }}</li>
{% endfor %}
</ul>
{% endblock %}

flask テンプレートの利用

templates/layout.html

<!doctype html>
<html>
<head>
	<title>{{ title }}</title>
</head>
<body>
	{% block content %}
	{% endblock %}
</body>
</html>

templates/hello.html

{% extends "layout.html" %}
{% block content %}
<h3></h3>
こんにちは。{{ name }}さん。
{% endblock %}

hello.py

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def hello():
	name = "Hoge"
	return render_template('hello.html', title='flask test', name=name)

if __name__ == "__main__":
	app.run(debug=True, host='192.168.56.10', port=8000)

【Blockchain】トランザクションへの電子署名の実装

import pandas as pd
import datetime
from ecdsa import SigningKey, SECP256k1
import binascii
import json

secret_key_A_str = "47c5c280197c691be3f80462b72d60b7b2915753f1a81a6eedbfbb2f01f55cae"
public_key_B_str = "02cfbf50fe5873ac6e5352e7524c4934e32f01281fc7d6112fed86cf58e72b09bb302f1f7d10d7c37d13eb7e62fd8bb1950b263c51ac76581f8b0a38d0d8853e"

secret_key_A = SigningKey.from_string(binascii.unhexlify(secret_key_A_str), curve=SECP256k1)
public_key_A = secret_key_A.verifying_key
public_key_A_str = public_key_A.to_string().hex()
time_now = datetime.datetime.now(datetime.timezone.utc).isoformat()

unsigned_transaction = {"time": time_now, "sender": public_key_A_str, "receiver": public_key_B_str, "amount": 3}
signature = secret_key_A.sign(json.dumps(unsigned_transaction).encode('utf-8'))
transaction = {"time": time_now, "sender": public_key_A_str, "receiver": public_key_B_str, "amount": 3, "signature": signature.hex()}

pd.to_pickle(transaction, "signed_transaction.pkl")

取引記録の検証

import pandas as pd
from ecdsa import VerifyingKey, BadSignatureError, SECP256k1
import binascii
import json

transaction = pd.read_pickle("signed_transaction.pkl")
public_key_A = VerifyingKey.from_string(binascii.unhexlify(transaction["sender"]), curve=SECP256k1)
signature = binascii.unhexlify(transaction["signature"])

unsigned_transaction = {
	"time": transaction["time"],
	"sender": transaction["sender"],
	"receiver": transaction["receiver"],
	"amount": transaction["amount"]
}

try:
	public_key_A.verify(signature, json.dumps(unsigned_transaction).encode('utf-8'))
	print("トランザクションは改竄されていません。")
except BadSignatureError:
	print("トランザクションは改竄されています。")

$ python3 verify_transaction.py
トランザクションは改竄されていません。

cheat.py

import pandas as pd

transaction = pd.read_pickle("signed_transaction.pkl")
print("改竄前のトランザクション:")
print(transaction)

transaction = {"time": transaction["time"], "sender": transaction["sender"], "receiver": transaction["receiver"], "amount": 30, "signature": transaction["signature"]}
print("改竄後のトランザクション:")
print(transaction)
pd.to_pickle(transaction, "signed_transaction.pkl")

改竄するとsignatureが変更されていないので、改竄されていることがわかる

【Python】Blockchainの電子署名

電子署名を行うために、ecdsaをインストール
$ pip3 install ecdsa

from ecdsa import SigningKey, BadSignatureError, SECP256k1

secret_key = SigningKey.generate(curve = SECP256k1)
print("秘密鍵:" + secret_key.to_string().hex())
public_key = secret_key.verifying_key
print("公開鍵:" + public_key.to_string().hex())

doc = "これは送信したい文章です。"
signature = secret_key.sign(doc.encode('utf-8'))
print("電子署名" + signature.hex())

try:
	public_key.verify(signature, doc.encode('utf-8'))
	print("文章は改竄されていません。")
except BadSignatureError:
	print("文章が改竄されています")

SECP256k1は楕円曲線
電子署名は元の文章から作成されたか否かの判別を行う

秘密鍵:47c5c280197c691be3f80462b72d60b7b2915753f1a81a6eedbfbb2f01f55cae
公開鍵:02cfbf50fe5873ac6e5352e7524c4934e32f01281fc7d6112fed86cf58e72b09bb302f1f7d10d7c37d13eb7e62fd8bb1950b263c51ac76581f8b0a38d0d8853e
電子署名d17955d7f850edf05dde3e363a23dd0452420ec351dccd203f15479970a011c3dcb60b5629a33a7846727d9041e1b6d7be796b909b8ba803c490ace73a1c18e4
文章は改竄されていません。

Blockchainのトランザクション

transaction1 = {“time”: “”, “sender”: “C”, “receiver”: “D”, “amount”: 1}

トランザクションの作成

import datetime

time_now = datetime.datetime.now(datetime.timezone.utc).isoformat()
transaction1 = {"time": time_now, "sender": "C", "receiver": "D", "amount": 1}

time_now = datetime.datetime.now(datetime.timezone.utc).isoformat()
transaction2 = {"time": time_now, "sender": "D", "receiver": "E", "amount": 3}

transactions = [transaction1, transaction2]
print(transactions)

$ python3 transaction.py
[{‘time’: ‘2023-09-23T06:31:46.973357+00:00’, ‘sender’: ‘C’, ‘receiver’: ‘D’, ‘amount’: 1}, {‘time’: ‘2023-09-23T06:31:46.973375+00:00’, ‘sender’: ‘D’, ‘receiver’: ‘E’, ‘amount’: 3}]

ubuntuにflutterをインストールでデプロイ

Flutter公式のインストールページを参考に、snapでflutterをインストールします。
https://docs.flutter.dev/get-started/install/linux

$ sudo snap install flutter –classic
$ flutter sdk-path

続いてflutterで開発したgithubのソースコードをリポジトリからcloneします。
$ git clone https://github.com/hpscript/flutter_test.git
$ cd flutter_test

$ flutter build web
あれ、githubのものをサーバ上でbuildするのではないの?
それとも、開発環境でbuildしたものをpushしてデプロイするのか?

.gitignoreでbuildをコメントアウトしてpush, pullしてサーバに置くとbuild/webをドキュメントルートとして表示できるようになる。

**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
#/build/

なるほど、flutterのデプロイについては何となく理解した。
dartで書いて、buildすれば良いのね。 良く出来ているわ。

nginxのドキュメントルート

nginxのドキュメントルート
/usr/share/nginx/html

almalinux8.8を使って、var/www/htmlがなかったので焦りました…
$ ls
adm crash empty games kerberos local log nis preserve spool yp
cache db ftp gopher lib lock mail opt run tmp