Express、FastAPIを使用し、二重fetch構成のメリット
更新日:2025/03/09

基本用語解説
FastAPI
FastAPI は現代的な高性能な Python ウェブフレームワークです。
pip
pip は Python のパッケージ管理ツールです。Python で書かれたソフトウェアパッケージ(ライブラリ)をインストール・管理するためのコマンドラインツールです。
Node.jsの世界に慣れていれば、requirements.txt は package.json の dependencies セクションだけを取り出したようなもの、と考えるとわかりやすいでしょう。
構成ファイル
大枠のフローとして「フロントエンドから直接FastAPIへアクセスするのではなく、Expressサーバーを経由して、API連携します」
Expressフレームワークを使用
Expressでフロントエンド処理とFastAPI中継(ローカルにNode.jsインストール済み)
1. クライアント側 (index.html)
│
├── 画像ファイル選択
│ └── <input type="file">で画像を選択
│
├── フォーム送信
│ └── FormDataオブジェクトを作成
│
└── APIリクエスト送信
└── fetch('http://localhost:3000/fastapi')
2. Express サーバー (server.js - Port:3000)
│
├── 静的ファイル配信
│ └── index.htmlの提供
│
├── ファイル受信
│ └── multerによるファイル処理
│
└── FastAPIへ転送
└── fetch('http://localhost:8000/ocr')
3. FastAPI サーバー (main.py - Port:8000)
│
├── CORS処理
│ └── クロスオリジンリクエストの許可
│
├── OCR処理
│ └── 画像からテキスト抽出
│
└── レスポンス返却
└── JSON形式で結果を返却
4. データの戻り
│
├── FastAPI → Express
│ └── OCR結果のJSON
│
├── Express → クライアント
│ └── JSONデータの転送
│
└── クライアント表示
└── 結果をHTML上に表示
Express/
├── server.js # Express サーバー(ポート3000)
├── index.html # フロントエンドのメインページ
├── main.py # FastAPI サーバー(ポート8000)
├── package.json # npm パッケージ設定
├── package-lock.json # npm パッケージのバージョン固定
└── node_modules/ # npm パッケージのインストール先
├── express/
├── cors/
├── multer/
├── node-fetch/
├── form-data/
└── ...
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FastAPIにPOSTリクエスト</title>
<style>
.result-area {
margin-top: 20px;
padding: 10px;
border: 1px solid #ccc;
min-height: 100px;
}
</style>
</head>
<body>
<h1>画像からテキストを抽出</h1>
<form id="ocr-form">
<div>
<label for="image-file">画像ファイル:</label>
<!-- accept="imgage/*"とは -->
<input type="file" id="image-file" accept="image/*" required>
</div>
<div style="margin-top: 10px;">
<button type="submit">テキスト抽出</button>
</div>
</form>
<div class="result-area" id="result">
<p>抽出結果がここに表示されます...</p>
</div>
<script>
// 送信ボタンクリック時の処理
document.getElementById('ocr-form').addEventListener('submit', async function(e) {
e.preventDefault(); // デフォルトの動作を防止
const fileInput = document.getElementById('image-file');
const resultDiv = document.getElementById('result');
if (!fileInput.files.length) {
resultDiv.innerHTML = '<p>ファイルを選択してください</p>';
return;
}
const file = fileInput.files[0];
const formData = new FormData();
formData.append('file', file);
resultDiv.innerHTML = '<p>処理中...</p>';
try {
const response = await fetch('http://localhost:3000/fastapi', {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error('APIリクエストに失敗しました');
}
const data = await response.json();
resultDiv.innerHTML = `<p>抽出されたテキスト:</p><pre>${data.extracted_text}</pre>`;
} catch (error) {
resultDiv.innerHTML = `<p>エラー: ${error.message}</p>`;
console.error('Error:', error);
}
});
</script>
</body>
</html>
server.js
import express from 'express';
import multer from 'multer';
import fetch from 'node-fetch';
const app = express();
// 静的ファイルの配信設定
app.use(express.static('.'));
// アップロードされたファイルをメモリに保存
const upload = multer({ storage: multer.memoryStorage() });
// FastAPIエンドポイント
app.post('/fastapi', upload.single('file'), async (req, res) => {
try {
if (!req.file) {
return res.status(400).json({ error: 'ファイルがアップロードされていません' });
}
// Blobを使用してFormDataを作成
const formData = new FormData();
const blob = new Blob([req.file.buffer], { type: req.file.mimetype });
formData.append('file', blob, req.file.originalname);
const response = await fetch('http://localhost:8000/express-fastapi', {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error('FastAPIサーバーでエラーが発生しました');
}
const data = await response.json();
res.json(data);
} catch (error) {
console.error('エラー:', error);
res.status(500).json({ error: 'リクエスト処理中にエラーが発生しました' });
}
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`サーバーが起動しました: http://localhost:${PORT}`);
});
FastApi
テストで確認用にシンプルな構成
python未インストールでDocker開発しました
プロジェクトルート/
├── app/
│ ├── __pycache__/ # Pythonのコンパイル済みファイル(自動生成)
│ │ └── *.pyc
│ └── main.py # FastAPIのメインアプリケーションファイル
│
├── .dockerignore # Dockerビルド時に除外するファイルの設定
├── Dockerfile # Dockerイメージのビルド設定
└── requirements.txt # Pythonパッケージの依存関係リスト
Dockerfile
# Pythonの公式イメージをベースとして使用
FROM python:3.9-slim
# Tesseract OCRとその日本語サポートのインストール
RUN apt-get update && apt-get install -y \
tesseract-ocr \
tesseract-ocr-jpn \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# コンテナ内の作業ディレクトリを/appに設定
WORKDIR /app
# 依存関係ファイルをコピー
COPY requirements.txt .
# 依存関係をインストール
RUN pip install --no-cache-dir -r requirements.txt
# 開発時はボリュームマウントを使用するため、COPYは不要
# COPY app/ .
# 開発用のコマンド
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
requirements.txt
# requirements.txt
# FastAPI: Webフレームワーク
fastapi==0.104.1
# Uvicorn: ASGIサーバー(FastAPIを実行するために必要)
uvicorn==0.23.2
# multipart: ファイルアップロード処理に必要
python-multipart==0.0.6
# pytesseract: TesseractのPythonラッパー(OCR処理用)
pytesseract==0.3.10
# Pillow: 画像処理ライブラリ
Pillow==10.0.1
main.py
from fastapi import FastAPI, File, UploadFile # FastAPIとファイルアップロード関連のインポート
from fastapi.middleware.cors import CORSMiddleware # CORSを許可するためのミドルウェア
import pytesseract # OCRライブラリ
from PIL import Image # 画像処理ライブラリ
import io # バイナリデータ処理用
import logging
# ロギングの設定
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
# FastAPIアプリケーションのインスタンス作成
app = FastAPI(title="Simple OCR API")
# CORSを許可するためのミドルウェアを追加
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 開発環境では一時的にすべてのオリジンを許可
allow_credentials=False, # '*'を使用する場合はFalseにする必要がある
allow_methods=["*"],
allow_headers=["*"],
)
# ルートエンドポイント(/)へのGETリクエスト処理
@app.get("/")
def read_root():
return {"message": "Welcome to Simple OCR API"} # JSONレスポンスを返す
# fastapiエンドポイント(/express-fastapi)へのPOSTリクエスト処理
@app.post("/express-fastapi")
async def extract_text(file: UploadFile = File(...)):
try:
# アップロードされた画像ファイルを読み込む
image_bytes = await file.read()
logger.debug(f"Received file size: {len(image_bytes)} bytes")
logger.debug(f"File content type: {file.content_type}")
# 画像オブジェクトを作成
image = Image.open(io.BytesIO(image_bytes))
logger.debug(f"Image size: {image.size}")
logger.debug(f"Image mode: {image.mode}")
# Tesseract OCRでテキスト抽出を実行
logger.debug("Starting OCR processing...")
text = pytesseract.image_to_string(image, lang='jpn+eng')
logger.debug(f"OCR completed. Extracted text: {text}")
return {"extracted_text": text.strip()}
except Exception as e:
logger.error(f"Error occurred: {str(e)}", exc_info=True)
return {"error": str(e)}
pytesseract
pytesseractはPythonからTesseract OCR(光学文字認識エンジン)を利用するためのラッパーライブラリです。画像からテキストを抽出するのに使用されます。
pytesseractの具体的な使用方法
text = pytesseract.image_to_string(image, lang='jpn+eng')
FastAPIの開発を依頼
「ExpressサーバーからPOSTリクエストでOCR処理用の画像を送信するためのFastAPIサービスを開発していただきたいです。」
「画像はFormData形式で送信され、これをFastAPI側で受け取っていただき、画像内のテキストを抽出をお願いします」
「抽出したテキストは {“extracted_text”: “抽出されたテキスト”} という形式のJSONで返却してください。エラー発生時は {“error”: “エラーメッセージ”} 形式でレスポンスを返してください。」
「使用するエンドポイントは /express-fastapi としてください。」
「日本語と英語の両方のテキストを認識できるよう設定し、ExpressサーバーからのクロスオリジンリクエストのためにCORS設定も必要です。デバッグがしやすいよう、ログレベルはDEBUGで設定してください。」

-
検索
(例) debug search etc.. -
カテゴリー
-
【WordPress】カスタムフィールド作成の仕方「ACF」Advanced Custom Fieldsの使用法
更新日:2024/06/10
299 view
-
mixhostでのWordPress利用について
更新日:2024/04/02
296 view
-
scrollHint
更新日:2024/03/13
249 view
-
LOLIPOPでWordPressインストール(サブディレクトリにインストールしたWordPressをドメイン直下で表示)
更新日:2024/06/13
237 view
-
XML Sitemap Generator for Google不具合のダウングレード対応、代替プラグイン
更新日:2024/06/13
235 view
-
Sass導入方法
更新日:2024/03/13
207 view
-
【SnowMonkey】納品までのフローまとめ
更新日:2025/02/15
163 view
-
【Snow Monkey】Googleサーチコンソール登録
更新日:2024/05/28
157 view
-
ワードプレスでフォントを変えたいとき、プラグインを使えば初心者でも簡単
更新日:2025/02/16
144 view
-
【Googleサーチコンソール】検索画面で表示させたくない「Googleのインデックス削除」
更新日:2024/06/07
129 view
-
【ショートコード】編集画面で任意の場所にHTMLファイルを挿入
更新日:2024/01/26
122 view
-
キーワード検索で上位表示させる方法【SEO】
更新日:2023/10/28
120 view
-
tailwindcss使い方
更新日:2024/03/13
120 view
-
Recline: GitHub Copilotで動作するClaude 3.5 Sonnet搭載の開発支援ツール
更新日:2025/01/20
110 view
-
WordPressプラグイン「All-in-One WP Migration」のトラブル
更新日:2022/03/31
84 view
-
ワードプレスセキュリティー対策まとめ【2025年】「site guard wordpress」「BackWPup バージョン5でUI変更!?」
更新日:2025/02/25
76 view
-
SSHを使用してGitHubのリポジトリをクローン、複数の接続元で公開鍵をディレクトリで区別する方法
更新日:2025/01/13
47 view
-
VSCodeで開発効率を劇的に向上させる!Roo-Clineプラグイン完全ガイド【Gemini API】
更新日:2025/02/08
41 view
-
「JSONスキーマ」と「Few-shot Learning」で実現する次世代生成AIソフトウェア開発の可能性
更新日:2025/02/12
40 view
-
WordPressの無料画像素材のおすすめダウンロードサイト!
更新日:2022/02/22
35 view
-
リファクタリング【VSCode Javasctipt Python】
更新日:2025/03/09
35 view
-
形態素解析とは?初心者でもわかるツールの使い方と実践例
更新日:2025/02/08
33 view
-
【Next.js AWS】音声文字起こし&要約、分析アプリケーション(S3)(Transcribe)(Amazon Bedrock)
更新日:2025/02/13
30 view
-
VSCodeプラグイン「 Pretter – Code formatter」「PHP Intelephense 」
更新日:2025/01/06
26 view
-
WordPressでカスタムフィールドを使った記事のスコアリング 一定割合ランダム表示でε-greedy方策
更新日:2025/02/24
24 view
-
【CSS JavaScript サンプルコード】アコーディオン 続きを読む(Read more)Toggle 折りたたみコンテンツ
更新日:2025/02/05
24 view
-
【WordPress】SVGを投稿記事のサムネイルに!自作プラグイン(未実装🤷♂️)「nonce(ナンス)トークン」wp_postmetaテーブルを利用
更新日:2025/02/16
23 view
-
Googleアドセンスとは?〜前編〜
更新日:2025/02/16
22 view
-
【WordPressプラグイン】人気記事 管理 WordPress Popular Posts 実践的なカスタマイズ
更新日:2025/02/15
22 view
-
AWSのOCRサービス完全ガイド:Textract、Rekognition、Comprehendの使い分け
更新日:2025/02/09
19 view
-
スマートフォンファーストのWeb開発実践ガイド
更新日:2025/01/23
18 view
-
【WordPress】プラグイン不使用でカスタムタクソノミーを設定、絞り込み検索について
更新日:2025/01/26
18 view
-
Express、FastAPIを使用し、二重fetch構成のメリット
更新日:2025/03/09
18 view
-
サブディレクトリでインストールしたWordPressをルートディレクトリで表示させる方法(Xserver編)
更新日:2025/01/19
17 view
-
クッキーとセッションの違い
更新日:2025/03/09
17 view