نویسندگان : محیا مهدیان و محمد حسن ستاریان
مقدمه و آشنایی
فلسک یک فریمورک وب مبتنی بر پایتون است برای ایجاد سریع و ساده وبسرور که توسط آرمینروناچر توسعه دادهشده است. تلاش برای سادهنگه داشتن طراحی فلسک و کوچکی فریمورک و قائل نشدن بسیاری از پیشفرض ها برای برنامهنویسان دلیلیاست که این بستهنرم افزار را یک میکروفریمورک مینامند. فلسک رایگان و متنباز بوده و با مجوز آزاد BSD منتشر شده است.
کار با فلسک به قدری ساده است که اگر کمی با زبان پایتون آشنا باشید با دیدن اولین کدهای فلسک با ساختار این فریمورک آشنا میشوید. فریمورک فلسک با همهی سادگی خود بسیار قدرتمند و کاراست و به هیچ عنوان کوچک بودن فریمورک را نمیتوان با ضعیف بودن آن برابر دانست و امکانات فریمورکهایی مثل جنگو و ریلز را با اندکی جستوجو به دست میدهد. برای مثال از سرویسهای بزرگی که از فلسک استفاده میکنند میتوان از Pinterest و Linkedin نام برد که به مناسب بودن فلسک برای توسعهی سرویسهای اینترنتی اشاره دارد.
دو کتابخانهی اساسی پایههای قدرتمند فلسک را ساختهاند؛ به عنوان واسط وبسرور ( WSGI ) از کتابخانهی werkzeug و برای تمپلیتانجین از Jinja2 استفاده کرده اند که هردو کتابخانه توسط تیم توسعه ی فلسک توسعه یافته شده است.
بطور پیشفرض برای کار با دیتابیسها، اعتبارسنجی فرم ها و کاربران و از این دست کارها ابزار مشخصی در فلسک تعریف نشده است و میتوان از ابزارهای شخص ثالث (Third party applications) که برای آن توسعه داده شدهاند استفاده کرد.
نصب
آماده کردن محیط مجازی
برای نصب و راهانداری پروژهها معقول است یک محیط مجازی توسعه ساخت تا در حین کار و حتی یادگیری، مفسر عمومی و پکیجهای عمومی سیستم دچار تغییر و کانفلیکت نشوند. محیطهای توسعهمجازی یک کپی از مفسر پایتون را بصورت خصوصی در دایرکتوری پروژه شما ایجاد میکنند و بعد از فعال کردن این مفسر پکیجها هم بصورت خصوصی در دایرکتوری پروژه نصب میشوند.
نحوه ایجاد و فعالسازی محیط مجازی را از اینجا بخوانید.
نصب فلسک
حالا نوبت نصب بسته ی فلسک است. متداول ترین روش نصب بستههای پایتون استفاده از مدیر بستهی pip است که با استفاده از آن فلسک با دستور زیر نصب میشود :
1 |
pip install flask |
برای بررسی صحت نصب فلسک مفسر پایتون را بصورت تعاملی در ترمینال باز کنید ( تنها دستور python را نوشته و اینتر کنید ) و بستهی فلسک را با دستور زیر فراخوانی کنید :
1 |
import flask |
اگر خطایی رخ نداد فلسک درست نصب شده است و میتوانید با اجرای دستور زیر نسخه نصب شده را بررسی کنید:
1 |
flask.__version__ |
ساختار برنامهها در فلسک
فلسک هیچ محدودیتی درمورد ساختاربندی فایلهای پروژه برای شما ایجاد نمیکند و میتوانید ساختار خودتان را داشته باشید یا از رولهای متداول جامعه ی فلسک استفاده کنید.
ساخت برنامه های فلسک
شروع سریع
کدهای یک اپلیکیشن سادهی فلسک که عبارت Hello World را در یک صفحه ی وب نمایان میکند بصورت زیر است :
1 2 3 4 5 6 7 8 9 |
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World!' if __name__ == '__main__': app.run() |
این برنامه از چند بخش تشکیل شده است : فراخوانی و تعریف فلسک، تعریف مسیرها، اجرای فلسک.
فراخوانی و تعریف فلسک
برای ساخت برنامههای فلسک نیاز است ابتدا فلسک را در فایل پایتون خود لود کنید و سپس یک نمونه (instance) از Flask بسازید یعنی این بخش :
1 2 |
from flask import Flask app = Flask(__name__) |
تنها آرگومان مورد نیاز برای کانستراکتور فلسک نام ماژول یا پکیج main است که برای بیشتر برنامه ها __name__
در پایتون مقدار درستی است.
میتوانیم بجای نام اینستنس فلسک ( در مثال بالا app ) از هر نام متغیر معتبری استفاده کنیم.
فلسک روی pip یک بسته از ماژولهای مرتبط به هم است و نه یک ماژول و به همین دلیل هر ماژول باید از درون بسته ی flask جداگانه ایمپورت بشود.
تعریف مسیرها
مسیرها همان آدرسهای (url های) مختلفی هستند که عملیاتهای متفاوتی بر اساس آنها انجام میشود. مثلا site.domain مسیر ریشه و site.domain/subdomain یک مسیر دیگر در همان سایت تعریف میکند. در کد مثال ما مسیر بصورت زیر تعریف شده بود :
1 2 3 |
@app.route('/') def hello_world(): return 'Hello World!' |
در اینجا یک دکوریتور نوع
()route از
app (که در قسمت قبل ساختیم) برای تابع
Hello world تعریف میکند و آدرس مسیر ('/'
) را به آن میفرستد. مسیرها در فلسک اساس ساخت برنامهها هستند. با استفاده از مسیرها میتوانید به سادگی بخشهای مختلف وباپلیکیشن خود را بسازید و مدیریت کنید.
اجرای فلسک
در آخر به پایتون میگوییم که فلسک را روی یک وبسرور اجرا کند که دستورات آن بصورت زیر است :
1 2 |
if __name__ == '__main__': app.run() |
این شرط برای بررسی این موضوع است که آیا این فایل پایتون مستقیما اجرا میشود (برقراری شرط) و یا به عنوان یک ماژول در یک برنامه دیگر وارد شده است (عدم برقراری شرط).
این کد را در یک فایل مانند app.py ذخیره کرده و در خط فرمان با دستور python app.py اجرا کنید. خروجی روی ترمینال چیزی شبیه این است :
1 |
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) |
که آدرس 127.0.0.1:5000 را که در خروجی مشخص شده است اگر در مرورگر خود امتحان کنید روی صفحه عبارت Hello World به صورت زیر نمایان میشود، (فلسک به صورت پیشفرض پورت ۵۰۰۰ را برای اجرا در نظر میگیرد):
تابع run میتواند پارامتر ای با عنوان host داشته باشد که مشخص میکند سرور برروی چه آدرسی اجرا شود، همچنین توسط پارامتر port میتوان پورتی که سرور روی آن اجرا شود را مشخص کرد و توسط پارامتر debug و دادن مقدار true به آن میتوان مشخص کرد که لاگها و گزارشات مربوط به اشکال یابی برنامه نیز چاپ شوند.
1 |
app.run(host='0.0.0.0', port=8080, debug=True) |
برای اینکه سرور از طریق کامپیوترهای متصل به همین شبکه قابل مشاهده و استفاده باشد به پارامتر host مقدار 0.0.0.0 را میدهیم.
توجه کنید که پارامتر host از جنس string، پارامتر port از جنس integer و پارامتر debug از جنس boolean است.
برنامههای کاربردیتر
استفاده از متغیرها در آدرس
در تعریف قوانین آدرسدهی میتوان به آدرسها با استفاده از عملگرهای <> متغیر اضافه کرد مانند <variable_name> تا بخشی از آدرس به صورت متغیر توسط تابع در دسترس باشد.همچنین میتوان نوع متغیر را با استفاده از یک مبدل مانند <converter:variable_name> مشخص کرد:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from flask import Flask app = Flask(__name__) @app.route('/user/<username>') def show_user_profile(username): # show the user profile for that user return (f'User {username}') @app.route('/post/<int:post_id>') def show_post(post_id): # show the post with the given id, the id is an integer return (f'Post {post_id}') @app.route('/path/<path:subpath>') def show_subpath(subpath): # show the subpath after /path/ return (f'Subpath {subpath}') app.run() |
نوع پیشفرص برای متغیرها string است.
آدرسهای منحصر به فرد و هدایت آدرس
به نحوه آدرس دهی در برنامه زیر دقت کنید:
1 2 3 4 5 6 7 |
@app.route('/projects/') def projects(): return 'The project page' @app.route('/about') def about(): return 'The about page' |
آدرس تعریف شده برای projects شبیه آدرس دایرکتوی است و در انتهای خود یک ‘/’ دارد. اگر به این آدرس بدون ‘/’ برویم فلسک ما را به آدرس اصلی (آدرس با ‘/’) هدایت میکند.
آدرس تعریف شده برای about شبیه آدرس فایل است و در انتهای خود ‘/’ ندارد. اگر به این آدرس با ‘/’ برویم با خطای ۴۰۴ (صفحهای یافت نشد) مواجه خواهیم شد. این امر این امکان را میدهد تا آدرسهای تعریف شده به این سبک منحصر به فرد بوده و کمک میکند موتورهای جستوجو یک صفحه را دوبار ایندکس نکنند.
متدهای HTTP
برنامهها هنگام دسترسی به آدرسها از متدهای HTTP مختلفی استفاده میکنند. به صورت پیشفرض یک آدرس تنها به متد GET پاسخ میدهد، اما با استفاده از مشخص کردن متدهای لازم در پارامتر methods از دکوریتور ()route میتوان به متدهای مختلف پاسخ داد:
1 2 3 4 5 6 7 8 |
from flask import request @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': return do_the_login() else: return show_the_login_form() |
در کد با بررسی نوع (method) درخواست (request) عملیات متفاوتی انجام میشود. این بدین معنی است که اگر به یک آدرس با متد GET درخواست بدیم یک پاسخ و اگر به همان صفحه با متد دیگری مانند POST درخواست بدیم پاسخ دیگری دریافت خواهیم کرد.
استفاده از قالبها (templates)
میتوان مشخص کرد با مراجعه به صفحهای یک فایل HTML رندر شده و به نمایش درآید. برای اینکار فلسک از فولدربندی خاصی استفاده میکند. در فولدر پروژه باید دو فولدر به نام های static و templates ایجاد کنید که در فولدر templates فایل های html و در فولدر static فایل های css و js خودتون رو قرار بدهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from flask import Flask, render_template app = Flask(__name__) @app.route("/") def index(): return "Hello World !" @app.route("/welcome") def welcome(): return render_template('welcome.html') if __name__ == __main__: app.run() |
حال اگر کاربر به صفحه welcome/ برود فانکشن به جای متن خالی، فایل HTML رو return میکند. توجه داشته باشید که این فایل HTML باید داخل پوشه templates قرار گرفته باشد تا فلسک اون رو شناسایی بکند.
استفاده در بخشی از برنامه
از آنجایی که فلسک تنها به عنوان دکوریتور برای توابعی که خود مشحص میکنیم قرار میگیرد و آنها را به آدرسهای مشخص شده مرتبط میکند، میتوان از آن در یک برنامه در کنار دیگر توابع استفاده کرد و نیازی به جدا سازی فایل مربوط به serve و اجرای برنامه از فایلی که عملیات برنامه در آن پیادهسازی شده نیست. به عنوان مثال به فایل زیر توجه کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import keras import flask app = flask.Flask(__name__) def load_model() ... loads model def prepare_image(): ... proccess image for prediction return image @app.route("/predict", methods=["POST"]) def predict(): if flask.request.method == "POST": if flask.request.files.get("image"): ... gets image and call prepare_image() and do predict return flask.jsonify(data) if __name__ == "__main__": load_model() app.run() |
این برنامه یک برنامه یادگیری ماشین است که عکس ارسالی به endpoint با آدرس predict/ و متد POST را آپلود کرده و با predict آن نتیجه را برمیگرداند. با اجرای کد مدل مربوطه لود شده و سرور شروع به گوش دادن به endpoint ذکر شده برای دریافت درخواستها میکند و در صورت دریافت درخواستی حاوی تصویر، توابع مربوطه برای predict عکس را صدا زده و نتیجه را برمیگرداند.
افرونهها
فلسک یک فریمورک بسیار توسعه پذیر است و میتوانید بصورت ماژولار کدهای آن را تقسیم بندی و استفاده کنید. همچنین پلاگینهای بسیاری هماکنون برای آن نوشته شده است که میتوانید در صفحهی extension های فلسک تعدادی از بهترین افزونههای فلسک را بیابید و استفاده کنید.
منابع
مقاله «میکروفریمورک فلسک – معرفی» از سایت کدرز
مقاله «آشنایی با میکرو-فریمورک فلسک» از سایت هایو
شبکه های اجتماعی