「スタンダードプランで15人、年払いにしたら結局いくら?」——料金表と電卓を行き来しながら見積もりを出すのは、意外と面倒な作業です。そこでPythonのFastAPIを使って、プラン・人数・オプション・支払い方法を選ぶと税込金額まで一発で表示される料金プラン見積もりシミュレーターを作ってみました。
テンプレートエンジンもデータベースも使わない1ファイル構成なので、FastAPI入門の題材にもちょうどいいはずです。実際に4種類の画面で表示と絞り込みの動作を確認するところまで、コードを抜粋しながら解説します。
動画の内容をテキストで確認する
オープニング。FastAPIを使った実践内容を約34秒で紹介します。概要紹介。
この動画では、PythonのFastAPIで、料金プランの見積もりシミュレーターを作ります。具体的にやること。具体的には、FastAPIでフォーム画面と計算処理を実装します。
小計から年払い割引を引き、最後に消費税を加えて税込み額を出します。実装環境・必須アプリ。実装環境と必須アプリは、Windows 11 Pro / Python 3.13.3 / FastAPIです。
実際のキャプチャ動画。実際の画面で操作を確認します。検証の結果、4種類の画面で表示と絞り込みの動作を確認できました。
エンディング。研修ならCodeCampで検索。
目次
- Python FastAPIで料金見積もりシミュレーターを作る方針
- PythonでFastAPIのコードを生成したプロンプトと作り方
- Python・FastAPIの環境構築(Windows 11/PowerShellで検証)
- Pythonのcalculate関数で見積もり計算を実装する
- PythonのFastAPIコードをCodexにレビューさせた結果
- Pythonで4種類の見積もり画面を動かしてみた
- PythonとFastAPIの実行で起きやすいエラーと対処
- クエリパラメータ設計でつまずきやすいポイント
- 料金シミュレーターが実務で使える場面
- Pythonの1ファイル構成で作ってみたまとめ
- 参考にした一次情報
Python FastAPIで料金見積もりシミュレーターを作る方針
今回作るのは、プラン(ライト/スタンダード/プレミアム)・利用人数・オプション・月払いか年払いかを選ぶと、税込の見積もり金額を表示するWebアプリです。画面は入力フォームの「/」と結果表示の「/estimate」の2つだけに絞りました。
方針はシンプルで、FastAPIのGETエンドポイントを2つ用意し、料金マスタはPythonの辞書で定義します。データベースを使わないので準備するものが少なく、HTMLもテンプレートエンジンを使わずPythonの文字列で組み立てるため、外部依存のない1ファイル構成に収まりました。
見積もり計算はcalculate関数に一本化し、小計→年払い割引→消費税の順に、円未満を切り捨てる整数計算で行う仕様です。お金の計算は適用順と丸め方で結果が変わるため、コードを書く前にこの順序を決めておきました。
このセクションの用語
- FastAPI
- PythonでWebアプリやAPIを作るためのフレームワーク。型ヒントを活かして、URLで受け取った値を自動で変換・検証してくれるのが特徴です。
- エンドポイント
- 「/」や「/estimate」のような、アプリが応答するURLの受け口のこと。1つのURLに1つの処理関数を対応させます。
- クエリパラメータ
- URLの「?」以降に付ける
plan=lightのようなキーと値の組。ページの再読み込みだけで条件をサーバーに渡せます。
PythonでFastAPIのコードを生成したプロンプトと作り方
この記事のコードはClaude Codeに書かせたもので、別のAIであるCodexにレビューさせています。以下は、その際に使った指示の内容です。
料金計算は仕様の曖昧さがそのまま金額のズレになるため、プラン・オプション・割引率をすべて具体的な数字で指定しました。とくに「小計から割引を引き、そのあと消費税を加える」と順番まで固定したのがポイントで、これがないと税込み額に割引をかける実装が混ざります。
依存をfastapiとuvicornだけに絞ったのは、生成コードを1ファイルに収めて写経から起動までの距離を最短にするためです。テンプレートエンジンやDBを禁止すると、読者はFastAPI本体の書き方だけに集中できます。
生成プロンプトで工夫したポイント
-
計算の順序は「小計 → 年払い割引を引く → 消費税10%を加える」に固定し:順番を明記しないと税込み額に割引をかける実装が混ざり、合計が数十円ずれることがあるためです。 -
割引額と税額は円未満を切り捨てた整数で扱う:浮動小数点のまま計算すると端数の出方が揺れるので、金額を整数に確定させて誰が実行しても同じ結果になるようにします。 -
3人まで込み・追加1人500円:実際のSaaSに多い「基本料+超過課金」の段階制を数字で示すと、超過分だけを課金する計算が正しく生成されやすくなります。 -
使うのはfastapiとuvicornだけ:依存が2つに絞られるとコードが1ファイルで完結し、環境構築でつまずく余地も小さくなるからです。
同じコードを作れる生成プロンプト(コピペ用・全文)
以下のプロンプトは、そのままコピペして同じものが作れるように整えた全文です。
Python・FastAPIの環境構築(Windows 11/PowerShellで検証)
この記事のセットアップ手順と掲載コードは、Windows 11 Pro、PowerShell 5.1、Python 3.13.3で動作確認しています。仮想環境を有効化せず、その中のPythonを直接指定するため、以下のコマンドはPowerShellとコマンドプロンプト(cmd)の両方で使えます。
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install fastapi uvicorn
macOS・Linuxでは仮想環境内のPythonパスが異なります。今回の動作確認環境とは異なるため、以下は環境差分を補う参考手順です。
python3 -m venv .venv
./.venv/bin/python -m pip install fastapi uvicorn
- 起動は.\.venv\Scripts\python.exe -m uvicorn estimate_app:app --reloadで行い、ブラウザでhttp://127.0.0.1:8000を開くと確認できます。
- サーバーはCtrl+Cで停止します。ポート8000が使用中なら--port 8001のように別ポートを指定してください。
Pythonのcalculate関数で見積もり計算を実装する
コード全体は「料金マスタの定義」「calculate関数」「HTML組み立てのrender_page」「2つのエンドポイント」という4ブロック構成です。上から順に読むと、データ→計算→表示という流れがそのまま追えるように並べました。
工夫が要ったのはオプションの複数選択です。options=support&options=backupのように同じ名前のクエリパラメータを複数並べて送り、受け取る側では引数にQuery(default=[])を指定してリストとしてまとめて受け取ります。
この書き方は自己流ではなく、FastAPIの公式ドキュメントで案内されている方法です。Queryを明示しないとリストはリクエストボディ扱いになってしまうため、GETで複数値を受けるなら必須の指定になります。
それでは、押さえておけば全体が分かる要点だけをコードから抜粋して見ていきます。
このセクションの用語
- 辞書(dict)
- キーと値をペアで持つPythonのデータ型。
PLANS["light"]のようにキーを指定して値を取り出せます。 - Query
- FastAPIでクエリパラメータの受け取り方を細かく指定する仕組み。
Query(default=[])とすると、同名パラメータの複数指定をリストで受け取れます。 - リスト内包表記
-
[x for x in ... if 条件]の形で、既存のリストから条件に合う要素だけを集めた新しいリストを1行で作る書き方。 - f文字列
- 先頭に
fを付けた文字列の中に{変数}を書くと、その場で値が埋め込まれるPythonの記法。HTMLの組み立てにも使えます。
from fastapi import FastAPI, Query
from fastapi.responses import HTMLResponse
# 料金マスタの定義
PLANS = {
"light": {"name": "ライト", "base": 5000, "included": 3, "per_user": 500},
"standard": {"name": "スタンダード", "base": 15000, "included": 10, "per_user": 800},
"premium": {"name": "プレミアム", "base": 50000, "included": 30, "per_user": 1200},
}
OPTIONS = {
"support": {"name": "優先サポート", "price": 3000},
"backup": {"name": "自動バックアップ", "price": 2000},
"sso": {"name": "SSO連携", "price": 5000},
}
YEARLY_DISCOUNT_RATE = 0.15 # 年払いは小計から15%割引
TAX_RATE = 0.10 # 消費税10%
# アプリ本体と動作確認したい画面の一覧
app = FastAPI(title="料金プラン見積もりシミュレーター")
ROUTES = [
"/",
"/estimate?plan=standard&users=15&options=support&options=backup&billing=yearly",
"/estimate?plan=light&users=3&billing=monthly",
"/estimate?plan=premium&users=40&options=sso&billing=yearly",
]
# 見積もり計算(小計 → 年払い割引 → 消費税の順で適用する)
def calculate(plan_key: str, users: int, option_keys: list[str], billing: str) -> dict:
plan = PLANS[plan_key]
extra_users = max(0, users - plan["included"])
user_fee = extra_users * plan["per_user"]
selected_options = [OPTIONS[k] for k in option_keys if k in OPTIONS]
option_fee = sum(o["price"] for o in selected_options)
subtotal = plan["base"] + user_fee + option_fee
discount = int(subtotal * YEARLY_DISCOUNT_RATE) if billing == "yearly" else 0
tax = int((subtotal - discount) * TAX_RATE)
return {
"plan": plan,
"users": users,
"extra_users": extra_users,
"user_fee": user_fee,
"options": selected_options,
"option_fee": option_fee,
"subtotal": subtotal,
"discount": discount,
"tax": tax,
"total": subtotal - discount + tax,
"billing": billing,
}
# ページ共通のHTMLレイアウト
def render_page(title: str, body: str) -> str:
return f"""<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{title}</title>
<style>
body {{ font-family: sans-serif; background: #f4f6fb; margin: 0; color: #223; }}
main {{ max-width: 640px; margin: 40px auto; background: #fff; border-radius: 12px;
padding: 32px; box-shadow: 0 2px 10px rgba(0,0,0,.08); }}
h1 {{ font-size: 1.4rem; border-left: 6px solid #2563eb; padding-left: 12px; }}
fieldset {{ border: 1px solid #d5dbe7; border-radius: 8px; margin-bottom: 20px; }}
legend {{ font-weight: bold; padding: 0 8px; }}
label {{ display: block; margin: 8px 0; }}
input[type=number] {{ width: 6em; padding: 4px; }}
button {{ background: #2563eb; color: #fff; border: none; border-radius: 8px;
padding: 12px 32px; font-size: 1rem; cursor: pointer; }}
table {{ width: 100%; border-collapse: collapse; margin: 16px 0; }}
th, td {{ border-bottom: 1px solid #e2e8f0; padding: 10px 8px; text-align: left; }}
td.amount {{ text-align: right; font-variant-numeric: tabular-nums; }}
tr.total td {{ font-size: 1.2rem; font-weight: bold; color: #2563eb; }}
a {{ color: #2563eb; }}
</style>
</head>
<body><main>{body}</main></body>
</html>"""
# 入力フォーム画面
@app.get("/", response_class=HTMLResponse)
def index() -> str:
plan_inputs = "".join(
f'<label><input type="radio" name="plan" value="{key}"'
f'{" checked" if key == "standard" else ""}>'
f'{p["name"]}:月額{p["base"]:,}円({p["included"]}人まで込み、追加1人{p["per_user"]:,}円)</label>'
for key, p in PLANS.items()
)
option_inputs = "".join(
f'<label><input type="checkbox" name="options" value="{key}">'
f'{o["name"]}(+{o["price"]:,}円/月)</label>'
for key, o in OPTIONS.items()
)
body = f"""
<h1>料金プラン見積もりシミュレーター</h1>
<p>プランと利用条件を選んで「見積もりを計算」を押してください。</p>
<form action="/estimate" method="get">
<fieldset><legend>プラン</legend>{plan_inputs}</fieldset>
<fieldset><legend>利用人数</legend>
<label>ユーザー数 <input type="number" name="users" value="10" min="1" max="500"> 人</label>
</fieldset>
<fieldset><legend>オプション</legend>{option_inputs}</fieldset>
<fieldset><legend>支払いサイクル</legend>
<label><input type="radio" name="billing" value="monthly" checked>月払い</label>
<label><input type="radio" name="billing" value="yearly">年払い(小計から15%割引)</label>
</fieldset>
<button type="submit">見積もりを計算</button>
</form>"""
return render_page("料金プラン見積もりシミュレーター", body)
# 見積もり結果画面
@app.get("/estimate", response_class=HTMLResponse)
def estimate(
plan: str = "standard",
users: int = 1,
options: list[str] = Query(default=[]),
billing: str = "monthly",
) -> str:
if plan not in PLANS:
return render_page(
"エラー",
'<h1>エラー</h1><p>不明なプランが指定されました。</p><p><a href="/">フォームに戻る</a></p>',
)
users = min(max(users, 1), 500)
result = calculate(plan, users, options, billing)
option_rows = "".join(
f'<tr><td>オプション:{o["name"]}</td><td class="amount">{o["price"]:,}円</td></tr>'
for o in result["options"]
) or '<tr><td>オプション</td><td class="amount">0円</td></tr>'
discount_row = (
f'<tr><td>年払い割引(15%)</td><td class="amount">-{result["discount"]:,}円</td></tr>'
if result["billing"] == "yearly"
else ""
)
billing_label = "年払い" if result["billing"] == "yearly" else "月払い"
body = f"""
<h1>見積もり結果</h1>
<p>{result["plan"]["name"]}プラン / {result["users"]}人 / {billing_label}</p>
<table>
<tr><td>基本料金({result["plan"]["included"]}人まで込み)</td><td class="amount">{result["plan"]["base"]:,}円</td></tr>
<tr><td>追加ユーザー料金({result["extra_users"]}人 × {result["plan"]["per_user"]:,}円)</td><td class="amount">{result["user_fee"]:,}円</td></tr>
{option_rows}
<tr><td>小計</td><td class="amount">{result["subtotal"]:,}円</td></tr>
{discount_row}
<tr><td>消費税(10%)</td><td class="amount">{result["tax"]:,}円</td></tr>
<tr class="total"><td>月額合計(税込)</td><td class="amount">{result["total"]:,}円</td></tr>
</table>
<p><a href="/">条件を変えて再計算する</a></p>"""
return render_page("見積もり結果", body)コード全文は上の折り畳みに入れてあるので、全部を上から読む必要はありません。ここでは特に重要な部分だけを抜き出して、何をしているのか順番に見ていきます。
PLANS辞書で料金マスタを一元管理する
PLANS = {
"light": {"name": "ライト", "base": 5000, "included": 3, "per_user": 500},
"standard": {"name": "スタンダード", "base": 15000, "included": 10, "per_user": 800},
"premium": {"name": "プレミアム", "base": 50000, "included": 30, "per_user": 1200},
}3つのプランを、基本料金base・込みユーザー数included・超過1人あたりの単価per_userという共通の形で持たせています。料金改定のときはこの辞書の数値を書き換えるだけで、計算にも画面にも反映される作りです。
calculate関数に見積もりロジックを集約する
def calculate(plan_key: str, users: int, option_keys: list[str], billing: str) -> dict:
plan = PLANS[plan_key]金額に関わる計算はすべてこの関数に集めました。入力は文字列と数値だけ、出力は計算結果を詰めた辞書という素直な形なので、画面と切り離して単体でテストしやすくなります。
max関数で超過人数のマイナスを防ぐ
extra_users = max(0, users - plan["included"])
user_fee = extra_users * plan["per_user"]利用人数がプランの込みユーザー数以下だとusers - plan["included"]は負の数になり、そのまま掛け算すると料金がマイナスになってしまいます。max(0, ...)で下限を0に固定するのが定番の守り方です。
リスト内包表記で選択オプションを取り出す
selected_options = [OPTIONS[k] for k in option_keys if k in OPTIONS]
option_fee = sum(o["price"] for o in selected_options)クエリで受け取ったオプションのキーのうち、if k in OPTIONSでマスタに存在するものだけを拾います。URLに不正なキーを混ぜられても黙って無視されるだけなので、余計なエラー処理を書かずに済みました。
intの切り捨てで割引と消費税を計算する
subtotal = plan["base"] + user_fee + option_fee
discount = int(subtotal * YEARLY_DISCOUNT_RATE) if billing == "yearly" else 0
tax = int((subtotal - discount) * TAX_RATE)小計→年払いなら15%割引→残額に消費税10%、という決めた順序どおりの計算です。掛け算のたびにint()で円未満を切り捨てて整数に戻すことで、小数の誤差が金額に紛れ込むのを防いでいます。
render_pageで共通HTMLレイアウトを返す
def render_page(title: str, body: str) -> str:
return f"""<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">ページごとに違うのはタイトルと本文だけなので、共通の枠をf文字列で1回だけ書き、{title}と{body}を差し込む方式にしました。テンプレートエンジンなしでも、この程度の規模なら十分に見通しよく書けます。
参考:
©FastAPI公式ドキュメントTo declare a query parameter with a type of list, like in the example above, you need to explicitly use Query, otherwise it would be interpreted as a request body.
PythonのFastAPIコードをCodexにレビューさせた結果
プロンプトから作ったコードは、一見動いていても抜けや改善点が潜んでいることがあります。エラーにならない=正しい、ではないのが怖いところです。
そこで、コードを書いたClaude Codeとは別のAIであるCodexに同じコードをレビューさせ、指摘をそのまま載せます。書き手と読み手を別のAIに分けると、自分では気づきにくい問題を洗い出せます。
| 指摘 | 深刻度 | 改善案 |
|---|---|---|
| billingにyearly以外の任意の値を指定しても月払いとして処理されるため、不正な入力を検出できません。 | 高 | billingをLiteral['monthly','yearly']などで検証し、許可されない値には422エラーを返してください。 |
| optionsに同じキーを複数回指定すると、同じオプション料金が重複加算されます。 | 高 | オプションキーをsetで重複排除するか、重複入力をバリデーションエラーとして拒否してください。 |
| 存在しないオプションキーを指定しても黙って無視されるため、利用者の入力ミスに気付けません。 | 中 | 不正なオプションキーを検出して422エラーを返すか、結果画面に明示的な警告を表示してください。 |
| usersが1未満または500超の場合にエラーではなく値を自動補正するため、入力値と見積もり条件が一致しません。 | 中 | Queryのgeとleで範囲を検証し、範囲外の値は422エラーとして再入力を促してください。 |
| 年払いでも合計を月額合計と表示しており、15パーセント割引後の月額相当額なのか年間請求額なのかが不明確です。 | 中 | 年額を表示する仕様なら割引後の月額を12倍し、月額相当を表示する仕様なら見出しと説明を月額相当に統一してください。 |
Pythonで4種類の見積もり画面を動かしてみた
開発サーバーを起動してブラウザからアクセスし、フォーム画面と条件違いの見積もり結果、合わせて4種類の画面を確認しました。いずれもHTTP 200で正常に表示されています。
結果画面は次の3パターンを試しました。プランと人数、オプションの絞り込み条件を変えるたびに、金額の内訳が組み替わって表示されるのを確認できています。
あわせて、ブラウザ操作の録画でも一連の流れをチェックしました。フォームで条件を選んで送信すると、URLのクエリパラメータが変わり、その条件どおりの見積もりに切り替わる様子が追えます。
このセクションの用語
- uvicorn
- FastAPIアプリを動かすためのサーバー。開発中は
uvicorn main:app --reloadのように起動し、コードを保存すると自動で再読み込みされます。 - HTTP 200
- リクエストが正常に処理されたことを示すステータスコード。エラー時は404や422など別の番号が返ります。
- スタンダードプラン・15人・優先サポート+自動バックアップ・年払い(
/estimate?plan=standard&users=15&options=support&options=backup&billing=yearly) - ライトプラン・3人・オプションなし・月払い(
/estimate?plan=light&users=3&billing=monthly)——込みユーザー数内に収まる最小構成 - プレミアムプラン・40人・SSO連携・年払い(
/estimate?plan=premium&users=40&options=sso&billing=yearly)——超過課金と割引が両方効く構成





PythonとFastAPIの実行で起きやすいエラーと対処
この手の構成で初心者が遭遇しやすいエラーを、原因と対処のセットでまとめておきます。どれも一般によくあるパターンなので、動かないときはまずここから疑ってみてください。
特に4つ目のQueryまわりは、コードが一見正しく見えるだけに気づきにくいポイントです。GETでリストを受け取るときの約束事として覚えておくと、原因の切り分けが早くなります。
このセクションの用語
- 仮想環境
- プロジェクトごとにライブラリを分けて管理するPythonの仕組み。有効化を忘れると、インストールしたはずのライブラリが見つからなくなります。
- 422 Unprocessable Entity
- 受け取った値が期待する型や条件に合わないときにFastAPIが自動で返すエラー。どの引数が問題かはレスポンスの
detailに書かれています。
| エラー例 | 原因 | 対処 |
|---|---|---|
ModuleNotFoundError: No module named 'fastapi' |
ライブラリが未インストール、または別の仮想環境を見ている | 仮想環境を有効化してからpip install "fastapi[standard]"を実行し直す |
起動時にaddress already in useと表示される |
ポート8000を別のプロセスがすでに使っている |
uvicorn main:app --port 8001のように空いているポート番号を指定する |
画面に{"detail":[{"type":"int_parsing",...}]}(422)が出る |
usersなど整数の引数に数値でない値が渡っている |
フォームの入力欄にtype="number"を指定し、URL直打ちのときは整数を渡す |
optionsを複数付けてもリストで受け取れない |
Queryを明示せずにリスト型の引数を宣言し、リクエストボディ扱いになっている |
options: list[str] = Query(default=[])の形で宣言する |
| ブラウザで日本語が文字化けする | HTMLに文字コードの指定がない |
<meta charset="utf-8">を<head>内に入れる |
クエリパラメータ設計でつまずきやすいポイント
フォームからGETで値を渡す今回の構成は仕組みが単純なぶん、名前や順序のちょっとしたズレが「値が届かない」「金額が合わない」という分かりにくい不具合につながります。ハマりやすい点を先にまとめておきます。
このセクションの用語
- name属性
- フォームの入力部品に付ける名前。送信時にはこの名前がクエリパラメータのキーになるため、受け取る側の引数名と揃える必要があります。
- 浮動小数点数
- 小数を近似値で扱う数値型。0.1のような値も2進数では正確に表せないため、金額計算では誤差の原因になりえます。
HTMLフォームのname属性は、エンドポイント側の引数名と完全に一致させる必要があります。1文字でも違うと値が渡らず、デフォルト値のまま計算されてしまうのが厄介です。
チェックボックスは全部同じname="options"にすると、options=support&options=backupのような複数値として送信されます。1つずつ別の名前を付けるとリストで受け取れなくなるので注意してください。
お金の計算に浮動小数点数をそのまま使うと、微小な誤差が合計に紛れ込むことがあります。今回は掛け算のたびにint()で円未満を切り捨て、常に整数で持つ方針に統一しました。
小計→割引→税の適用順を入れ替えると、同じ入力でも合計金額が変わります。どの順で丸めるかも含めて、計算ルールは実装前に仕様として固定しておくのが安全です。
料金シミュレーターが実務で使える場面
「基本料金+人数課金+オプション+割引」という構造は、SaaSに限らず多くの料金体系に共通しています。PLANSとOPTIONSの中身を差し替えるだけで流用できるので、応用の幅は広いはずです。
実務での使いどころを、具体的な使い方まで含めて挙げてみます。
| 使える場面 | 具体的な使い方 |
|---|---|
| SaaS製品の営業・商談支援 | 商談中にプラン・人数・オプションをその場で切り替えて税込金額を提示する。料金改定時はPLANS辞書の数値を書き換えるだけで画面にも反映される |
| 社内システムの部署別課金の案内 | 情シスが利用部署ごとの人数とオプションを入力して概算を出し、結果画面のURLをそのまま稟議資料や依頼メールに貼って共有する |
| 代理店・パートナー向け見積もりツール | 計算ロジックがcalculate関数に一本化されているため、割引率の定数だけを代理店ごとに変えた派生版を短時間で用意できる |
| ジムやレンタルスペースなど非IT業種の料金案内 | 「基本料+超過課金+オプション」という構造は共通なので、PLANSの項目名と単価を差し替えて店頭タブレット用の料金案内として使う |
Pythonの1ファイル構成で作ってみたまとめ
FastAPIのGETエンドポイント2つと辞書の料金マスタだけで、料金プラン見積もりシミュレーターを1ファイルに収めました。実際に4種類の画面で表示と絞り込みの動作を確認でき、フォームで条件を変えると内訳ごと金額が切り替わるところまで動いています。
振り返ると、学びの中心は次の3点でした。どれもFastAPIに限らず、Webアプリで「条件を受け取って計算結果を返す」場面全般で効いてくる考え方です。
次のステップとしては、Queryのge=1のような値の範囲チェックを足したり、料金マスタをJSONファイルに切り出したりする拡張が考えられます。まずはこの1ファイルを手元で動かして、PLANSの数値を自分の題材に書き換えるところから試してみてください。
- 複数選択は同名クエリパラメータの繰り返しで表現し、
Query(default=[])でリストとして受け取る - お金の計算は「小計→割引→税、円未満切り捨て」のように、適用順と丸め方を先に仕様として決めてから実装する
- 計算を
calculate関数、表示をrender_page関数に分けておくと、1ファイル構成でも見通しが保てる
参考にした一次情報
- ^ FastAPI公式ドキュメント(日本語). https://fastapi.tiangolo.com/ja/, (参照26-07-17).
- ^ クエリパラメータ - FastAPI. https://fastapi.tiangolo.com/ja/tutorial/query-params/, (参照26-07-17).
- ^ カスタムレスポンス(HTMLResponse) - FastAPI. https://fastapi.tiangolo.com/ja/advanced/custom-response/, (参照26-07-17).
- ^ Uvicorn公式ドキュメント. https://www.uvicorn.org/, (参照26-07-17).
※内容は執筆時点のものです。ライブラリやサイトの仕様は変わる可能性があるため、公式ドキュメントもあわせてご確認ください。
ITやプログラミングに関するコラム
【CSS】notで複数の件を除外する方法
【Git】remote設定を変更する方法
【VBA】コメントアウトを設定する方法
x86とx64の違いを分かりやすく解説
マークダウンで改行する方法
CapsLockキーを解除する方法
GitLabとGitHubの違いを解説
Linuxで環境変数を確認する方法
UbuntuのIPアドレスを確認する方法
パソコンのメモリの目安を用途別に選ぶ方法
ITやプログラミングに関するニュース
VercelがAI GatewayにSeedream 5.0 Proを追加、AI SDKのモデル指定で画像生成と編集が可能に
AWSがAmazon LocationのPlaces APIを強化、住所表記の指定と移動手段別の検索が可能に
VercelがトレースにTree・Waterfallビューを追加、ログ画面で処理の階層と所要時間を確認可能に
Googleがエージェント評価の再考を提唱、難易度を情報量で測るDiscovery Benchを解説
Google CloudがCloud Runサンドボックスを公開プレビューで提供、サービスヘルスは一般提供に
Google Cloud EMEAが英国金融の重要第三者に指定、イングランド銀行・PRA・FCAの直接監督下に
AWS DMS Schema ConversionがSQL Serverのオフライン変換に対応、ソースDBへ接続せずスキーマを変換可能に
EC2 G7インスタンスが米国東部(バージニア北部)で利用可能に、G6比でAI推論性能が最大4.6倍
SageMaker HyperPodが継続プロビジョニングでのAMIベース構成に対応、S3のスクリプト管理なしでSlurmクラスターを作成可能に
AWSがEMR on EKSでSparkトラブルシューティングエージェントに対応、失敗ジョブの原因分析を自然言語で依頼可能に
