FastAPI
前回、Pythonで画像データをbase64形式に変換する方法を紹介しました。
今回はFastAPIで画像データをJavaScriptに送り、HTMLで表示する方法を紹介します。
今回、重要なのは
- FastAPIで画像データをbase64形式にして送る
- JavaScriptでbase64形式のデータを受け取り、デコードする
- FastAPIでCORSを設定し、外部からのアクセスに対してレスポンスできるようにする
という3点です。
最初の2点は前回からの続きなので分かりやすいですが、3はセキュリティーの話で、私もまだよく分かっていないので、とりあえず使えるようにだけするレベルで解説していきます。
それでは始めていきましょう。
FastAPIでbase64形式のデータを送信
まずはFastAPIで画像データをbase64形式のデータに変換し、送信する部分です。
前回同様、3PySciのロゴ(3pysci_logo.png)を使って解説していきます。
そしてほぼ前回のおさらいになります。
from fastapi import FastAPI
import base64
app = FastAPI()
@app.get("/")
def test10():
with open("3pysci_logo.png", "rb") as img:
base64_data = base64.b64encode(img.read()).decode('utf-8')
return {"img":base64_data}
とりあえずエンドボインとをURL直下(”/”)に作成し、アクセスされたら同じフォルダの「3pysci_logo.png」の画像をbase64形式に変換したのち、UTF-8形式にしてJSON形式で返しています。
ターミナル上で「uvicorn main:app –reload」でサーバーを起動し、「http://127.0.0.1:8000」にアクセスしてみるとこんな感じで大量の文字が表示されます。
これでFastAPI側の準備は「とりあえず」は完成です。
JavaScriptでbase64形式のデータを受け取りデコード
次にJavaScriptでbase64形式のデータを受け取りデコードします。
HTML全体としてはこんな感じ。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
async function callApi() {
const res = await fetch('http://127.0.0.1:8000')
.then(result => result.json())
.then((output) => {
document.write('<img src="data:image/png;base64,'+ output["img"]+'" alt="Bare">')
}).catch(err => console.error(err));
};
callApi();
</script>
</body>
</html>
JavaScriptはまだまだ勉強不足で、色々なサイトから寄せ集めて作っているため細かい部分は分かりません。
重要な点としては
- fetchを使って、FastAPIにアクセスする
- 得られた値をJSONとして読み込み、「<img scr=”data:imaga/png:base64, {base64形式のデータ}” alt=”Bare>”」としてHTMLに出力する
という2点です。
HTMLが準備できたら、先ほど同様ターミナル上で「uvicorn main:app –reload」でサーバーを起動したのち、作成したHTMLを開きます。
しかし3PySciのロゴ画像は表示されません。
コンソールを見てみるとこんな感じのエラーが出ています。
「Origin http://127:0.0.1:5555 is not allowed by Access-Control-Allow-Origin. Status code: 200」というのが最初に少しお話しした外部からのアクセスを制限しているセキュリティーによりFastAPIにアクセスできなかったことを示しています。
そのためFastAPI側でアクセスできるようにCORSという設定を追加してあげる必要があります。
FastAPIにおけるCORSの設定
CORSの設定はセキュリティーの設定になるため、実際の運用に関してはちゃんと勉強して、間違いなく設定するのをオススメしますが、とりあえず今回はローカルで動けばいいというレベルでの設定を行います。
またここでの解説も間違っている可能性は多々ありますので、公式サイトや他のサイトを見て勉強されることをオススメします。
CORSとはオリジン間リソース共有(Cross-Origin Resource Sharing)と呼ばれ、今回の場合、FastAPIが起動しているURLとJavaScript(HTML)が設置してあるURLが異なる場合、JavaScriptからのリクエストに対し、FastAPIがレスポンスを返せるように設定する項目になります。
つまりCORSを設定していない場合はFastAPIに対し、外部からのリクエストは処理されないということです。
ということでFastAPIにCORSを設定し、外部からのリクエストに対し、処理を返せるようにしてみましょう。
from fastapi import FastAPI
import base64
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/")
def test12():
with open("3pysci_logo.png", "rb") as img:
base64_data = base64.b64encode(img.read()).decode('utf-8')
return {"img":base64_data}
追加したのは「from fastapi.middleware.cors import CORSMiddleware」でCORSMiddlewareのインポートと下記の「app.add_middleware()」の部分です。
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
ここでとりあえず重要なのが「allow_origins = [“*”]」の部分です。
ここではこのFastAPIプログラムを実行できるアクセス元のURLをリスト形式で設定できます。
上記の例では「[“*”]」となっており、どんなアクセス元であったとしてもこのFastAPIを使用することができるようになっています。
もし特定のウェブサイトからのリクエストのみ処理させたい場合はここにURLを記載すれば良いということです。
これで「uvicorn main:app –reload」でサーバーを起動したのち、作成したHTMLを開くと無事3PySciのロゴが表示されました。
ということでまだまだ勉強不足であやふやな部分は多々ありますが、FasstAPIからJavaScriptに画像データを送り、HTML上に表示することができました。
次回はさらにMatplotlibで作成した画像データをサーバー上に保存せずにJavaScriptに送る方法を解説していきます。
ではでは今回はこんな感じで。
コメント