FastAPI¶
فریمورک FastAPI، کارایی بالا، یادگیری آسان، کدنویسی سریع، آماده برای استفاده در محیط پروداکشن
مستندات: https://fastapi.tiangolo.com
کد منبع: https://github.com/fastapi/fastapi
FastAPI یک وب فریمورک مدرن و سریع (با کارایی بالا) برای ایجاد APIهای متنوع (وب، وبسوکت و غبره) با زبان پایتون نسخه +۳.۶ است. این فریمورک با رعایت کامل راهنمای نوع داده (Type Hint) ایجاد شده است.
ویژگیهای کلیدی این فریمورک عبارتند از:
-
سرعت: کارایی بسیار بالا و قابل مقایسه با NodeJS و Go (با تشکر از Starlette و Pydantic). یکی از سریعترین فریمورکهای پایتونی موجود.
-
کدنویسی سریع: افزایش ۲۰۰ تا ۳۰۰ درصدی سرعت توسعه قابلیتهای جدید. *
- باگ کمتر: کاهش ۴۰ درصدی خطاهای انسانی (برنامهنویسی). *
- هوشمندانه: پشتیبانی فوقالعاده در محیطهای توسعه یکپارچه (IDE). تکمیل در همه بخشهای کد. کاهش زمان رفع باگ.
- آسان: طراحی شده برای یادگیری و استفاده آسان. کاهش زمان مورد نیاز برای مراجعه به مستندات.
- کوچک: کاهش تکرار در کد. چندین قابلیت برای هر پارامتر (منظور پارامترهای ورودی تابع هندلر میباشد، به بخش خلاصه در همین صفحه مراجعه شود). باگ کمتر.
- استوار: ایجاد کدی آماده برای استفاده در محیط پروداکشن و تولید خودکار مستندات تعاملی
- مبتنی بر استانداردها: مبتنی بر (و منطبق با) استانداردهای متن باز مربوط به API: OpenAPI (سوگر سابق) و JSON Schema.
* تخمینها بر اساس تستهای انجام شده در یک تیم توسعه داخلی که مشغول ایجاد برنامههای کاربردی واقعی بودند صورت گرفته است.
اسپانسرهای طلایی¶
نظر دیگران در مورد FastAPI¶
Typer, فریمورکی معادل FastAPI برای کار با واسط خط فرمان¶
اگر در حال ساختن برنامهای برای استفاده در CLI (به جای استفاده در وب) هستید، میتوانید از Typer. استفاده کنید.
Typer دوقلوی کوچکتر FastAPI است و قرار است معادلی برای FastAPI در برنامههای CLI باشد.️ 🚀
نیازمندیها¶
پایتون +۳.۶
FastAPI مبتنی بر ابزارهای قدرتمند زیر است:
نصب¶
$ pip install fastapi
---> 100%
نصب یک سرور پروداکشن نظیر Uvicorn یا Hypercorn نیز جزء نیازمندیهاست.
$ pip install "uvicorn[standard]"
---> 100%
مثال¶
ایجاد کنید¶
- فایلی به نام
main.py
با محتوای زیر ایجاد کنید:
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
همچنین میتوانید از async def
... نیز استفاده کنید
اگر در کدتان از async
/ await
استفاده میکنید، از async def
برای تعریف تابع خود استفاده کنید:
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
توجه:
اگر با async / await
آشنا نیستید، به بخش "عجله دارید?" در صفحه درباره async
و await
در مستندات مراجعه کنید.
اجرا کنید¶
با استفاده از دستور زیر سرور را اجرا کنید:
$ uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
درباره دستور uvicorn main:app --reload
...
دستور uvicorn main:app
شامل موارد زیر است:
main
: فایلmain.py
(ماژول پایتون ایجاد شده).app
: شیء ایجاد شده در فایلmain.py
در خطapp = FastAPI()
.--reload
: ریستارت کردن سرور با تغییر کد. تنها در هنگام توسعه از این گزینه استفاده شود..
بررسی کنید¶
آدرس http://127.0.0.1:8000/items/5?q=somequery را در مرورگر خود باز کنید.
پاسخ JSON زیر را مشاهده خواهید کرد:
{"item_id": 5, "q": "somequery"}
تا اینجا شما APIای ساختید که:
- درخواستهای HTTP به مسیرهای
/
و/items/{item_id}
را دریافت میکند. - هردو مسیر عملیات (یا HTTP متد)
GET
را پشتیبانی میکند. - مسیر
/items/{item_id}
شامل پارامتر مسیرitem_id
از نوعint
است. - مسیر
/items/{item_id}
شامل پارامتر پرسمان اختیاریq
از نوعstr
است.
مستندات API تعاملی¶
حال به آدرس http://127.0.0.1:8000/docs بروید.
مستندات API تعاملی (ایجاد شده به کمک Swagger UI) را مشاهده خواهید کرد:
مستندات API جایگزین¶
حال به آدرس http://127.0.0.1:8000/redoc بروید.
مستندات خودکار دیگری را مشاهده خواهید کرد که به کمک ReDoc ایجاد میشود:
تغییر مثال¶
حال فایل main.py
را مطابق زیر ویرایش کنید تا بتوانید بدنه یک درخواست PUT
را دریافت کنید.
به کمک Pydantic بدنه درخواست را با انواع استاندارد پایتون تعریف کنید.
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: Union[bool, None] = None
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
سرور به صورت خودکار ریاستارت میشود (زیرا پیشتر از گزینه --reload
در دستور uvicorn
استفاده کردیم).
تغییر مستندات API تعاملی¶
مجددا به آدرس http://127.0.0.1:8000/docs بروید.
- مستندات API تعاملی به صورت خودکار بهروز شده است و شامل بدنه تعریف شده در مرحله قبل است:
- روی دکمه "Try it out" کلیک کنید، اکنون میتوانید پارامترهای مورد نیاز هر API را مشخص کرده و به صورت مستقیم با آنها تعامل کنید:
- سپس روی دکمه "Execute" کلیک کنید، خواهید دید که واسط کاربری با APIهای تعریف شده ارتباط برقرار کرده، پارامترهای مورد نیاز را به آنها ارسال میکند، سپس نتایج را دریافت کرده و در صفحه نشان میدهد:
تغییر مستندات API جایگزین¶
حال به آدرس http://127.0.0.1:8000/redoc بروید.
- خواهید دید که مستندات جایگزین نیز بهروزرسانی شده و شامل پارامتر پرسمان و بدنه تعریف شده میباشد:
خلاصه¶
به طور خلاصه شما یک بار انواع پارامترها، بدنه و غیره را به عنوان پارامترهای ورودی تابع خود تعریف میکنید.
این کار را با استفاده از انواع استاندارد و مدرن موجود در پایتون انجام میدهید.
نیازی به یادگیری نحو جدید یا متدها و کلاسهای یک کتابخانه بخصوص و غیره نیست.
تنها پایتون +۳.۶.
به عنوان مثال برای یک پارامتر از نوع int
:
item_id: int
یا برای یک مدل پیچیدهتر مثل Item
:
item: Item
...و با همین اعلان تمامی قابلیتهای زیر در دسترس قرار میگیرد:
- پشتیبانی ویرایشگر متنی شامل:
- تکمیل کد.
- بررسی انواع داده.
- اعتبارسنجی داده:
- خطاهای خودکار و مشخص در هنگام نامعتبر بودن داده.
- اعتبارسنجی، حتی برای اشیاء JSON تو در تو.
- تبدیل داده ورودی: که از شبکه رسیده به انواع و داده پایتونی. این داده شامل:
- JSON.
- پارامترهای مسیر.
- پارامترهای پرسمان.
- کوکیها.
- سرآیندها (هدرها).
- فرمها.
- فایلها.
- تبدیل داده خروجی: تبدیل از انواع و داده پایتون به داده شبکه (مانند JSON):
- تبدیل انواع داده پایتونی (
str
,int
,float
,bool
,list
و غیره). - اشیاء
datetime
. - اشیاء
UUID
. - qمدلهای پایگاهداده.
- و موارد بیشمار دیگر.
- تبدیل انواع داده پایتونی (
- دو مدل مستند API تعاملی خودکار :
- Swagger UI.
- ReDoc.
به مثال قبلی باز میگردیم، در این مثال FastAPI موارد زیر را انجام میدهد:
- اعتبارسنجی اینکه پارامتر
item_id
در مسیر درخواستهایGET
وPUT
موجود است. - اعتبارسنجی اینکه پارامتر
item_id
در درخواستهایGET
وPUT
از نوعint
است.- اگر غیر از این موارد باشد، سرویسگیرنده خطای مفید و مشخصی دریافت خواهد کرد.
- بررسی وجود پارامتر پرسمان اختیاری
q
(مانندhttp://127.0.0.1:8000/items/foo?q=somequery
) در درخواستهایGET
.- از آنجا که پارامتر
q
با= None
مقداردهی شده است، این پارامتر اختیاری است. - اگر از مقدار اولیه
None
استفاده نکنیم، این پارامتر الزامی خواهد بود (همانند بدنه درخواست در درخواستPUT
).
- از آنجا که پارامتر
- برای درخواستهای
PUT
به آدرس/items/{item_id}
، بدنه درخواست باید از نوع JSON تعریف شده باشد:- بررسی اینکه بدنه شامل فیلدی با نام
name
و از نوعstr
است. - بررسی اینکه بدنه شامل فیلدی با نام
price
و از نوعfloat
است. - بررسی اینکه بدنه شامل فیلدی اختیاری با نام
is_offer
است، که در صورت وجود باید از نوعbool
باشد. - تمامی این موارد برای اشیاء JSON در هر عمقی قابل بررسی میباشد.
- بررسی اینکه بدنه شامل فیلدی با نام
- تبدیل از/به JSON به صورت خودکار.
- مستندسازی همه چیز با استفاده از OpenAPI، که میتوان از آن برای موارد زیر استفاده کرد:
- سیستم مستندات تعاملی.
- تولید خودکار کد سرویسگیرنده در زبانهای برنامهنویسی بیشمار.
- فراهم سازی ۲ مستند تعاملی مبتنی بر وب به صورت پیشفرض.
موارد ذکر شده تنها پارهای از ویژگیهای بیشمار FastAPI است اما ایدهای کلی از طرز کار آن در اختیار قرار میدهد.
خط زیر را به این صورت تغییر دهید:
return {"item_name": item.name, "item_id": item_id}
از:
... "item_name": item.name ...
به:
... "item_price": item.price ...
در حین تایپ کردن توجه کنید که چگونه ویرایشگر، ویژگیهای کلاس Item
را تشخیص داده و به تکمیل خودکار آنها کمک میکند:
برای مشاهده مثالهای کاملتر که شامل قابلیتهای بیشتری از FastAPI باشد به بخش آموزش - راهنمای کاربر مراجعه کنید.
هشدار اسپویل: بخش آموزش - راهنمای کاربر شامل موارد زیر است:
- اعلان پارامترهای موجود در بخشهای دیگر درخواست، شامل: سرآیند (هدر)ها، کوکیها، فیلدهای فرم و فایلها.
- چگونگی تنظیم محدودیتهای اعتبارسنجی به عنوان مثال
maximum_length
یاregex
. - سیستم Dependency Injection قوی و کاربردی.
- امنیت و تایید هویت, شامل پشتیبانی از OAuth2 مبتنی بر JWT tokens و HTTP Basic.
- تکنیک پیشرفته برای تعریف مدلهای چند سطحی JSON (بر اساس Pydantic).
- قابلیتهای اضافی دیگر (بر اساس Starlette) شامل:
- وبسوکت
- GraphQL
- تستهای خودکار آسان مبتنی بر HTTPX و
pytest
- CORS
- Cookie Sessions
- و موارد بیشمار دیگر.
کارایی¶
معیار (بنچمارک)های مستقل TechEmpower حاکی از آن است که برنامههای FastAPI که تحت Uvicorn اجرا میشود، یکی از سریعترین فریمورکهای مبتنی بر پایتون، است که کمی ضعیفتر از Starlette و Uvicorn عمل میکند (فریمورک و سروری که FastAPI بر اساس آنها ایجاد شده است) (*)
برای درک بهتری از این موضوع به بخش بنچمارکها مراجعه کنید.
نیازمندیهای اختیاری¶
استفاده شده توسط Pydantic:
email-validator
- برای اعتبارسنجی آدرسهای ایمیل.
استفاده شده توسط Starlette:
HTTPX
- در صورتی که میخواهید ازTestClient
استفاده کنید.aiofiles
- در صورتی که میخواهید ازFileResponse
وStaticFiles
استفاده کنید.jinja2
- در صورتی که بخواهید از پیکربندی پیشفرض برای قالبها استفاده کنید.python-multipart
- در صورتی که بخواهید با استفاده ازrequest.form()
از قابلیت "تجزیه (parse)" فرم استفاده کنید.itsdangerous
- در صورتی که بخواید ازSessionMiddleware
پشتیبانی کنید.pyyaml
- برای پشتیبانیSchemaGenerator
در Starlet (به احتمال زیاد برای کار کردن با FastAPI به آن نیازی پیدا نمیکنید).graphene
- در صورتی که ازGraphQLApp
پشتیبانی میکنید.
استفاده شده توسط FastAPI / Starlette:
uvicorn
- برای سرور اجرا کننده برنامه وب.orjson
- در صورتی که بخواهید ازORJSONResponse
استفاده کنید.ujson
- در صورتی که بخواهید ازUJSONResponse
استفاده کنید.
میتوان همه این موارد را با استفاده از دستور pip install fastapi[all]
. به صورت یکجا نصب کرد.
لایسنس¶
این پروژه مشمول قوانین و مقررات لایسنس MIT است.