歡迎來到 FastAPI 的世界,這是一個用于構建 Python API 的時尚高性能 Web 框架。如果您是 API 編程的新手,請不用擔心——我們會從基礎開始。

API(應用程序編程接口)連接多個軟件程序,允許它們進行對話和交換信息。API 在現代軟件開發中是必不可少的,因為它們是應用程序的后端架構。

閱讀完本快速入門指南后,你將能夠使用FastAPI和MongoDB開發一個課程管理API。最好的是,你不僅將編寫API,還將對其進行測試和容器化。

在本實戰項目中,我們將使用FastAPI(一個快速的Web框架)和MongoDB數據庫(用于存儲和檢索課程信息)來創建一個Python后端系統。

該系統將允許用戶訪問課程詳細信息、查看章節、對單個章節進行評分和匯總評分。

本項目旨在為具有基本編程知識和一些NoSQL知識的Python開發人員設計。對于MongoDB、DockerPyTest的熟悉程度并不是必需的,因為我會在本項目的范圍內重點介紹你需要了解的一切。

我們將構建的內容

以下是我們將要構建的內容:

FastAPI 后端:它將用作處理 API 請求和響應的接口。選擇 FastAPI 是因為其易用性、性能和直觀的設計。

MongoDB 數據庫:用于存儲課程信息的 NoSQL 數據庫。MongoDB 的靈活架構允許我們將數據存儲在類似 JSON 的文檔中,使其適合此項目。

課程信息:用戶將能夠查看各種課程詳細信息,例如課程名稱、描述、講師等。

章節詳情:系統將提供有關課程中章節的信息,包括章節名稱、描述和任何其他相關數據。

章節評分:用戶將能夠對單個章節進行評分。我們將實現記錄和檢索章節評級的功能。

課程綜合評分:系統將根據每門課程章節的評分計算并顯示每門課程的匯總評分。

本指南將展示如何設置開發環境、構建FastAPI后端、集成MongoDB、定義API端點、添加章節評分功能以及計算課程綜合評分。它涵蓋了項目的基本概念以及Python、MongoDB和NoSQL數據庫的使用。

最終,這個實用的后端系統將管理章節詳細信息、課程信息和用戶評分,為復雜且有價值的項目奠定基礎。

我們的目標是創建一個處理與課程相關查詢的系統。必須根據請求從MongoDB中檢索課程信息。最后,這些回答數據必須以標準格式(JSON)返回。

我們將從一個腳本開始,該腳本從courses.json中讀取課程信息。這些數據將被存儲在MongoDB實例中。一旦數據加載完成,我們的API代碼就可以連接到這個數據庫,以便輕松檢索數據。

有趣的是,使用 FastAPI 創建多個端點。我們的 API 將能夠:

此外,對于每門課程,我們將匯總所有評論,為訪問者提供有關課程受歡迎程度和質量的相關信息。

本教程專注于構建一個可擴展、高效且用戶友好的API。完成所有測試后,我們將使用Docker將應用程序容器化。這將極大地簡化部署、維護和安裝過程。

API 方法

HTTP(超文本傳輸協議)方法指定要對資源執行的操作。以下是最常用的 API 開發方法:

GET:從服務器請求信息。當客戶端提交 GET 請求時,它正在從服務器請求數據。

POST:將數據發送到服務器進行處理。當客戶端提交 POST 請求時,它通常會將數據傳送到服務器以創建或更新資源。

PUT:更新服務器數據。當客戶端提交 PUT 請求時,請求中指示的資源將更新。

DELETE:發送 DELETE 請求的客戶端請求刪除指定的資源。

客戶端和服務器

客戶端通常是發送請求到服務器的前端應用程序,如網頁瀏覽器或移動應用。而服務器則是負責處理客戶端請求并作出相應響應的后端應用程序。

請求是客戶端發送給服務器的通信,它指定了要執行的操作和任何所需的數據。請求包括HTTP方法、URL(統一資源定位符)、頭部,以及在POST或PUT請求的情況下,還包括數據負載。

服務器收到請求后,會對其進行處理并返回響應。響應是服務器返回給客戶端的消息,其中包含請求的數據或活動的結果。

響應通常包括一個HTTP狀態碼,指示請求的成功或失敗,以及服務器返回給客戶端的任何數據。

Image

顯示 API 工作原理的圖表

如何設置 MongoDB 數據庫

MongoDB是一種NoSQL數據庫。它是非關系型的,并以集合和文檔的形式保存信息。

從官方網站為您的操作系統安裝MongoDB。

現在運行終端的命令以驗證安裝是否成功。運行mongosh命令應該得到以下輸出:

運行 mongosh 命令應生成此輸出

使用 MongoDB Compass 連接到 MongoDB 服務器。我建議您通過指定端口號、存儲引擎、身份驗證等設置來配置 MongoDB。

創建新的 MongoDB 連接

現在連接已經建立,下一步是創建一個數據庫或“文檔”。將這個數據庫命名為“courses”。目前它對你來說還是空的。稍后我們會使用Python腳本來插入文檔。

如何解析課程數據并將其插入 MongoDB

你可以逐個插入記錄,但最好使用JSON文件來簡化這個過程。從GitHub下載名為courses.json的文件。所有課程信息都包含在這個文件中(作為課程列表)。

具體來說,每門課程都有以下結構:

此項目需要一些 Python 包。

通過 pip 命令安裝它們,如下所示:

pip install fastapi pymongo uvicorn starlette pydantic

現在,讓我們編寫一個Python腳本來將所有這些課程數據插入數據庫,這樣我們就可以開始構建API路由了。啟動你的IDE,創建一個名為script.py的文件,并確保它與courses.json文件在同一個目錄中。

""" 
Script to parse course information from courses.json, create the appropriate databases and
collection(s) on a local instance of MongoDB, create the appropriate indices (for efficient retrieval)
and finally add the course data on the collection(s).
"""

import pymongo
import json

# Connect to MongoDB
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["courses"]
collection = db["courses"]

# Read courses from courses.json
with open("courses.json", "r") as f:
courses = json.load(f)

# Create index for efficient retrieval
collection.create_index("name")

# add rating field to each course
for course in courses:
course['rating'] = {'total': 0, 'count': 0}

# add rating field to each chapter
for course in courses:
for chapter in course['chapters']:
chapter['rating'] = {'total': 0, 'count': 0}

# Add courses to collection
for course in courses:
collection.insert_one(course)

# Close MongoDB connection
client.close()

此腳本使用 JSON 文件中的課程信息填充 MongoDB 數據庫。

它首先連接到本地MongoDB實例。它從名為courses.json的文件中讀取課程數據,并為課程評分創建一個新字段。然后,它開發一個索引以加快數據檢索速度。最后,將課程數據添加到MongoDB集合中。

這是一個用于管理數據庫中課程數據的簡單腳本。運行腳本后,courses.json中的所有記錄應該都已插入到courses數據庫中。切換到MongoDB Compass進行驗證。

運行 python 腳本后,您應該能夠在 courses 數據庫中看到 JSON 項目

如何設計 FastAPI 端點

這些 API 端點提供了一種有效的方法來管理課程信息、檢索課程詳細信息,并允許用戶交互以對章節進行評級。

我建議在編寫代碼之前,先設計 API 終端節點以及 HTTP 請求類型。這是一個很好的參考,并在編碼過程中提供清晰度。

端點請求類型描述
/coursesGET獲取所有可用課程的列表以及排序選項。

選項:按標題(升序)、日期(降序)或課程總評分(降序)排序。

支持基于域的可選篩選。

端點請求類型描述
/coursesGET獲取所有可用課程的列表。
/courses/{course_id}GET通過課程ID獲取特定課程的概述。
/courses/{course_id}/{chapter_id}GET獲取課程中特定章節的信息。
/courses/{course_id}/{chapter_id}POST對課程中特定章節進行評分。

選項:好評 (1)、好評 (-1)。

每個課程的評分是匯總得出的。

好的,現在讓我們深入API代碼。創建一個全新的Python文件,并將其命名為main.py

import contextlib
from fastapi import FastAPI, HTTPException, Query
from pymongo import MongoClient
from bson import ObjectId
from fastapi.encoders import jsonable_encoder

app = FastAPI()
client = MongoClient('mongodb://localhost:27017/')
db = client['courses']

代碼導入了必要的模塊,并創建了名為app的FastAPI類的活動實例。它還使用PyMongo庫建立了到本地MongoDB數據庫的連接,變量db現在存儲了對courses文檔的連接引用。

現在讓我們更詳細地討論這些端點。

獲取所有課程端點 ( – GET)

此端點允許您檢索所有可用課程的列表。您可以根據不同的標準對課程進行排序,例如字母順序(基于課程標題的升序)、日期(降序)或課程總評分(降序)。此外,我們還允許用戶根據其域篩選課程。

@app.get('/courses')
def get_courses(sort_by: str = 'date', domain: str = None):
# set the rating.total and rating.count to all the courses based on the sum of the chapters rating
for course in db.courses.find():
total = 0
count = 0
for chapter in course['chapters']:
with contextlib.suppress(KeyError):
total += chapter['rating']['total']
count += chapter['rating']['count']
db.courses.update_one({'_id': course['_id']}, {'$set': {'rating': {'total': total, 'count': count}}})

# sort_by == 'date' [DESCENDING]
if sort_by == 'date':
sort_field = 'date'
sort_order = -1

# sort_by == 'rating' [DESCENDING]
elif sort_by == 'rating':
sort_field = 'rating.total'
sort_order = -1

# sort_by == 'alphabetical' [ASCENDING]
else:
sort_field = 'name'
sort_order = 1

query = {}
if domain:
query['domain'] = domain

courses = db.courses.find(query, {'name': 1, 'date': 1, 'description': 1, 'domain':1,'rating':1,'_id': 0}).sort(sort_field, sort_order)
return list(courses)

此代碼在FastAPI應用程序中定義了一個端點,用于檢索所有可用課程的列表。可以通過向/courses URL發送HTTP GET請求來訪問該端點。

裝飾器附加到該函數上,并負責處理此操作:@app.get()

當向此端點發出請求時,代碼首先通過計算每個課程中所有章節的評分總和來計算課程總評分。然后,它更新MongoDB數據庫中每個課程的字段,包含計算出的總評分和評分計數。

接下來,代碼根據查詢參數確定排序模式。如果sort_by設置為date,則課程將按其創建日期的降序排序。如果設置為rating,則課程將按其總評分的降序排序。否則,課程將按其名稱的字母順序升序排序。

如果提供了可選的查詢參數domain,則代碼將基于指定的領域過濾課程。

最后,代碼查詢MongoDB數據庫以檢索相關的課程信息,包括課程名稱、創建日期、描述、領域和評分。課程根據所選的排序模式進行排序,并以列表形式返回。

這是對代碼的解釋,但實際的API響應呢?在當前工作目錄中,從終端運行以下命令:

uvicorn main:app --reload

Uvicorn 是一個 ASGI Web 服務器。您可以直接在本地計算機上與 API 終端節點交互,而無需任何外部服務器。運行上述命令時,您應該會看到一條成功消息,指出服務器已啟動。

打開瀏覽器并在 URL 欄中輸入 http://127.0.0.1:8000/courses。您將看到的輸出將是直接來自服務器的 JSON 響應。

驗證第一個對象是否包含以下內容:

{
"name": "Introduction to Programming",
"date": 1659906000,
"description": "An introduction to programming using a language called Python. Learn how to read and write code as well as how to test and \"debug\" it. Designed for students with or without prior programming experience who'd like to learn Python specifically. Learn about functions, arguments, and return values (oh my!); variables and types; conditionals and Boolean expressions; and loops. Learn how to handle exceptions, find and fix bugs, and write unit tests; use third-party libraries; validate and extract data with regular expressions; model real-world entities with classes, objects, methods, and properties; and read and write files. Hands-on opportunities for lots of practice. Exercises inspired by real-world programming problems. No software required except for a web browser, or you can write code on your own PC or Mac.",
"domain": [
"programming"
],
"rating": {
"total": 6,
"count": 12
}
}

猜猜看?這是我們存儲在數據庫中的所有課程的列表。現在,您的前端應用程序可以遍歷所有這些項目,并以一種吸引人的方式向用戶展示它們。這就是API的強大之處。

Image

整個課程的評級將根據作業文檔中提到的章節總和進行更新。

此時,如果您想查看API的文檔,可以通過導航到http://127.0.0.1:8000/docs端點來查看。這個可導航的API是與FastAPI一起預先打包的。是不是很酷?

Image

適用于所有 API 端點的 FastAPI 文檔

不喜歡文檔的樸素外觀嗎?別擔心,還有一個具有稍微更華麗界面的端點。只需導航到http://127.0.0.1:8000/redoc,您將會看到這個屏幕:

FastAPI 備用 redoc 界面,帶有搜索和下載選項

獲取課程概述端點 ( – GET)

您將使用此終端節點來獲取特定課程的概述。只需在 URL 中提供course_id,API 就會返回有關該特定課程的詳細信息。

@app.get('/courses/{course_id}')
def get_course(course_id: str):
course = db.courses.find_one({'_id': ObjectId(course_id)}, {'_id': 0, 'chapters': 0})
if not course:
raise HTTPException(status_code=404, detail='Course not found')
try:
course['rating'] = course['rating']['total']
except KeyError:
course['rating'] = 'Not rated yet'

return course

此代碼片段會在MongoDB數據庫中搜索具有指定course_id的課程,并提取課程信息,同時省略field.course_id和chapters字段。

如果找不到該課程,它會拋出一個狀態碼為404的HTTPException異常。如果找到了,它會嘗試訪問rating字段,并將其替換為其’total’值以顯示總評分。如果沒有找到rating字段,則會將框設置為“尚未評分”。

最后,省略chapters字段后,它返回包含總評分的課程信息的JSON響應。

單個課程概述端點響應

獲取特定章節信息端點 ( – GET)

訪問此端點將返回課程中某個章節的具體信息。通過在URL中指定course_idchapter_id,您可以獲取該特定章節的詳細信息。

@app.get('/courses/{course_id}/{chapter_id}')
def get_chapter(course_id: str, chapter_id: str):
course = db.courses.find_one({'_id': ObjectId(course_id)}, {'_id': 0, })
if not course:
raise HTTPException(status_code=404, detail='Course not found')
chapters = course.get('chapters', [])
try:
chapter = chapters[int(chapter_id)]
except (ValueError, IndexError) as e:
raise HTTPException(status_code=404, detail='Chapter not found') from e
return chapter

其中,course_id代表課程的身份標識,而chapter_id則是在該課程內部的章節標識符。

當向此端點發送請求時,代碼會首先在MongoDB數據庫中搜索具有指定course_id的課程,并在響應中忽略_id列。

如果數據庫中找不到具有所提供course_id的課程,代碼將拋出一個狀態碼為404的HTTPException異常,表明無法找到該課程。

然后,代碼使用GET函數來檢索該課程的章節列表,如果chapters字段不存在,則將其默認值設置為空列表。

利用請求中提供的chapter_id,代碼會嘗試在章節列表中檢索出確切的章節。如果chapter_id不是有效的整數或超出了章節列表的范圍,代碼將拋出一個狀態碼為404的HTTPException異常,表明無法找到該章節。

如果找到了該章節,響應中將包含該課程內該章節的詳細信息。

章節詳細信息端點

Rate Chapter 終端節點 ( – POST)

此端點允許用戶對課程中的各個章節進行評分。您可以提供1分表示正面評價,或-1分表示負面評價。API會匯總每個課程的所有評分,為未來改進提供寶貴的反饋。

到目前為止,我們主要看到了GET請求。但現在,讓我們來看看如何向服務器發送數據、驗證數據并將其插入到應用程序數據庫中。

@app.post('/courses/{course_id}/{chapter_id}')
def rate_chapter(course_id: str, chapter_id: str, rating: int = Query(..., gt=-2, lt=2)):
course = db.courses.find_one({'_id': ObjectId(course_id)}, {'_id': 0, })
if not course:
raise HTTPException(status_code=404, detail='Course not found')
chapters = course.get('chapters', [])
try:
chapter = chapters[int(chapter_id)]
except (ValueError, IndexError) as e:
raise HTTPException(status_code=404, detail='Chapter not found') from e
try:
chapter['rating']['total'] += rating
chapter['rating']['count'] += 1
except KeyError:
chapter['rating'] = {'total': rating, 'count': 1}
db.courses.update_one({'_id': ObjectId(course_id)}, {'$set': {'chapters': chapters}})
return chapter

我們已經設置了一個端點,允許用戶通過向特定URL發送HTTP POST請求來為課程中的每個章節打分。用戶可以為正面評價提供1作為評分值,或為負面評價提供-1。代碼查詢MongoDB數據庫以找到具有指定course_idchapter_id的課程,同時排除某些字段。

如果找不到該課程,它會拋出一個狀態碼為404的HTTP異常。代碼會檢索章節列表,并將其默認值設置為空列表。

如果chapter_id不是有效的整數或超出范圍,它會拋出一個狀態碼為404的HTTPException。如果找到了該章節,代碼會根據提供的評分更新其評分,具體做法是:將評分值與提供的評分相加,并增加總計數。

如果章節沒有現有的評分字段,它會創建一個新的字段,并用提供的評分和計數1進行初始化。然后,將更新后的評分更新到數據庫中,并返回更新后的章節作為響應,向用戶提供他們對該章節評分的反饋。

Image

向章節添加評級的 POST 請求

要發出 POST 請求,請打開文檔并單擊上圖中突出顯示的請求。然后,點擊 “Try it out”,填寫帖子數據,然后按下面的 Execute 按鈕。這會將 POST 數據發送到服務器,然后對其進行驗證。

如果提交的所有數據都符合預期,則服務器將接受并顯示 200 狀態代碼,這意味著操作成功。提交的數據現在位于 MongoDB 文檔中。

發布請求成功

這就是 API 開發部分的總結。

使用 PyTest 進行自動化 API 端點測試

隨著現代 Web 應用程序復雜性的增加,API 終端節點的數量及其交互也在增加。

在動態電子商務 Web 應用程序中,可能有數百個終端節點,每個終端節點都支持多種 HTTP 請求方法。這些端點可能錯綜復雜地相互連接。

確保每次開發迭代后所有這些端點的正常運行成為開發人員和 QA 團隊的一項艱巨任務。這就是自動化測試的用武之地。

在與main.pycourses.json相同的目錄中創建一個文件:test_app.py

from fastapi.testclient import TestClient
from pymongo import MongoClient
from bson import ObjectId
import pytest
from main import app

client = TestClient(app)
mongo_client = MongoClient('mongodb://localhost:27017/')
db = mongo_client['courses']

這將建立一個自動化測試環境。

FastAPI 測試客戶端模擬對 Web 應用的 HTTP 請求。有了這個功能,您可以假裝自己是一個用戶,向您的應用發送請求并獲取響應,就像真實用戶一樣。

我們使用 MongoDB 連接來存儲課程數據,而 MongoClient 支持在測試期間進行交互和數據更新。

Test Database 是一個用于測試的單獨數據庫。這不會影響實際的課程文件。

通過此配置,您現在可以創建使用 TestClient 向 FastAPI 應用程序發送請求的測試函數。在這些測試期間,您將與 MongoDB 數據庫進行交互,但不要擔心,這只是測試數據庫,因此不會損害任何重要內容。

如何測試 “Get Courses List” 端點

這些測試函數用于與FastAPI應用的“/courses”端點進行交互。它們檢查當提供不同的參數(如按領域排序和過濾)時,該端點是否按預期行為工作,TestClient用于此目的。

這些測試會驗證 API 響應中的狀態代碼、數據存在、排序順序和域篩選,從而確保課程端點的功能正確可靠。

def test_get_courses_no_params():
response = client.get("/courses")
assert response.status_code == 200

def test_get_courses_sort_by_alphabetical():
response = client.get("/courses?sort_by=alphabetical")
assert response.status_code == 200
courses = response.json()
assert len(courses) > 0
assert sorted(courses, key=lambda x: x['name']) == courses

def test_get_courses_sort_by_date():
response = client.get("/courses?sort_by=date")
assert response.status_code == 200
courses = response.json()
assert len(courses) > 0
assert sorted(courses, key=lambda x: x['date'], reverse=True) == courses

def test_get_courses_sort_by_rating():
response = client.get("/courses?sort_by=rating")
assert response.status_code == 200
courses = response.json()
assert len(courses) > 0
assert sorted(courses, key=lambda x: x['rating']['total'], reverse=True) == courses

def test_get_courses_filter_by_domain():
response = client.get("/courses?domain=mathematics")
assert response.status_code == 200
courses = response.json()
assert len(courses) > 0
assert all([c['domain'][0] == 'mathematics' for c in courses])

def test_get_courses_filter_by_domain_and_sort_by_alphabetical():
response = client.get("/courses?domain=mathematics&sort_by=alphabetical")
assert response.status_code == 200
courses = response.json()
assert len(courses) > 0
assert all([c['domain'][0] == 'mathematics' for c in courses])
assert sorted(courses, key=lambda x: x['name']) == courses

def test_get_courses_filter_by_domain_and_sort_by_date():
response = client.get("/courses?domain=mathematics&sort_by=date")
assert response.status_code == 200
courses = response.json()
assert len(courses) > 0
assert all([c['domain'][0] == 'mathematics' for c in courses])
assert sorted(courses, key=lambda x: x['date'], reverse=True) == courses

請注意assert語句。它會將預期結果與實際結果進行比較,并根據此比較返回True或False(布爾值)。目標是使所有這些測試通過,即讓這些值相等。

如何測試“獲取單個課程信息”端點

測試使用TestClient向FastAPI的“/courses/course_id”端點發送查詢,使用db.courses.find_one函數從MongoDB數據庫檢索課程數據。通過比較API響應數據和數據庫數據,可以幫助你確定該端點是否正確處理了存在和不存在的課程ID。

def test_get_course_by_id_exists():
response = client.get("/courses/6431137ab5da949e5978a281")
assert response.status_code == 200
course = response.json()
# get the course from the database
course_db = db.courses.find_one({'_id': ObjectId('6431137ab5da949e5978a281')})
# get the name of the course from the database
name_db = course_db['name']
# get the name of the course from the response
name_response = course['name']
# compare the two
assert name_db == name_response

def test_get_course_by_id_not_exists():
response = client.get("/courses/6431137ab5da949e5978a280")
assert response.status_code == 404
assert response.json() == {'detail': 'Course not found'}

如何測試 “Get Course Chapter Info” 端點

測試預期當使用TestClient發送請求時,FastAPI應用的“/courses/course_id/chapter_number”端點將為特定的課程ID和編號提供章節信息。

我們使用斷言來確定響應是否包含預期數據,或者對于不存在的章節是否給出了“未找到”響應。它驗證了是否檢索到了正確的API章節,并處理了存在和不存在的章節。

def test_get_chapter_info():
response = client.get("/courses/6431137ab5da949e5978a281/1")
assert response.status_code == 200
chapter = response.json()
assert chapter['name'] == 'Big Picture of Calculus'
assert chapter['text'] == 'Highlights of Calculus'

def test_get_chapter_info_not_exists():
response = client.get("/courses/6431137ab5da949e5978a281/990")
assert response.status_code == 404
assert response.json() == {'detail': 'Chapter not found'}

如何測試 “Post Course Rating” 端點

為了測試評級功能,測試函數指定課程 ID、章節 ID 和評級變量。它使用 TestClient 的 post 方法向“/courses/course id/chapter id”API 提交 POST 請求,在 URL 中提供課程 ID 和章節編號,并將 rating 變量作為查詢參數傳遞。

FastAPI 模擬用戶的活動來評價課程的某個章節。響應成功,狀態代碼為 200。JSON 內容針對“name”和“rating”鍵以及“total”和“count”鍵進行驗證。總評分和評分計數大于 0,表示用戶已對該章節進行評分。

def test_rate_chapter():
course_id = "6431137ab5da949e5978a281"
chapter_id = "1"
rating = 1

response = client.post(f"/courses/{course_id}/{chapter_id}?rating={rating}")

assert response.status_code == 200

# Check if the response body has the expected structure
assert "name" in response.json()
assert "rating" in response.json()
assert "total" in response.json()["rating"]
assert "count" in response.json()["rating"]

assert response.json()["rating"]["total"] > 0
assert response.json()["rating"]["count"] > 0

def test_rate_chapter_not_exists():
response = client.post("/courses/6431137ab5da949e5978a281/990/rate", json={"rating": 1})
assert response.status_code == 404
assert response.json() == {'detail': 'Not Found'}

此驗證可確保評級添加端點按預期工作,API 會返回正確的成功代碼和有關章節的預期信息,包括其名稱和更新的評級詳細信息。

通過運行命令,文件中的所有測試函數都將被執行,并且您將獲得反饋,了解端點是否按預期工作,或者是否出現了任何錯誤或回歸。這允許開發人員和QA團隊在開發周期的早期發現問題,并保持應用程序的可靠性和穩定性。運行命令pytest test_app.py即可執行測試。

如下圖所示,所有測試都通過了。干得好!隨著您在應用程序中添加更多功能和端點,請繼續添加相關的測試以驗證正確性。這被稱為測試驅動開發(TDD)。

Image

使用 Pytest 運行 API 測試

運行Pytest命令會顯示如上圖所示的輸出。它表示有13個測試通過了。這意味著我們的所有端點都能正常工作,并返回預期的響應。

通過檢測回歸、集成組件、解決錯誤、進行負載和性能測試以及安全測試,端點測試驗證了應用程序的基本操作是否正確。所有潛在的弱點和漏洞都會被記錄下來并標記以供檢查。

Pytest有助于確保API端點能夠很好地協同工作,并幫助您處理失敗情況和邊緣案例。它能夠在實際情況中管理大量的并發大請求。

如何使用 Docker 容器化應用程序

您可以將應用程序及其所有依賴項放在一個稱為容器的單元中。這稱為容器化。它將應用程序與底層系統分開,從而在不同操作系統之間保持一致性。

Docker 是一種現代容器化技術,可以更輕松地創建、分發和執行容器。它使開發人員能夠一致且可重復地構建、交付和執行應用程序,而無需從源代碼構建。

從以下網址安裝Docker:https://www.docker.com/get-started。

Docker 化 Python 程序可幫助您確保它們在多臺計算機上一致地運行,從而消除兼容性問題。它將軟件、其依賴項和自定義內容容器化,使其具有可移植性。

在與其他文件相同的目錄中,創建一個新文件,命名為Dockerfile(注意,它不需要任何擴展名)。

# Use an official Python runtime as a parent image
FROM python:3.9-slim-buster

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /code
WORKDIR /app

COPY ./requirements.txt /app/requirements.txt

# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt

COPY . /app

# Run app.py when the container launches
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]

從官方的Python 3.9精簡鏡像開始,Dockerfile定義了鏡像的藍圖。

它更改工作目錄到/app,這是應用程序代碼將存儲的位置。該項目的依賴項被列在requirements.txt文件中,該文件已被放入容器中。

RUN命令使用pip來安裝Python依賴項。COPY命令將應用程序的代碼從主機移動到容器的/app目錄。CMD命令提供了容器啟動時將要執行的命令。

在這種情況下,它運行“uvicorn main:app”(main.py中的FastAPI應用程序),并將主機設置為0.0.0.0,端口設置為80。

如何運行 Docker 容器

在與Dockerfile相同的目錄中,使用以下命令構建Docker鏡像:docker build -t my_python_app .

使用 Docker 容器化 FastAPI 應用程序

使用以下命令以分離模式運行容器:docker run -d -p 80:80 my_python_app

完成此操作后,您可以從 Docker Desktop 查看容器和映像的狀態。

Docker Desktop 顯示我們的容器映像現在在端口 80 上處于運行狀態

如何終止 Docker 容器

使用docker ps命令查找容器ID或名稱。使用其ID或名稱停止容器:

docker stop <container_id_or_name>

本指南僅涵蓋了開發、測試和容器化方面的內容。但請注意,如果忽視部署后的容器安全,可能會帶來漏洞、配置錯誤和攻擊等風險。理想情況下,您應該利用CNAPP(云原生應用保護平臺)來掃描鏡像、遵循最佳實踐,并監控運行中的容器以確保安全。

重要的是,Docker容器化允許將Python腳本與其依賴項捆綁在一起,使它們保持一致性和可移植性。Dockerfile描述了如何創建鏡像。

在構建完鏡像后運行容器只需執行一個命令。同樣,停止容器也非常簡單。Docker簡化了Python應用程序的分發管理。

結論

本教程是一個快速入門指南,可幫助您利用 FastAPI 的強大功能。我們構建了一個課程管理 API,可以有效地處理與課程相關的查詢。

我們通過將課程數據從JSON文件導入MongoDB,然后創建了多個端點,供用戶訪問課程列表、概覽、章節信息和用戶分數。我們還添加了一個評論聚合功能,以展示如何使用HTTP POST和HTTP GET方法,從而可以從服務器抓取數據以及向服務器發送數據。

PyTest幫助我們處理自動化測試,確保了可靠性和穩定性。接著,我們將應用程序容器化,使用Docker來簡化部署和維護。

我的GitHub倉庫中包含了本快速入門指南所涵蓋的完整代碼。歡迎訂閱我的技術博客,獲取技術速查表和資源。

原文鏈接:https://www.freecodecamp.org/news/fastapi-quickstart/

上一篇:

x開頭的單詞及其應用場景

下一篇:

什么是AI:人工智能深度解析與應用展示
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費