مروری بر رابط دروازه وب سرور
WSGI به رابط دروازه وب سرور اشاره دارد. WSGI در زمانی که برنامه جنگو یا فلسک خود را مستقر میکنید، نقش حیاتی ایفا میکند. در اینجا، درباره چیستی WSGI بحث خواهیم کرد، چه زمانی باید به مفهوم WSGI و نحوه عملکرد WSGI عمیقتر بپردازید.
هم رویش منتشر کرده است:
آموزش جنگو از صفر --- طراحی سایت با پایتون و Django
WSGI چیست؟
WSGI مشخصاتی است که ارتباط بین وب سرورها و برنامهها یا فریمورکهای وب پایتون را توصیف میکند و توضیح میدهد که چگونه یک وب سرور با برنامهها-فریمورکهای وب پایتون ارتباط برقرار میکند و چگونه برنامهها-فریمورکهای وب میتوانند برای پردازش یک درخواست همکاری زنجیرهای داشته باشند.
استاندارد پایتون WSGI با PEP 3333 مفصل توضیح داده شده است. بنابراین، اگر مایل به کسب اطلاعات بیشتر در مورد PEP 3333 هستید، میتوانید به مستندات رسمی پایتون نگاهی بیندازید.
WSGI چگونه کار میکند؟
حال، بیایید نگاهی به نحوه عملکرد WSGI بیندازیم. بنابراین، برای به دست آوردن درک روشنی از WSGI، اجازه دهید یک سناریوی موردی را فرض کنیم که در آن یک برنامه وب در برنامه جنگو یا فلسک توسعه داده شده است همانطور که در شکل زیر نشان داده شده است.
از آنجایی که یک برنامه وب در وبسرور مستقر شده است. شکل زیر نشاندهنده وبسروری است که درخواستهای کاربران مختلف را دریافت میکند.
اکنون یک سوال مطرح میشود – چگونه یک وبسرور میتواند با برنامه پایتون تعامل داشته باشد؟
وب سرور فوق میتواند سرور آپاچی، NGINX و غیره باشد که وظیفه مدیریت فایلهای مختلف و اهداف کش را بر عهده دارد. علاوه بر این، اگر میخواهید چندین برنامه را مقیاس کنید، میتوانید از سرور به عنوان متعادل کننده بار استفاده کنید.
بنابراین، اکنون یک مشکل به وجود میآید زیرا یک وب سرور باید با برنامه پایتون تعامل داشته باشد.
از این رو، برای انجام تعامل بین وب سرورها و برنامه پایتون به یک واسطه نیاز است. بنابراین، استاندارد برای انجام ارتباط بین وبسرور و برنامه پایتون WSGI (رابط دروازه وب سرور ) است.
اکنون وب سرور قادر به ارسال درخواست یا ارتباط با کانتینرهای WSGI است. به این ترتیب، برنامه پایتون یک شیء «قابل فراخوانی» را ارائه میکند که شامل عملکردهای خاصی است که توسط برنامه WSGI فراخوانی میشوند که طبق استاندارد PEP 3333 تعریف شدهاند. از این رو، چندین کانتینر WSGI مانند Gunicorn، uWSGI و غیره موجود است.
شکل زیر نشان دهنده ارتباطی است که بین وب سرور، WSGI و برنامه پایتون انجام میشود.
چندین کانتینر WSGI وجود دارد که در دسترس هستند. از این رو، یک کانتینر WSGI باید در پروژه نصب شود تا یک وب سرور بتواند با یک کانتینرو با برنامه پایتون بیشتر ارتباط برقرار کند و پاسخ را بر اساس آن ارائه میدهد. در نهایت، زمانی که وبسرور پاسخ را دریافت میکند، به مرورگر کاربران وب ارسال میشود.
هم رویش منتشر کرده است:
آموزش flask پروژه محور از صفر تا انتشار آنلاین ــ تولید API با فلسک و پایتون
چرا به جای اشاره مستقیم وبسرور به برنامه جنگو یا فلسک از WSGI استفاده کنیم؟
اگر مستقیماً وبسرور خود را به برنامه هدایت کنید، انعطافپذیری برنامه شما را کاهش میدهد. از آنجایی که وبسرور شما مستقیماً به برنامه وب شما اشاره میکند، نمیتوانید اجزای پشته وب را تعویض کنید.
بیایید به یک مثال نگاهی بیندازیم تا شما را در مورد کاربرد WSGI روشن کنیم. به عنوان مثال، امروز تصمیم گرفتید برنامه خود را با استفاده از Gunicorn اجرا کنید، اما شاید پس از چند سال تصمیم گرفتید از Gunicorn به mod_wsgi تغییر دهید.
حال در این حالت میتوانید به راحتی بدون ایجاد هیچ تغییری در اپلیکیشن یا فریمورکی که WSGI را پیادهسازی میکند به mod_wsgi سوئیچ کنید. از این رو، WSGI انعطافپذیری را برای برنامه شما فراهم میکند.
یکی دیگر از دلایل استفاده از WSGI مقیاسپذیری آن است. هنگامی که برنامه شما فعال است، میتواند هزاران درخواست در آن وجود داشته باشد. از این رو، WSGI قادر به ارائه هزاران درخواست در یک زمان است. همانطور که میدانیم، سرور WSGI مسئول رسیدگی به درخواستها از وبسرور است و برای انجام ارتباط آن درخواستها به فرآیند برنامه تصمیم میگیرد. در اینجا میتوانیم مسئولیتها را بین سرورها برای مقیاسبندی ترافیک وب تقسیم کنیم.
پیادهسازی سرور WSGI
سرورهای مختلفی وجود دارند که از WSGI پشتیبانی میکنند.
گانیکورن (یونیکورن سبز)
Gunicorn یک سرور مبتنی بر مدل pre-fork worker است که با فریمورکهای مختلف وب سازگار است. علاوه بر این، اجرای آن نیز ساده است.
uWSGI
uWSGI به دلیل اجرای سرور WSGI بسیار کارآمد شناخته شده است. همچنین میتواند برای توسعه و استقرار برنامه پایتون استفاده شود. در uWSGI، سرورهای برنامه، پروکسیها، مدیران فرآیند و مانیتورها همگی از طریق یک API مشترک و یک پیکربندی مشترک پیادهسازی میشوند که UWSGI را به یک سرور WSGI توسعهدهنده تبدیل میکند.
mod_wsgi
mod_wsgi بسته پایتونی است که یک ماژول Apache را ارائه میدهد که یک رابط سازگار با WSGI را برای میزبانی برنامههای وب پایتونی در وبسرور آپاچی پیادهسازی میکند.
CherryPy
CherryPy یک فریمورک وب پایتون است که به توسعهدهندگان این امکان را میدهد تا برنامههای وب را به همان روشی که سایر برنامههای شیگرا پایتون را توسعه میدهند، توسعه دهند.
CherryPy به عنوان یک فریمورک HTTP شیگرا در نظر گرفته میشود که میتواند به طور موثر روی چندین سرور HTTP به طور همزمان اجرا شود.
چه زمانی باید در WSGI عمیقتر شوید؟
زمانی که باید یک فریمورک برنامه وب جدید ایجاد کنید، میتوانید عمیق تر به WSGI بروید. از این رو، تا زمانی که به دنبال توسعه یک فریمورک برنامه وب جدید نباشید، فقط میتوانید با هدف و کاربرد WSGI آشنا باشید. امروزه، فریمورکهای برنامه کاربردی وب از WSGI پشتیبانی میکنند و به همین دلیل نیازی به نگرانی در مورد پیکربندی و استقرار برنامه ندارید.
مفهوم دیگری وجود دارد به نام ASGI
رابط دروازه ناهمگام سرور (ASGI)
چیزهای هیجانانگیز زیادی در اکوسیستم توسعه وب پایتون اتفاق میافتد – یکی از محرکهای اصلی این تلاش ASGI، رابط دروازه سرور ناهمزمان است.
همه چیز با async/await شروع شد
برخلاف جاوا اسکریپت یاGo، پایتون زبانی نیست که از ابتدا اجرای ناهمزمان داشته باشد. برای مدت طولانی، اجرای کارها به طور همزمان در پایتون تنها با استفاده از چندرشتهای یا چندپردازشی یا استفاده از کتابخانههای تخصصی شبکه مانند eventlet، gevent، یا Twisted امکانپذیر بود. (در سال 2008،Twisted قبلاً APIهایی برای کوروتینهای ناهمزمان داشت، به عنوان مثال به شکل InlineCallbacks و (DeferredGenerator
اما اینها در پایتون 3.4+ تغییر کرد. Python 3.4 کتابخانه asyncio را به کتابخانه استاندارد اضافه کرد و پشتیبانی از چند وظیفه مشترک را در ژنراتورها و بازدهی از نحو را افزود.
بعداً، syntax async/wait در پایتون 3.5 اضافه شد. از زمانی که نسخه 3.5 منتشر شد، وبسرورها و برنامههای پایتون حتی جانگو به سمت ناهمگامسازی حرکت میکنند.
مروری بر ASGI
حال، چگونه ASGI در همه اینها جای میگیرد؟
ASGI را میتوان به عنوان چسبی در نظر گرفت که به سرورها و برنامههای کاربردی ناهمزمان پایتون اجازه میدهد با یکدیگر ارتباط برقرار کنند. ایدههای طراحی زیادی را با WSGI به اشتراک میگذارد و اغلب به عنوان جانشین آن با async داخلی ارائه میشود.
در اینجا این مدل نمودار به نظر میرسد:
اما واقعیت، کمی پیچیدهتر از این نمودار است.
ASGI از دو جزء مختلف تشکیل شده است:
- یک سرور پروتکل، که سوکتها را خاتمه میدهد و آنها را به اتصالات و پیامهای رویداد هر اتصال ترجمه میکند.
- یک برنامه، که در داخل یک سرور پروتکل (Protocol Server) زندگی میکند، یک بار در هر اتصال نمونهسازی میشود و پیامهای رویداد را در صورت وقوع مدیریت میکند.
بنابراین با توجه به ویژگیها، آنچه ASGI مشخص میکند قالب پیام و نحوه تبادل آن پیامها بین برنامه و سرور پروتکلی است که آن را اجرا میکند.
حال میتوانیم نمودار خود را به نسخه دقیقتر اصلاح کنیم:
بدیهی است که جزئیات بسیاری وجود دارد که باید به آنها نگاه کرد.
علاوه بر این، اگرچه مشخصات روی ارتباط سرور به برنامه تمرکز زیادی دارد، اماASGI بسیار بیشتر از آن را شامل میشود.
اصول ASGI
اکنون که دیدیم ASGI چگونه در اکوسیستم وب پایتون جا میشود، بیایید نگاهی دقیقتر به شکل کد آن بیندازیم.
ASGI بر مدل ذهنی زیر متکی است:
هنگامی که کلاینت به سرور متصل میشود، یک برنامه کاربردی را نمونهسازی میکنیم. سپس بایتهای دریافتی را وارد برنامه میکنیم و هر بایتی را که خارج میشود، پس میفرستیم.
“Feed into the app” در اینجا به معنای فراخوانی برنامه به گونهای است که گویی یک تابع است، یعنی چیزی که مقداری ورودی میگیرد و یک خروجی را برمیگرداند.
و در واقع، این تمام چیزی است که یک برنامه ASGI قابل فراخوانی است. شکل این فراخوانی مجدداً توسط مشخصات ASGI تعریف میشود. به نظر میرسد:
async def app(scope, receive, send):
امضای این تابع همان چیزی است که “I” در ASGI مخفف آن است: رابطی که برنامه باید برای سرور اجرا کند تا بتواند آن را فراخوانی کند.
بیایید به 3 استدلال نگاهی بیندازیم:
- scope یک دیکشنری است که حاوی اطلاعاتی در مورد درخواست ورودی است. محتویات آن بین اتصالات HTTP و WebSocket متفاوت است.
- receive یک تابع ناهمزمان است که برای دریافت پیامهای رویداد ASGI استفاده میشود.
- send یک تابع ناهمزمان است که برای ارسال پیامهای رویداد ASGI استفاده میشود.
در اصل، این آرگومانها به شما امکان میدهند که دادههایی را از طریق یک کانال ارتباطی که توسط سرور پروتکل نگهداری میشود، receive () و ()send کنید، و همچنین بدانید که این کانال در چه زمینه (یا محدوده) ایجاد شده است.
نمونه کد:
برای دریافت احساس عملیتر از ظاهر ASGI، یک پروژه مینیمال ایجاد کردیم که یک برنامه خام ASGI HTTP ارائه شده توسط uvicorn (یک سرور محبوب ASGI) را به نمایش میگذارد:
در اینجا، از send () برای ارسال پاسخ HTTP به کلاینت استفاده میکنیم: ابتدا هدرها و سپس بدنه پاسخ را ارسال میکنیم.
اکنون، با این همه دیکشنری و دادههای باینری خام، کار کردن با ASGI چندان راحت نیست.
خوشبختانه، گزینههای سطح بالاتری وجود دارد. Starlette یک پروژه فوق العاده است و IMO یک قطعه اساسی از اکوسیستم ASGI است.
به طور خلاصه، جعبهابزاری از اجزای سطح بالاتر مانند درخواستها و پاسخها را ارائه میکند که میتوانید از آنها برای انتزاع برخی از جزئیات ASGI استفاده کنید. در اینجا، نگاهی به Starlette “Hello, World!” میاندازیم:
# app.py
from starlette.responses import PlainTextResponse
async def app(scope, receive, send):
assert scope["type"] == "http"
response = PlainTextResponse("Hello, world!")
await response(scope, receive, send)
Starlette هر آنچه از یک فریمورک واقعی وب انتظار دارید را دارد – مسیریابی، میان افزار و غیره.
لاکپشتها تا پایان
نکته جالب و کاملاً متحولکننده در مورد ASGI مفهوم “لاکپشتها تا پایان” است. این عبارت در اصل توسط اندرو گادوین، ابداع شد. اما دقیقاً این عبارت به چه معناست؟
از آنجایی که ASGI یک انتزاع است که به شما امکان میدهد شرایطی را که در آن قرار دارید بگویید، و بتوانید دادهها را در هر زمان دریافت و ارسال کنید، این ایده وجود دارد که ASGI را میتوان نه تنها بین سرورها و برنامهها، بلکه واقعاً در هر نقطه از پشته (Stack) از آن استفاده کرد.
به عنوان مثال، شی Starlette Response خود یک برنامه ASGI است. در واقع، میتوانیم مثال برنامه Starlette را از قبل به این موارد حذف کنیم:
# app.py
app = PlainTextResponse("Hello, world!")
پیامد عمیقتر “لاکپشتها تا پایان” این است که میتوانیم انواع برنامهها، میانافزارها، کتابخانهها و پروژههای دیگر را بسازیم و تا زمانی که همه آنها رابط برنامه ASGI را پیاده سازی کنند اطمینان حاصل کنیم که آنها با هم کار خواهند کرد.
علاوه بر این، بر اساس تجربه در ساخت Bocadillo، استفاده از رابط ASGI اغلب (اگر نه همیشه) منجر به کد بسیار تمیزتر میشود.
به عنوان مثال، میتوانیم یک میانافزار ASGI یعنی برنامهای که برنامه دیگری را میپیچد، بسازیم تا مدت زمان ارائه درخواست را نشان دهد:
# app.py
import time
class TimingMiddleware:
def __init__(self, app):
self.app = app
async def __call__(self, scope, receive, send):
start_time = time.time()
await self.app(scope, receive, send)
end_time = time.time()
print(f"Took {end_time - start_time:.2f} seconds")
برای استفاده ، آن را در اطراف یک برنامه پیچیده میکنیم…
# app.py
import asyncio
from starlette.responses import PlainTextResponse
async def app(scope, receive, send):
await asyncio.sleep(1)
response = PlainTextResponse("Hello, world!")
await response(scope, receive, send)
app = TimingMiddleware(app)
و به این شکل کار میکند
$ uvicorn app:app
INFO: Started server process [59405]
INFO: Waiting for application startup.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
...
INFO: ('127.0.0.1', 62718) - "GET / HTTP/1.1" 200
Took 1.00 seconds
نکته شگفتانگیز این است که TimingMiddleware میتواند هر برنامه ASGI را بپیچد. برنامه داخلی در اینجا بسیار ابتدایی است، اما میتواند یک پروژه تمام عیار و واقعی باشد (به صدها نقطه پایانی API و WebSocket فکر کنید)، تا زمانی که با ASGI سازگار باشد.
چرا باید اهمیت بدهم؟
در حالی که فکر میکنم قابلیت همکاری یک نقطه فروش قوی است، استفاده از مؤلفههای مبتنی بر ASGI برای ساخت برنامههای وب پایتون مزایای بیشتری دارد.
- سرعت: ماهیت ناهمگام برنامهها و سرورهای ASGI آنها را بسیار سریع میکند (حداقل برای پایتون)
- ویژگیها: سرورها و فريمورکهای ASGI به شما امکان دسترسی به ویژگیهای ذاتی همزمان (WebSocket)، رویدادهای ارسال شده از سرور، (HTTP/2) را میدهند که پیادهسازی با استفاده از همگامسازی WSGI غیرممکن است.
- پایداری: ASGI به عنوان یک ویژگی حدود 3 سال است که وجود دارد و نسخه آن 3.0 بسیار پایدار در نظر گرفته میشود. در نتیجه بخشهای اساسی اکوسیستم در حال تثبیت هستند.
کجا میتوانم اجزای سازگار با ASGI را پیدا کنم؟
در واقع، افراد بیشتری در حال ساخت و بهبود پروژههای ساخته شده پیرامون ASGI هستند. بدیهی است که این موارد شامل سرورها و فریمورکهای وب، اما میانافزار و برنامههای کاربردی محصولگرا مانند Datasette میشود.
برخی از اجزای فریمورک غیروب عبارتند از:
- :Mangum پشتیبانی ASGI برای AWS Lambda
- :datate-auth-github احراز هویت GitHub برای برنامههای ASGI
- :tartiflette-starlette پشتیبانی ASGI ازTartiflette ، یک موتور GraphQL ناهمگام.
کلیدواژگان
WSGI چیست | UWSGI چیست | رابط دروازه وب سرور | wsgi چیست با مثال | WSGI پایتون چیست | Asgi چیست | asgi چیست به زبان ساده | asgi چیست با مثال | رابط دروازه وب سرور چیست | رابط دروازه وب سرور چیست به زبان ساده | رابط دروازه وب سرور چیست توضیح دهید | تفاوت WSGI و ASGI | مقایسه WSGI و ASGI | فرق WSGI و ASGI | تفاوت WSGI با ASGI | اجزای سازگار با ASGI | اجزای سازگار با ASGI چیست | اجزای سازگار ASGI
منابع
what-is-wsgi-web-server-gateway-interface
what-is-introduction-to-asgi-async-python-web