Ninja Learn | نینجا لرن
1.25K subscribers
96 photos
36 videos
11 files
307 links
یادگیری برنامه نویسی به سبک نینجا 🥷
اینجا چیزایی یاد میگیری که فقط نینجاهای وب‌ بلدن 🤫

📄 Send me post: https://t.me/NoronChat_bot?start=sec-fdggghgebe

👥 ɢʀᴏᴜᴘ: https://t.me/+td1EcO_YfSphNTlk
Download Telegram
🚀 معرفی FastAPI

ـ FastAPI یه فریم ورک پایتونیه که باهاش میشه داخل پایتون api توسعه داد که تازگیا خیلییی بین پایتون کارا سرو و صدا کرده.
ـFastAPI یه فریم‌ورک مدرن برای ساختن APIبا پایتون و ویژگی هایی مثل async/await که بهینه شده و... . خیلی از شرکت‌های بزرگ مثل Netflix و Uber برای توسعه سرویس‌هاشون از FastAPI استفاده می‌کنن، و دلیلش هم مشخصه: سریع، ساده و انعطاف‌پذیره.

💡 چرا FastAPI محبوبه؟
سریع‌ترین فریم‌ورک پایتون: FastAPI به لطف استفاده از Starlette و Pydantic، یکی از سریع‌ترین فریم‌ورک‌های پایتون حساب می‌شه.

کدنویسی سریع‌تر: تایپ‌هینت‌های پایتون باعث می‌شه نوشتن کدها هم سریع‌تر باشه و هم باگ‌های کمتری داشته باشی.

مستندات خودکار: یکی از بهترین ویژگی‌های FastAPI اینه که خودش به‌طور اتوماتیک با Swagger UI و ReDoc مستندات API رو برات می‌سازه.

پشتیبانی از async/await: فست خیلی خوب از کدونیسی async ساپورت میکنه و یکی از دلایل محبوبیتشه.

🛠 ـFastAPI و کار با دیتابیس
وقتی می‌خوای با دیتابیس کار کنی، معمولاً از ORMها استفاده می‌کنی. تو FastAPI دو تا گزینه معروف داریم:
ـSQLAlchemy
ـSQLModel
حالا کدوم بهتره؟ بیاین دقیق‌تر بررسی کنیم:

ـ🔍 SQLAlchemy؛ قدیمی و قدرتمند
ـSQLAlchemy یکی از معروف‌ترین ORMها برای پایتونه که زیاد استفاده میشه. انعطاف‌پذیری بالایی داره و برای پروژه‌های پیچیده و بزرگ گزینه خیلی خوبیه.
مزیت‌ها:
کنترل کامل روی کوئری‌ها و عملکرد دیتابیس
پشتیبانی از تراکنش‌ها و مدل‌های پیچیده
جامعه کاربری بزرگ و منابع آموزشی زیاد
چالش‌ها:
سینتکسش برای تازه‌کارها ممکنه سخت و پیچیده باشه
نوشتن کدهای زیاد برای مدل‌سازی

ـ🌀 SQLModel؛ ساده و مدرن
ـSQLModel یه کتابخونه جدیدتره که توسط خالق FastAPI یعنی Sebastián Ramírez توسعه داده شده. هدف SQLModel اینه که کار با دیتابیس رو ساده‌تر کنه و کدنویسی رو شبیه به Pydantic (برای ولیدیشن) بکنه.
مزیت‌ها:
سینتکس خیلی ساده و خوانا
پشتیبانی از تایپ‌هینت‌های پایتون
هماهنگی عالی با FastAPI
کمتر شدن کدنویسی و مدل‌سازی سریع
چالش‌ها:
هنوز نسبت به SQLAlchemy به بلوغ کامل نرسیده
برای پروژه‌های خیلی پیچیده ممکنه محدودیت‌هایی داشته باشه

مقایسه کدها
مدل‌سازی با SQLAlchemy:
from sqlalchemy import Column, Integer, String  
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)


مدل‌سازی با SQLModel:
from sqlmodel import SQLModel, Field  

class User(SQLModel, table=True):
id: int = Field(default=None, primary_key=True)
name: str = Field(index=True)


همون‌طور که می‌بینید، SQLModel خیلی تمیزتر و کوتاه‌تره و شبیه به Pydantic می‌شه.

🎯 بالاخره SQLAlchemy یا SQLModel؟
اگه تازه‌کار هستی یا پروژه‌ت کوچیکه و می‌خوای سریع کارت راه بیفته، SQLModel گزینه بهتریه. سینتکس ساده‌ای داره و هماهنگیش با FastAPI عالیه.
ولی اگه پروژه‌ت بزرگه یا نیاز به کنترل کامل و قابلیت‌های بیشتر ORM داری ، SQLAlchemy انتخاب بهتریه.
خلاصه:
پروژه‌های کوچیک و متوسط SQLModel
پروژه‌های بزرگ و پیچیده SQLAlchemy

امید وارم مفید بوده باشه :)

#python #fastapi


🔆 CHANNEL | GROUP
21👍5
تا حالا کلی مطالب خفن و کاربردی تو کانال NinjaLearn براتون آماده کردیم و الان صدها مطلب مختلف و جذاب داریم.

از اونجایی که مطالب کانال خیلی متنوع و زیاد شده، تصمیم گرفتیم یه دسته‌بندی مرتب و منظم برای همه‌ی پست‌ها داشته باشیم تا شما عزیزان راحت‌تر بتونید محتوای مورد نظرتون رو پیدا کنید

این شما و این لیست دسته‌بندی‌های کانال🔻:

🦫 #go: آموزش‌ها و نکات کاربردی زبان گو

💻 #programming: مطالب برنامه نویسی

🐍 #python: ترفندها و نکات پایتونی

🦄 #django: مطالب فریم‌ورک جنگو

⚡️ #fastapi: مطالب فریم ورک فست

🌐 #web: مطالب مرتبط به وب

📡 #network: مطالب مرتبط به شبکه

🗂️ #db: معرفی و نکات دیتابیس

🔖 #reference: معرفی مقاله و ویدیو

📢 #notif: اطلاع رسانی ها

#question: سوالات جالب در برنامه نویسی

🎊 #event: رویداد هایی که معرفی کردیم

🎬 #movie: معرفی فیلم و سریال

📚 #book: معرفی کتاب‌های تخصصی

🤖 #AI: مطالب مرتبط به هوش مصنوعی

📊 #ml: مطالب مرتبط به یادگیری ماشین

🛠️ #backend: آموزش‌ها و ترفندهای بک‌اند

🔒 #security: نکات امنیتی

#devops: مطالب مرتبط به دواپس

📺 #YouTube: ویدیوهای چنل یوتیوب ما


هر کدوم از این هشتگ‌ها برای یه موضوع خاص طراحی شده تا شما به راحتی بتونید محتوای مورد نظرتون رو پیدا کنید. دیگه لازم نیست کلی تو کانال بگردید 😊

اگه موضوع جدیدی به مطالب کانال اضافه بشه، حتماً تو این لیست قرار می‌گیره


راستی میتونید بنر کانال رو برای دوستاتون هم بفرستید تا اونا هم به جمع ما بپیوندن و از این مطالب مفید استفاده کنن 😉

NinjaLearn Banner 🥷🤝


#category



🔆 CHANNEL | GROUP
22👍1👎1🔥1
⚡️ خب خب خب starlette چیست؟ ⚡️

ـStarlette یکی از فریم‌ورک‌های عالی برای ساخت اپلیکیشن‌های وب در پایتونه که به طور خاص برای پردازش درخواست‌ها به صورت غیرهمزمان (async) ساخته شده. این فریم‌ورک با استفاده از ASGI (Asynchronous Server Gateway Interface)
سرعت و کارایی بالایی رو به ما میده.

یکی از ویژگی‌های خوب Starlette اینه که خیلی سبک و کم‌حجم هست، به طوری که می‌تونید به راحتی ازش برای ساخت سرویس‌ها و API های پیچیده استفاده کنید بدون اینکه بخواید با پیچیدگی‌های اضافی روبه‌رو بشید. 🚀

پشت صحنه‌ی Starlette 🎬
ـASGI:
ـStarlette از ASGI به جای WSGI استفاده می‌کنه. این تغییر باعث میشه که تو بتونی درخواست‌ها رو به صورت همزمان پردازش کنی و کارایی بهتری داشته باشی، مخصوصاً در مواقعی که نیاز به پردازش‌های طولانی یا مولتی تسک داری.
ـNon-blocking I/O:
با non-blocking I/O درخواستو عملیات ها منتظر نمی‌مونن. این یعنی که هر درخواست به سرعت پردازش می‌شه و سیستم هیچ‌وقت از کار نمی‌افته.
ـEvent-driven:
ـStarlette معماری event-driven داره، به این معنی که هیچ عملیات غیرضروری انجام نمیده. فقط وقتی که یه اتفاقی بیفته، کاری انجام می‌ده، که باعث میشه سرعت پردازش بالاتر بره.
ـMiddleware:
ـStarlette کاملاً روی middleware ها بنا شده که می‌تونید به راحتی ویژگی‌هایی مثل لاگینگ، احراز هویت، یا مدیریت خطاها رو به برنامه اضافه کنید.
ـUvicorn:
معمولا از Uvicorn برای راه‌اندازی اپلیکیشن استفاده میشه که یه سرور ASGI خیلی سریع و سبک هست. این باعث میشه که اپلیکیشن شما به راحتی به HTTP/2 و WebSocket متصل بشه.
چرا Starlette سریع‌تره؟ 💨
سبک بودن:
ـStarlette به شدت مینیمال طراحی شده و چیز اضافی توش نیست که بخواد سرعت رو پایین بیاره. به همین خاطر به راحتی می‌تونید اپلیکیشن‌هایی با کارایی بالا بسازید.

پشتیبانی از async:
استفاده از async و await برای پردازش درخواست‌ها بصورت همزمان باعث میشه تا اپلیکیشن شما بدون هیچ کندی درخواست‌ها رو پردازش کنه. این یه ویژگی خیلی مهم برای اپلیکیشن‌هایی هست که نیاز به سرعت بالا دارن.

ـUvicorn:
ـ Uvicorn باعث میشه که اپلیکیشن‌ها با کمترین تأخیر و بیشترین کارایی اجرا بشن.

پشتیبانی از WebSocket:
ـStarlette از WebSocket به خوبی پشتیبانی می‌کنه که باعث میشه اپلیکیشن‌های real time سریع و کارآمد اجرا بشن.

ویژگی‌های کاربردی Starlette 🛠️
ـWebSocket:
پشتیبانی از WebSocket برای اپلیکیشن‌های realt time مثل چت یا نوتیفیکیشن‌های زنده.


ـBackground Tasks:
امکان اجرای کارهای پس‌زمینه‌ای مثل ارسال ایمیل یا پردازش داده‌ها بدون معطلی کاربر.


ـMiddleware قدرتمند:
می‌تونید به راحتی هر middleware دلخواهی رو برای احراز هویت، لاگینگ و موارد دیگه اضافه کنید.


ـRouting منعطف:
مسیرهای URL رو می‌تونید به صورت خیلی دقیق و منعطف تعریف کنید.


و...

چرا starllete باعث سرعت Fastapi میشه؟ 🔄
در حقیقت، FastAPI یه فریم‌ورک مبتنی بر Starlette هست که ویژگی‌هایی مثل Pydantic برای اعتبارسنجی و OpenAPI برای مستندسازی خودکار API‌ها و... موارد دیگه رو اضافه کرده. بنابراین، FastAPI از Starlette استفاده می‌کنه.
پس الان کاملا براتون واضح هست که چرا Fastapi سریع هست

نمونه کد ساده از Starlette 🖥️
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route

async def homepage(request):
return JSONResponse({'message': 'Hello, Starlette!'})

routes = [
Route("/", endpoint=homepage)
]

app = Starlette(debug=True, routes=routes)

برای اجرای اپلیکیشن:
uvicorn app:app --reload 


اینم سایت خود starllette
https://www.starlette.io/


شیرو و ریکشن فراموش نشه ❤️


#programming #fastapi #web



🔆 CHANNEL | GROUP
15👍5
خب خب خب WebSocket در Fastapi 🌀

امروز می‌خوام درباره‌ی یه موضوع باحال و کاربردی تو دنیای وب حرف بزنم: پیاده‌سازی WebSocket در FastAPI اگه دنبال ساخت اپلیکیشن‌های realtime مثل چت، داشبوردهای زنده یا بازی‌های آنلاین هستین، این پست براتون خیلی مفیده. پس با من همراه باشین تا با هم یاد بگیریم WebSocket چیه و چطور می‌تونیم تو FastAPI ازش استفاده کنیم.

🧠 WebSocket چیه و چرا مهمه؟
‏ WebSocket یه پروتکل ارتباطیه که به کلاینت (مثل مرورگر) و سرور اجازه می‌ده یه ارتباط دوطرفه و همیشگی داشته باشن. برعکس HTTP که فقط یه درخواست می‌فرستی و یه پاسخ می‌گیری، WebSocket این امکان رو می‌ده که هر دو طرف هر وقت خواستن پیام بفرستن و بگیرن، بدون اینکه نیاز باشه کلاینت مدام درخواست بفرسته. این برای اپلیکیشن‌هایی که نیاز به آپدیت‌های زنده دارن، مثل چت روم‌ها، اعلان‌های realtime یا بازی‌های آنلاین، عالیه

🚀 FastAPI و WebSocket

FastAPI یه فریم‌ورک وب مدرن و سریع برای پایتونه. یکی از قابلیت‌های باحالش هم پشتیبانی از WebSocketه. FastAPI از Starlette استفاده می‌کنه (یه فریم‌ورک ASGI سبک و قدرتمند)، و همین باعث می‌شه بتونیم به راحتی WebSocket رو پیاده‌سازی کنیم.

🛠 چطوری WebSocket رو تو FastAPI پیاده‌سازی کنیم؟

برای شروع، باید از کلاس WebSocket تو FastAPI استفاده کنیم. بیاین با یه مثال ساده شروع کنیم:
from fastapi import FastAPI, WebSocket

app = FastAPI()

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"پیامت این بود: {data}")

تو این کد:
یه endpoint به اسم /ws ساختیم.

وقتی کلاینت بهش وصل می‌شه، سرور با accept() ارتباط رو قبول می‌کنه.

بعدش تو یه حلقه پیام‌های کلاینت رو می‌گیره و همونو برمی‌گردونه.


به این می‌گن یه Echo Server ساده هر چی کلاینت بفرسته، سرور عینشو برمی‌گردونه.

📡 یه مثال پیشرفته‌تر: چت روم با WebSocket

حالا بیاین یه چیز باحال‌تر بسازیم، مثلاً یه چت روم که چندتا کلاینت بتونن بهش وصل بشن و پیام‌هاشون رو به هم بفرستن. برای این کار، باید اتصال‌های فعال رو مدیریت کنیم. یه کلاس به اسم ConnectionManager می‌سازیم که لیست اتصال‌ها رو نگه داره و بتونیم بهشون پیام بفرستیم یا به همه broadcast کنیم.
from fastapi import FastAPI, WebSocket
from typing import List

app = FastAPI()

class ConnectionManager:
def __init__(self):
self.active_connections: List[WebSocket] = []

async def connect(self, websocket: WebSocket):
await websocket.accept()
self.active_connections.append(websocket)

def disconnect(self, websocket: WebSocket):
self.active_connections.remove(websocket)

async def send_personal_message(self, message: str, websocket: WebSocket):
await websocket.send_text(message)

async def broadcast(self, message: str):
for connection in self.active_connections:
await connection.send_text(message)

manager = ConnectionManager()

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await manager.connect(websocket)
try:
while True:
data = await websocket.receive_text()
await manager.send_personal_message(f"تو نوشتی: {data}", websocket)
await manager.broadcast(f"یکی گفت: {data}")
except Exception as e:
print(f"خطا: {e}")
finally:
manager.disconnect(websocket)

اینجا چی داریم؟
‏ConnectionManager یه کلاسه که اتصال‌های فعال رو تو یه لیست نگه می‌داره.
وقتی کلاینت وصل می‌شه، به لیست اضافه می‌شه (connect) و وقتی قطع می‌شه، حذف می‌شه (disconnect).

‏send_personal_message به یه کلاینت خاص پیام می‌فرسته.

‏broadcast به همه کلاینت‌های وصل‌شده پیام رو می‌فرسته.

تو endpoint، پیام کلاینت رو می‌گیریم، به خودش یه جواب شخصی می‌دیم و به بقیه هم broadcast می‌کنیم.

جمع‌بندی

‏WebSocket تو FastAPI به شما این امکان رو می‌ده که اپلیکیشن‌های realtime و جذاب بسازین. از چت روم‌ها گرفته تا داشبوردهای زنده و بازی‌های آنلاین.

خب اینم از این امید وارم مفید بوده باشه :]

#️⃣  #fastapi #backend #python


🥷 CHANNEL | GROUP
👍11👌53🔥2👏1🤩1
سیستم مدیریت وابستگی در FastAPI
یکی از بهترین ویژگی های FastAPI، سیستم مدیریت وابستگی(Dependnecy Injection) اون هست، این سیستم باعث میشه کد ما تمیز تر، تست پذیر تر و قابل توسعه تر بشه.
بهتره برای درک بهتر این پست درمورد Dependency Injectionرو مطالعه کنید تا با پایه و اساس این مبحث آشنا بشین.

‏Depends چیه؟
این کلاس توی FastAPI، برای مدیریت وابستگی ها استفاده میشه. به زبان ساده Depends یه راهه که بتونیم بک تابع یا آبجکت رو به صورت خودکار به فانکشن های دیگه تزریق کنیم بدون اینکه دستی اونارو صدا بزنیم یا بخونیم.
با یه مثال ساده شروع میکنیم:
from fastapi import FastAPI, Depends

app = FastAPI()

def get_db():
db = "Database Connection"
try:
yield db
finally:
print("Closing DB connection")

@app.get("/items/")
def read_items(db = Depends(get_db)):
return {"db_connection": db}

اینجا read_items خودش مستقیم سشن دیتابیس رو نمیسازه، فقط میگه: من به یه سشن دیتابیس نیاز دارم.
FastAPI به صورت خودکار get_db رو صدا میزنه و نتیجه رو به db میده.

چرا این سیستم خوبه؟
وابستگی ها مدیریت شده و قابل کنترل میشن
کد تست پذیر تر میشه
ساختار پروژه ماژولار میشه
لاجیک لایه های مختلف جدا میشه و تغییرات ساده تر میشن

اگه ازش استفاده نکنیم چی؟
خب با استفاده نکردن از این ویژگی یه کمک بزرگ رو از دست میدین. به طور مثال اگه وابستگی ها تو در تو باشن شما میتونید فقط با همین ویژگی کلی به تمیزی کدتون کمک کنید.
from fastapi import Header, HTTPException, APIRouter, Depends


router = APIRouter()

def get_token(token: str = Header(...)):
return token

def get_current_user(token: str = Depends(get_token)):
user = {"username": "abolfazl", "role": "admin"}
return user

def require_admin(user: dict = Depends(get_current_user)):
if user["role"] != "admin":
raise HTTPException(status_code=403, detail="Not authorized")
return user

def list_users_service():
return [{"username": "a"}, {"username": "b"}]

@router.get("/users")
def list_users(admin_user: dict = Depends(require_admin)):
users = list_users_service()
return users

توی مثال بالا میتونید چندین لایه از وابستگی رو ببینید که به خوبی با Depends مدیریت شدن. حالا اگه این سیستم وجود نداشت چی؟
def list_users():
token = get_token()
user = get_current_user(token)
admin_user = require_admin(user)
...

اگه اون سیستم وجود نداشت باید قبل از هرکاری دونه دونه سرویس ها و لایه های پایین تر رو صدا میزدین و نتیجه اونهارو به همدیگه پاس میدادین. درواقع Depends میاد هر وابستگی ای که تعیین کرده باشین رو قبل از ورود به بدنه ی فانکشن اجرا میکنه و نتیجه ی وابستگی رو به آرگومان فانکشن پاس میده. در نتیجه شما در اولین خط بدنه ی فانکشن همه ی نتایجی که میخواین رو از طریق آرگومان ها در اختیار دارین.

پشت صحنه چه اتفاقی میوفته؟

FastAPI از بالا شروع کرد به نگاه کردن:
دید require_admin به get_current_user نیاز داره، بعد دید get_current_user هم به get_token نیاز داره، پس اول get_token اجرا شد، بعد get_current_user بعد هم require_admin. هربار خروجی یه فانکشن، ورودی فانکشن بعدی شد. درنهایت اگه مشکلی نباشه میرسیم به endpoint.

از کجا فهمید چی رو به کجا بفرسته؟

خب باید بگم که FastAPI به شدت به تایپ هینت ها وابسته است و خیلی ازشون استفاده میکنه. همین Depends هم با استفاده از تایپ هینت ها جای مقادیر رو درک میکنه. یه فانکشن توی پایین ترین لایه یه آرگومان با تایپ Header داره؟ خب Depends اون آرگومان رو توی درخواست دریافت میکنه به اون فانکشن میرسونه.

کجا ازش استفاده کنیم؟
هر وابستگی ای که نیاز داره یه پارامتری رو مستقیما از درخواست بگیره و روش پردازش انجام بده، و به نحوی قبل از فانکشن endpoint اجرا بشه و نتیجه ی آماده داشته باشه(درست همونطور که گفتم، قبل از بدنه ی اصلی فانکشن) باید با Depends استفاده بشه. مثلا گرفتن توکن از هدر یا چک کردن دسترسی ها، اتصال به دیتابیس

اما اگه فانکشنی که میخواید استفاده کنید ارتباط مستقیم با بدنه و اطلاعات ورودی از درخواست نداره و فقط برای انجام کاری یا پردازش داخلی باشه نیازی به Depends نداره. مثل ثبت نام کاربر که ممکنه دیتای خام و پردازش نشده ای از درخواست نیاز نداشته باشه و صرفا اطلاعات رو توی دیتابیس ذخیره میکنه

سعی کردم هر سوالی که برای خودم توی فرآیند این سیستم پیش اومد رو به بهترین شکل پوشش بدم. اگه مشکلی توی درک داشتین یا سوالی براتون مونده بود توی کامنت ها بپرسین.

#️⃣ #fastapi #python #backend


🥷🏻 CHANNEL | GROUP
👍14
خب خب خب، ‏Middleware های FastAPI🚀
خب middleware یه کد واسط بین دریافت درخواست و پاسخ دادن توی یه اپلیکیشن وبه. یعنی هر ریکوئستی که به سرور میرسه، قبل از رسیدن به route اصلی، از middleware رد میشه و همچنین هر درخواستی هم قبل از رسیدن به کلاینت از middleware عبور میکنه تا تغییر داده بشه، لاگ بشه و ...

چطور توی FastAPI ازشون استفاده کنیم؟🤔
‌‏Middleware ها توی FastAPI با دکوریتور app.middleware تعریف میشن و معمولا ساختارشون این شکلیه:
from fastapi import FastAPI, Request

app = FastAPI()

@app.middleware("http")
async def my_middleware(request: Request, call_next):
# Before reaching route
print("Before route")

# Executing View
response = await call_next(request)

# After view did its thing
print("After route")

return response

همونطور که توی مثال بالا دیدید، هر کدی که قبل از اجرای call_next باشه مربوط به درخواست، و هر کدی که بعد از اجرای call_next نوشته بشه مربوط به پاسخ میشه.
توی این مثال قبل از رسیدن درخواست به route اصلی، عبارت 'Before route' چاپ میشه و بعد اینکه route پردازشش با درخواست تموم شد و پاسخ آماده ی برگشت به کلاینت بود، عبارت 'After route' چاپ میشه و بعد از اون پاسخ به کلاینت میرسه.


چندتا مثال ساده برای درک کاربرداش🛠️
از چندتا مثال ساده میتونیم استفاده کنیم
لاگ گیری ساده درخواست ها:
@app.middleware("http")
async def log_requests(request: Request, call_next):
print(f"New request: {request.method} {request.url}")
response = await call_next(request)
return response


اضافه کردن Header به پاسخ:
@app.middleware("http")
async def add_custom_header(request: Request, call_next):
response = await call_next(request)
response.headers["X-App-Version"] = "1.0.0"
return response


سنجش مدت زمان اجرای درخواست:
import time

@app.middleware("http")
async def measure_time(request: Request, call_next):
start = time.time()
response = await call_next(request)
duration = time.time() - start
response.headers["X-Process-Time"] = str(duration)
return response


چندتا نکته📎
1️⃣کلاس Middleware که از FastAPI ایمپورت شده درواقع همون کلاس Middleware توی Starlette هست و برای راحتی میتونیم از FastAPI ایمپورتش کنیم.

2️⃣اگه dependency ای داشته باشیم که با yield تعریف شدن، بخش خرجی اون ها بعد از اجرای middleware اجرا میشه.

3️⃣اگه BackgrounTask ای وجود داشته باشه، اون ها بعد از اجرای همه ی middleware ها اجرا میشن.

جمع بندی✍️
با استفاده از middleware ها میتونید درخواست و پاسخ هارو تمیز کنید، یا قبل از پردازش شدنشون توسط route کارایی که میخواین رو انجام بدین. درواقع با تعریف middleware یه تابع بین client و route اصلی قرار میدیم.

#️⃣ #fastapi #python #backend


🥷🏻 CHANNEL | GROUP
14
خب خب خب، ‏Background Task ها توی FastAPI🚀
گاهی اوقات نیاز داریم که یه کاری بعد از ارسال پاسخ به کاربر انجام بشه. مثل ارسال ایمیل خوشامد گویی، ثبت لاگ یا آمار توی دیتابیس، پردازش فایل آپلود شده و .... توی این شرایط میتونیم از Background Task ها استفاده کنیم، اینجوری میتونیم بدون معطل کردن کاربر اون کارهارو جداگانه انجام بدیم.

استفاده از Background Task ها🛠
خب اول باید کلاس BackgroundTasks رو ایمپورت کنیم و یه پارامتر از همین نوع برای فانکشن route بنویسیم.
from fastapi import BackgroundTasks, FastAPI

app = FastAPI()


def write_notification(email: str, message=""):
with open("log.txt", mode="w") as email_file:
content = f"notification for {email}: {message}"
email_file.write(content)


@app.post("/send-notification/{email}")
async def send_notification(email: str, background_tasks: BackgroundTasks):
background_tasks.add_task(write_notification, email, message="some notification")
return {"message": "Notification sent in the background"}

حالا FastAPI میاد یه آبجکت با نوع BackgroundTasks برامون ایجاد میکنه و به اون پارامتر پاس میده.
بعد از اینکه فانکشن تسکمون رو ایجاد کردیم میتونیم با استفاده از متود ()add_task از همون پارامتر اون فانکشن رو به صف اجرا اضافه کنیم. همچنین میتونیم آرگومان های مورد نیازمون رو هم با استفاده از همین متود به تسکمون پاس بدیم.

‏Background Tasks و Dependency injection💉
‏Background Tasks به خوبی با سیستم تزریق وابستگی FastAPI سازگاره. میتونیم توی سطح های مختلف برنامه(فانکشن route، یه وابستگی و...) از Background Task استفاده کنیم.
from typing import Annotated

from fastapi import BackgroundTasks, Depends, FastAPI

app = FastAPI()


def write_log(message: str):
with open("log.txt", mode="a") as log:
log.write(message)


def get_query(background_tasks: BackgroundTasks, q: str | None = None):
if q:
message = f"found query: {q}\n"
background_tasks.add_task(write_log, message)
return q


@app.post("/send-notification/{email}")
async def send_notification(
email: str, background_tasks: BackgroundTasks, q: Annotated[str, Depends(get_query)]
):
message = f"message to {email}\n"
background_tasks.add_task(write_log, message)
return {"message": "Message sent"}

توی این مثال بعد از اینکه پاسخ به کلاینت ارسال شد، یه تسک میاد ایمیل کاربر رو توی فایل log.txt مینویسه. اگه یه کوئری پارامتر هم به API ارسال بشه یه تسک دیگه اون رو هم توی فایل مینویسه.

نکته مهم⚠️
این ابزار فقط برای کارهای سبک وسریع مناسبه. مثل همین لاگ نوشتن، ارسال ایمیل یا پردازش های خیلی کوچیک و سبک. برای کارهای سنگین تر مثل پردازش تصویر بهتره که از سیستم هایی مثل Celery استفاده بشه.

جمع بندی✍️
‏Background Task یه ابزار ساده ولی کاربردیه. میتونه توی پروژه هایی که تسک های سنگینی ندارن از Celery بی نیازتون کنه و کارهارو بعد از پاسخ دهی به صورت غیرهمزمان انجام بده.

#️⃣ #fastapi #python #backend


🥷🏻 CHANNEL | GROUP
👍116