ウェブサイト検索

Ubuntu 24.04にMongoDBを使ったFast APIをインストールする方法


Ubuntu 24.04にMongoDBを使ったFast APIをインストールする方法

このページで

  1. 前提条件
  2. MongoDBのインストール
  3. Pythonと仮想環境の設定
  4. FastAPIプロジェクトの作成

    1. サーバー/app.py
    2. メイン.py
    3. FastAPIプロジェクトを実行する
  5. FastAPIをMongoDBに接続する

    1. サーバー/データベース.py
  6. pydanticを使用したデータベースモデルの作成
  7. CRUD操作を追加する

    1. アイテムを作成する
    2. すべてのアイテムを取得する
    3. IDに基づいて特定のアイテムを取得する
    4. アイテムを更新する
    5. アイテムを削除する
  8. CRUD操作のためのルートを追加する

    1. サーバー/ルート/アイテム.py
    2. 新しいアイテムを追加するためのルート
    3. 全アイテムを取得するルート
    4. 特定のアイテムを取得するルート
    5. アイテム更新のルート
    6. アイテムを削除するためのルート
    7. サーバー/app.py
  9. テストCRUD操作
  10. 結論

FastAPIは、APIサービスを作成するためのPythonに基づいたWebフレームワークです。これは、モダンで迅速、高性能なフレームワークで、非同期操作をサポートしています。

このチュートリアルでは、Ubuntu 24.04 に MongoDB を使用して FastAPI をインストールする方法を学びます。また、FastAPI と MongoDB データベースを使用して CRUD 操作を行う最初の API を作成する方法も学びます。

前提条件

このガイドを始めるにあたり、以下のものを用意してください:

  • Ubuntu 24.04 システム
  • 管理者権限を持つ非ルートユーザー

MongoDBのインストール

新しいFastAPIプロジェクトを作成する前に、MongoDBサーバーを私たちのシステムにインストールしましょう。

まず、以下のコマンドを実行してパッケージインデックスを更新し、システムに「gnupg」と「curl」をインストールします。

sudo apt update && sudo apt install gnupg curl -y

以下のコマンドを実行して、MongoDB サーバーの GPG キーを追加します。

curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | \
sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg \
--dearmor

以下のコマンドを使用してMongoDBリポジトリを追加してください。

echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list

リポジトリが追加されたら、次のコマンドを実行してパッケージインデックスを更新し、MongoDBサーバーをインストールします。インストールを確認するには'Y'を入力してください。

sudo apt update && sudo apt install mongodb-org

インストールが完了したら、MongoDBサービスの'mongod'サービスを開始および有効にし、MongoDBサービスのステータスを確認して、正常に動作していることを確認します。

sudo systemctl enable --now mongod
sudo systemctl status mongod

下にMongoDBサーバーが動作していることがわかります。

それに加えて、以下の「mongosh」コマンドを使用してMongoDBサーバーにログインできます。終了するには、Ctrl + dを押してください。

mongosh

Pythonと仮想環境の設定

MongoDBがインストールされたら、Pythonパッケージをインストールし、プロジェクトディレクトリと仮想環境を設定します。

以下のコマンドでPython、Pip、およびVenvモジュールをインストールしてください。インストールを確認するために「Y」を入力してください。

sudo apt install python3 python3-pip python3-venv

インストールが完了したら、ユーザーにログインしてください。

su - username

新しい'~/app'ディレクトリを作成し、その中に移動します。このディレクトリは、あなたのFastAPIプロジェクトを保存するために使用されます。

mkdir -p ~/app; cd ~/app

以下のコマンドを実行して、新しいvenv仮想環境を作成し、それをアクティブにします。これで、シェルのプロンプトが(venv) user@hostnameのようになります。

python3 -m venv .venv
source .venv/bin/activate

ここから、作業環境は「venv」仮想環境である必要があります。以下のコマンドを使用して「venv」からログアウトできます。

deactivate

FastAPIプロジェクトの作成

Pythonの仮想環境を作成してアクティベートしたので、FastAPIをインストールしてプロジェクト構造を作成しましょう。

「pip3」コマンドを使用して、「fastapi」と「uvicorn」パッケージをインストールするために実行してください。

pip3 install fastapi uvicorn
  • 「fastapi」は、PythonでAPIを構築するための主要なFastAPIウェブフレームワークです。
  • 'uvicorn'は、PythonでのASGI(非同期サーバゲートウェイインターフェース)ウェブサーバーの実装です。

インストールが完了したら、次のコマンドを使用して新しいファイルとディレクトリを作成します。

mkdir -p server/{models,routes}
touch main.py server/{app.py,database.py} server/models/itemModels.py server/routes/item.py

以下は私たちのFastAPIプロジェクトの構造です。

サーバー/app.py

プロジェクトの準備が整ったので、FastAPIプロジェクトの主要アプリケーションである 'server/app.py' ファイルを修正しましょう。

app.pyファイルをテキストエディタで開き、次のスクリプトをコピーしてください。

from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
 return {"message": "Hello FastAPI!"}
  • プロジェクトにFastAPIモジュールをインポートし、それを「app」変数にバインドします。
  • 新しい「root」関数を作成し、「Hello FastAPI!」を返します。
  • 'ルート'関数はルートURLのGETメソッドに応答しました
  • 'async' はあなたの関数を非同期関数としてマークし、その本体内で 'await' を使用することがあります。

メイン.py

このセクションでは、あなたのFastAPIプロジェクトを'uvicorn'(PythonのASGIウェブサーバー)を通じて実行するために使用される'main.py'ファイルを修正します。

今すぐ 'main.py' スクリプトを開いて修正し、以下のコードを挿入してください。

import uvicorn
if __name__ == "__main__":
 uvicorn.run("server.app:app", host="0.0.0.0", port=8080, reload=True)
  • 「uvicorn」モジュールをインポートする
  • メインスクリプトである 'main.py' が実行されると、 'server/app.py' 内の 'app' または FastAPI モジュールがロードされます。
  • FastAPIは「0.0.0.0」でポート「8080」で実行されます。
  • コードが変更される際に、自動リロードを有効にするには「reload=True」を使用します。

FastAPIプロジェクトを実行する

プロジェクトが準備できたので、最初のFastAPIプロジェクトを実行しましょう。

以下のように 'main.py' スクリプトを実行すれば、あなたのシステムで FastAPI が実行されます。

python3 main.py

今すぐウェブブラウザを開き、http://SERVERIP:8080/ にアクセスしてください。インストールが成功していれば、'Hello FastAPI!' メッセージが表示されます。また、ターミナルから 'curl' を使ってアクセスすることもできます。

最後に、Swagger UIによって提供されているAPIドキュメントにhttp://SERVERIP:8080/docs>からアクセスできます。

FastAPIをMongoDBに接続する

このガイドでは、FastAPIとMongoDBを使用して基本的なAPIを作成します。あなたのAPIはMongoDBデータベースサーバーとCRUD操作を行えるようにする必要があります。このステップでは、プロジェクトをMongoDBサーバーに接続します。

まず、下記の「pip3」コマンドを実行して、プロジェクトに「motor」MongoDBドライバーをインストールします。「motor」は、MongoDBサーバーへのノンブロッキングかつコルーチンベースのAPIアクセスを提供します。

pip3 install motor

サーバー/データベース.py

「motor」モジュールがインストールされた後に、「server/database.py」スクリプトを修正しましょう。

テキストエディタで「server/database.py」ファイルを開き、次のスクリプトを入力してください。これは「motor」モジュールを介してMongoDBサーバーに接続するために使用されます。

from motor.motor_asyncio import AsyncIOMotorClient
MONGODB_HOST = "mongodb://localhost:27017"
connection = AsyncIOMotorClient(MONGODB_HOST)
database = connection.items
item_collection = database.get_collection("item_collection")
  • 『motor.motor_asyncio』から『AsyncIOMotorClient』をインポートします。
  • 新しい定数「MONGODB_HOST」を作成し、MongoDBサーバー「mongodb://localhost:27017」を指すようにします。
  • 「接続」変数を介してMongoDBサーバーに接続します。
  • 「database」変数を介して「items」データベースに接続します。
  • 「item_collection」変数を使ってデータベースのコレクションにアクセスします。

pydanticを使ったデータベースモデルの作成

このセクションでは、MongoDBデータベースのモデル化を提供するpydanticを使用して、データを設計します。

以下の'pip3'コマンドで'pydantic'モジュールをインストールしてください。'pydantic'モジュールは、モデルを通じてデータベーススキーマを作成できるデータ検証ライブラリです。

pip3 install pydantic

今、テキストエディタで'server/models/itemModels.py'ファイルを開き、次のスクリプトをコピーしてください。

from pydantic import BaseModel, Field
from typing import Optional
class Item(BaseModel):
 name: str
 category: str
 stocks: int
 price: int = Field(gt=0)
 class Config:
 json_schema_extra = {
 "example": {
 "name": "Company Smart Watch",
 "category": "smartwatch",
 "stocks": 10,
 "price": 1000,
 }
 }
class ItemUpdate(BaseModel):
 name: Optional[str] = None
 category: Optional[str] = None
 stocks: Optional[int] = None
 price: Optional[int] = None
 class Config:
 json_schema_extra = {
 "example": {
 "name": "New Smart watch",
 "category": "new-smartwatch",
 "stocks": 5,
 "price": 500,
 }
 }
  • 「pydantic」から「BaseModel」と「Field」モジュールをインポートします。
  • 'typing' から 'Optional' モジュールをインポートします
  • FastAPIのために以下の『アイテム』データベーススキーマを作成します:

    • 'name' と 'category' は文字列タイプです
    • '株'と'価格'は整数カテゴリーです
    • '価格' は 0 より大きくなければなりません
  • リクエストにユーザーが含めることができるデータの例を提供することで、'Config'クラスを介してデータモデルを拡張します。
  • 次の「ItemUpdate」スキーマを作成してください。すべてのフィールドはオプションです。

CRUD操作を追加する

この時点で、あなたはMongoDBサーバーに接続し、pydanticを介してデータベーススキーマを作成しました。次に、FastAPIとMongoDBを使ってCRUD操作を作成しましょう。

'server/database.py' スクリプトを再度開き、新しい関数 'item_helper' を作成し、型 'dict' にします。この関数を呼び出して、アイテムの詳細データを取得します。

def item_helper(item) -> dict:
 return {
 "id": str(item["_id"]),
 "name": item["name"],
 "category": item["category"],
 "stocks": item["stocks"],
 "price": item["price"],
 }

次の行を追加して、'bson.objectid'から'ObjectId'モジュールをインポートします。'ObjectId'はBSONのデータ型の一部であり、MongoDBがデータストレージとJSONデータの表現に使用します。

from bson.objectid import ObjectId

アイテムを作成する

まず、MongoDBデータベースに新しいデータを追加できる非同期関数を作成します。

次のように新しい関数'add_item'を作成します:

Add a new item
async def add_item(item_details: dict) -> dict :
 item = await item_collection.insert_one(item_details)
 new_item = await item_collection.find_one({"_id": item.inserted_id})
 return item_helper(new_item)
  • 'add_item'関数は、アイテムの詳細に関する辞書データを受け入れます
  • データベース内の文書にアクセスするために「item_collection」を介し、新しいアイテムを追加するために「insert_one」クエリを実行します。
  • 新しいアイテムは、操作が成功した際に印刷されます。

すべてのアイテムを取得する

次に、データベース内のすべての利用可能なアイテムを取得できる新しい関数「get_items」を作成します。

MongoDBからすべてのアイテムを取得するための新しい関数「get_items」を作成します。

retrieve all items
async def get_items():
 items = []
 async for item in item_collection.find():
 items.append(item_helper(item))
 return items
  • 「アイテム」の空のリストを作成します。
  • すべてのデータを検索するために「find()」クエリを使用し、それをループ処理する
  • 各アイテムは、'append' メソッドを介して 'items' リストに追加されます
  • ループが完了した後、あなたのアイテムが表示されます。

IDに基づいて特定のアイテムを取得する

次に、特定のセレクタ「id」に対してデータを取得できる新しい関数を作成します。これにより、特定のアイテムに関する詳細データが表示されます。

特定のアイテムのデータを取得するために、新しい関数「get_item」を作成します。「get_item」関数は、セレクターとして文字列「id」を受け取り、辞書を返します。

retrieve specific item
async def get_item(id: str) -> dict:
 item = await item_collection.find_one({"_id": ObjectId(id)})
 if item:
 return item_helper(item)
 return "Item Not Found."
  • 'find_one()'クエリは'id'に基づいてデータを取得するために使用されます。
  • アイテムが見つかった場合、詳細は'item_helper'辞書形式で表示されます。
  • アイテムが利用できない場合、返答は「アイテムが見つかりません」となります。

アイテムを更新する

今、アイテムを更新するための新しい関数を作成します。APIを介してアイテムを部分的に更新することもできます。

以下のコードのように新しい関数「change_item」を定義してください:

update item
async def change_item(id: str, data: dict):
 if len(data) < 1:
 return "Please input your data"
 find_item = await item_collection.find_one({"_id": ObjectId(id)})
 if find_item:
 item_update = await item_collection.update_one({"_id": ObjectId(id)}, {"$set": data})
 if item_update:
 return True
 return False
  • 'change_item'関数は、ターゲットアイテムの'id'と新しいデータとしての'data'という2つの引数を取ります。
  • データが空であるか '< 1' の場合、操作は終了しました。
  • この関数は「id」セレクタに基づいてアイテムを見つけます
  • もし「id」が見つかれば、「item_update」が実行されます。
  • もし「item_update」が成功した場合は「True」を返し、そうでなければ「False」を返します。

アイテムを削除する

最後に、特定のセレクタを介してアイテムを削除するための「delete_item」関数を作成します。

アイテムを削除するために、'delete_item'関数を作成し、次のように'id'セレクタを使用します:

delete an item
async def delete_item(id: str):
 item = await item_collection.find_one({"_id": ObjectId(id)})
 if item:
 await item_collection.delete_one({"_id": ObjectId(id)})
 return(f'Item {id} deleted.')
 return "Item Not Found."
  • 「find_one()」クエリは、提供された「id」に基づいてアイテムを検索します。
  • アイテムが見つかった場合、それは 'delete_one()' クエリを介して削除され、'削除されたアイテムID' が返されます。
  • アイテムが利用できない場合は、'アイテムが見つかりません' と表示されます。

CRUD操作のためのルートを追加する

この時点で、FastAPIを使ったCRUD操作のための非同期関数を作成しました。さあ、各操作のためのルートまたはエンドポイントを作成しましょう。

server/routes/item.pyファイルをお好みのエディタで編集してください。

サーバー/ルート/アイテム.py

まず、'fastapi'から'APIRouter'と'Body'モジュールを追加します。次に、'fastapi.encoders'から'jsonable_encode'を追加します。

from fastapi import APIRouter, Body
from fastapi.encoders import jsonable_encoder

「database.py」ファイルから各関数をインポートします。

from server.database import (
 add_item,
 get_items,
 get_item,
 change_item,
 delete_item,
)

「itemModels.py」ファイルから「Item」と「ItemUpdate」モデルをインポートします。

from server.models.itemModels import (
 Item,
 ItemUpdate,
)

'router' 変数を通じて 'APIRouter' クラスを呼び出してください。

router = APIRouter()

新しいアイテムを追加するためのルート

さて、新しいアイテムを追加するためのルートを追加しましょう。この例では、POSTを使用して「/item」URLに新しいアイテムを追加できます。

新しいアイテムを追加するためのルートを設定するには、以下の行を追加してください。アイテムのルートURLへのPOSTは、すべて新しいデータの挿入として扱われます。

add new item operation
@router.post("/")
async def add_item_data(item: Item = Body(...)):
 item = jsonable_encoder(item)
 new_item = await add_item(item)
 return new_item
  • 'add_item_data'関数は、リクエストの'Body'の一部となる'Item'スキーマを受け入れます。
  • あなたのアイテムは 'jsonable_encoder' を通じて辞書形式に変換されます
  • 辞書データを「new_item」変数の上にある「add_item」関数を介して挿入してください(database.pyを参照)。
  • 挿入されたデータ「new_item」を応答として返します。

全アイテムを取得するルート

次のスクリプトを追加して、データを取得するためのルートを設定します。ルートアイテムURLへのすべてのGETリクエストは、あなたのデータをすべて取得します。

get all available items
@router.get("/")
async def get_item_data():
 items = await get_items()
 if items:
 return items
 return "No available item."
  • 「database.py」ファイルから「get_item」関数を実行する「get_item_data」関数を作成してください。
  • アイテムが利用可能な場合、すべてのアイテムのリストを取得できます。
  • アイテムがない場合は、「利用可能なアイテムはありません」というレスポンスが返されます。

特定のアイテムを取得するルート

特定のアイテムの詳細を取得するために、'id'をセレクタとして使用します。'/id'へのすべてのGETリクエストは、要求された'id'の詳細なアイテムを返します。

Show details of the item via the id
@router.get("/{id}")
async def get_item_details(id):
 item_details = await get_item(id)
 if item_details:
 return item_details
 return "Item not found."
  • 'get_item_details'関数が作成され、URLから'id'が渡されます。
  • 「get_item」関数(database.pyを参照)が呼び出され、「id」を引数として渡します。
  • アイテムが見つかった場合、そのアイテムの詳細が表示されます。
  • その特定の「ID」を持つアイテムがない場合、「アイテムが見つかりません」と表示されます。

アイテムを更新するためのルート

更新されたアイテムのルートを設定するために、次のコードをコピーしてください:

Update Item
@router.put("/{id}")
async def update_item(id: str, data: ItemUpdate = Body(...)):
 data = {k: v for k, v in data.dict().items() if v is not None}
 updated_item = await change_item(id, data)
 if updated_item:
 return{f'Success: item {id} updated.'}
 return "Error"
  • 「update_item」関数は、セレクターとしての「id」と「ItemUpdate」モデルに基づく「data」という2つの引数を取ります。
  • データは「data」変数で確認されます
  • 「updated_item」は「database.py」ファイルから「change_item」関数を実行します。
  • 更新が成功した場合、出力に「成功」と表示されます。

アイテムを削除するためのルート

次の行を挿入して、アイテムを削除するための 'remove_item' 関数を作成します。特定の '/id' に対するすべての DELETE 操作は、'id' に一致するアイテムを削除します。

delete item via id
@router.delete("/{id}")
async def remove_item(id):
 item_to_delete = await delete_item(id)
 if item_to_delete:
 return item_to_delete
 return{f'Item {id} Not Available.'}
  • 「remove_item」関数は「delete_item」を実行し、「id」セレクタを渡します。
  • 削除操作は「item_to_delete」変数を介して保存され、実行されます。
  • アイテムが利用できない場合は、「アイテムIDが利用できません」という返事が届きます。

サーバー/app.py

「server/routes/item.py」ファイルを終えたので、「server/app.py」に含めましょう。

テキストエディタを使用して「app.py」ファイルを開いてください。

「server/routes/item.py」ファイルから「ItemRouter」として「router」をインポートします。

from server.routes.item import router as ItemRouter

デフォルトのプレフィックス「/item」を使用して「ItemRouter」を挿入します。CRUD操作は「/item」URLを介して処理されます。

app.include_router(ItemRouter, tags=["Item"], prefix="/item")

これであなたのCRUDエンドポイントは以下の場所で利用可能になります:

  • 新しいアイテムを追加します: '/item'にPOST
  • すべてのアイテムを取得する: '<strong>/item</strong>' にGETする
  • 特定のアイテムを取得する: '/item/id' にGETリクエストを送る。'id'はMongoDBによって生成されます。
  • アイテムを更新する: '/item/id' にPUTする
  • アイテムを削除: '/item/id' に削除する

テストCRUD操作

まず、FastAPIプロジェクトが実行中であることを確認してください。次のように'main.py'スクリプトを実行することもできます:

python3 main.py

http://SERVERIP:8080/docsをナビゲートすると、あなたが作成した各ルートを見ることができます。

以下は新しいアイテムを追加する例です。

APIを通じて利用可能なすべてのアイテムを取得します。

「id」セレクタを使用して特定のアイテムを取得します。

特定のアイテムから部分データを更新します。

以下は更新されたデータです。

以下は、'id'セレクタを使用した削除操作です。

結論

おめでとうございます!Ubuntu 24.04にMongoDBを使ったFastAPIのインストールを完了しました。また、'motor'モジュールを使用してFastAPIをMongoDBに接続する方法、'pydantic'を使用してデータモデルを作成する方法、FastAPIでCRUD操作を作成する方法、そしてAPIのエンドポイントを作成する方法を学びました。

関連記事: