وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

ساخت اپلیکیشن Todo با Flask در پایتون

0 42
زمان لازم برای مطالعه: 9 دقیقه


معرفی

در این آموزش قصد داریم یک API یا یک وب سرویس برای یک برنامه todo بسازیم. سرویس API با استفاده از معماری مبتنی بر REST پیاده سازی خواهد شد.

برنامه ما ویژگی های اصلی زیر را خواهد داشت:

  • یک مورد در لیست کار ایجاد کنید
  • لیست کامل کارها را بخوانید
  • موارد را با وضعیت “شروع نشده”، “در حال انجام” یا “کامل” به روز کنید
  • موارد را از لیست حذف کنید

REST چیست؟

باقی مانده، یا انتقال دولتی نمایندگی، یک سبک معماری برای ساخت وب سرویس ها و API ها است. این امر مستلزم آن است که سیستم هایی که REST را پیاده سازی می کنند بدون تابعیت باشند. سرویس گیرنده بدون اینکه بداند سرور در چه وضعیتی است، درخواستی را برای بازیابی یا اصلاح منابع به سرور ارسال می کند. سرورها بدون نیاز به دانستن ارتباط قبلی با مشتری، پاسخ را برای مشتری ارسال می کنند.

هر درخواست به سیستم RESTful معمولاً از این 4 فعل HTTP استفاده می کند:

  • گرفتن: یک منبع خاص یا مجموعه ای از منابع را دریافت کنید
  • پست: یک منبع جدید ایجاد کنید
  • قرار دادن: یک منبع خاص را به روز کنید
  • حذف: یک منبع خاص را حذف کنید

اگر چه دیگران مجاز هستند و گاهی استفاده می شوند، مانند پچ، سر، و گزینه ها.

فلاسک چیست؟

فلاسک چارچوبی برای پایتون برای توسعه برنامه های کاربردی وب است. بدون نظر است، یعنی برای شما تصمیم نمی گیرد. به همین دلیل، محدود به ساختار برنامه شما به روش خاصی نیست. این انعطاف پذیری و کنترل بیشتری را برای توسعه دهندگانی که از آن استفاده می کنند، فراهم می کند. Flask ابزارهای پایه برای ایجاد یک برنامه وب را در اختیار شما قرار می دهد، و می توان آن را به راحتی گسترش داد تا بیشتر مواردی را که باید در برنامه خود قرار دهید، شامل شود.

برخی دیگر از فریمورک های محبوب وب را می توان به عنوان جایگزینی برای Flask در نظر گرفت. اگر Flask برای شما کار نمی کند، جنگو یکی از محبوب ترین جایگزین ها است. ما در این آموزش مقایسه جنگو و فلاسک را انجام داده ایم.

راه اندازی فلاسک

ابتدا بیایید پیش برویم و با استفاده از Flask نصب کنیم pip:

$ pip install Flask

اجازه دهید به سرعت Flask را پیکربندی کنیم و یک وب سرور را در ماشین محلی خود بچرخانیم. یک فایل ایجاد کنید main.py در todo_service_flask فهرست راهنما:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

پس از وارد کردن Flask، a را راه اندازی کردیم مسیر. یک مسیر با یک الگوی URL، یک روش HTTP و تابعی که درخواست HTTP را دریافت و مدیریت می کند، مشخص می شود. ما آن مسیر را با یک تابع پایتون متصل کرده ایم که هر بار که URL از طریق HTTP درخواست می شود فراخوانی می شود. در این مورد، ما را راه اندازی کرده ایم root (/) مسیر را به طوری که می توان با الگوی URL به آن دسترسی داشت http://(IP-OR-DOMAIN):(PORT)/.

اجرای برنامه Flask

کار بعدی چرخش یک سرور محلی و سرویس دهی به این وب سرویس است تا بتوانیم از طریق یک کلاینت به آن دسترسی داشته باشیم.

خوشبختانه، همه اینها را می توان با یک دستور واحد و ساده انجام داد:

$ FLASK_APP=main.py flask run

شما باید پیام را در console:

Running روی http://127.0.0.1:5000/ (Press CTRL+C to quit)

ما میتوانیم استفاده کنیم حلقه شلیک کردن a گرفتن درخواست. اگر شما روی Mac، cURL باید قبلاً در سیستم شما نصب شده باشد:

$ curl -X GET http://127.0.0.1:5000/

ما باید با پاسخ استقبال کنیم:

Hello World!

داستان به اینجا ختم نمی شود. بیایید پیش برویم و برنامه Todo خود را ساختار دهیم.

ساختار برنامه Todo

برنامه Todo ما چندین ویژگی اساسی خواهد داشت:

  • افزودن موارد به لیست
  • دریافت همه موارد از لیست
  • به روز رسانی یک مورد در لیست
  • حذف یک مورد از لیست

اینها اغلب به عنوان نامیده می شوند چیز چندش و کثیف عملیات، برای ایجاد، خواندن، به روز رسانی و حذف کنید.

ما از پایگاه داده SQLite برای ذخیره داده ها استفاده خواهیم کرد، که یک پایگاه داده مبتنی بر فایل بسیار سبک وزن است. می توانید نصب کنید مرورگر DB برای SQLite برای ایجاد آسان پایگاه داده

بیایید نام این پایگاه داده را بگذاریم todo.db و آن را در زیر دایرکتوری قرار دهید todo_service_flask. اکنون برای ایجاد جدول، یک پرس و جو ساده اجرا می کنیم:

CREATE TABLE "items" (
    "item" TEXT NOT NULL,
    "status" TEXT NOT NULL,
    PRIMARY KEY("item")
);

همچنین، برای ساده نگه داشتن همه چیز، همه مسیرهای خود را در یک فایل می نویسیم، اگرچه این همیشه تمرین خوبی نیست، به خصوص برای برنامه های بسیار بزرگ.

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

هنگامی که با این ساختار اولیه Flask راحت شدید، می توانید برنامه خود را هر طور که دوست دارید بازسازی کنید.

ساخت اپلیکیشن

برای جلوگیری از نوشتن چندین بار منطق برای کارهایی که معمولاً اجرا می شوند، مانند افزودن موارد به پایگاه داده، می توانیم تعریف کنیم توابع کمکی در یک فایل جداگانه و در صورت لزوم به سادگی با آنها تماس بگیرید. برای این آموزش ما فایل را نامگذاری می کنیم helper.py.

افزودن موارد

برای پیاده سازی این ویژگی به دو چیز نیاز داریم:

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

ابتدا اجازه دهید چند ثابت را تعریف کرده و آن را بنویسیم add_to_list() تابع:

import sqlite3

DB_PATH = './todo.db'   
NOTSTARTED = 'Not Started'
INPROGRESS = 'In Progress'
COMPLETED = 'Completed'

def add_to_list(item):
    try:
        conn = sqlite3.connect(DB_PATH)

        
        
        c = conn.cursor()

        
        c.execute('insert into items(item, status) values(?,?)', (item, NOTSTARTED))

        
        conn.commit()
        return {"item": item, "status": NOTSTARTED}
    except Exception as e:
        print('Error: ', e)
        return None

این تابع با پایگاه داده ارتباط برقرار می کند و پرس و جوی درج را اجرا می کند. آیتم درج شده و وضعیت آن را برمی گرداند.

بعد، ما import چند ماژول و یک مسیر برای مسیر تنظیم کنید /item/new:

import helper
from flask import Flask, request, Response
import json

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

@app.route('/item/new', methods=('POST'))
def add_item():
    
    req_data = request.get_json()
    item = req_data('item')

    
    res_data = helper.add_to_list(item)

    
    if res_data is None:
        response = Response("{'error': 'Item not added - " + item + "'}", status=400 , mimetype='application/json')
        return response

    
    response = Response(json.dumps(res_data), mimetype='application/json')

return response

این request ماژول برای تجزیه درخواست و دریافت داده های بدنه HTTP یا پارامترهای پرس و جو از URL استفاده می شود. response برای بازگرداندن پاسخ به مشتری استفاده می شود. پاسخ از نوع است JSON.

اگر می‌خواهید درباره خواندن و نوشتن JSON در پایتون اطلاعات بیشتری کسب کنید، ما شما را تحت پوشش قرار داده‌ایم!

ما یک وضعیت را برگرداندیم 400 اگر مورد به دلیل برخی از خطاهای مشتری اضافه نشده باشد. این json.dumps() تابع شیء یا فرهنگ لغت پایتون را به یک شیء معتبر JSON تبدیل می کند.

اجازه دهید کد را ذخیره کنیم و بررسی کنیم که آیا ویژگی ما به درستی پیاده سازی شده است یا خیر.

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

$ curl -X POST http://127.0.0.1:5000/item -d '{"item": "Setting up Flask"}' -H 'Content-Type: application/json'

اگر شما روی ویندوز، باید داده‌های JSON را از نقل قول‌های تکی به نقل‌قول‌های دوبل قالب‌بندی کنید و از آن فرار کنید:

$ curl -X POST http://127.0.0.1:5000/item -d "{\"item\": \"Setting up Flask\"}" -H 'Content-Type: application/json'

لطفا به موارد زیر توجه کنید:

  • URL ما از دو بخش تشکیل شده است – الف URL پایه (http://127.0.0.1:5000) و مسیر یا مسیر (/item/new)
  • روش درخواست است پست
  • هنگامی که درخواست به وب سرور می رسد، سعی می کند نقطه پایانی را بر اساس مکان یابی کند روی این اطلاعات
  • ما داده‌ها را در قالب JSON ارسال می‌کنیم – {“item”: “Setting up Flask”}

همانطور که درخواست را ارسال می کنیم، باید با پاسخ استقبال کنیم:

{"Setting up Flask": "Not Started"}

اجازه دهید دستور زیر را اجرا کنیم تا یک مورد دیگر به لیست اضافه کنیم:

$ curl -X POST http://127.0.0.1:5000/item -d '{"item": "Implement POST endpoint"}' -H 'Content-Type: application/json'

باید با پاسخی که شرح وظیفه و وضعیت آن را به ما نشان می‌دهد، استقبال کنیم:

{"Implement POST endpoint": "Not Started"}

تبریک می گویم!!! ما عملکرد افزودن یک مورد به لیست کارها را با موفقیت پیاده سازی کردیم.

بازیابی همه موارد

ما اغلب می خواهیم همه موارد را از یک لیست دریافت کنیم، که خوشبختانه بسیار آسان است:

def get_all_items():
    try:
        conn = sqlite3.connect(DB_PATH)
        c = conn.cursor()
        c.execute('select * from items')
        rows = c.fetchall()
        return { "count": len(rows), "items": rows }
    except Exception as e:
        print('Error: ', e)
        return None

این تابع با پایگاه داده ارتباط برقرار می کند و a ایجاد می کند انتخاب کنید query و سپس آن را از طریق اجرا می کند c.fetchall(). این همه رکوردهای بازگردانده شده توسط انتخاب کنید پرس و جو. اگر فقط به یک مورد علاقه مند هستیم، می توانیم در عوض تماس بگیریم c.fetchone().

روش ما، get_all_items یک شی پایتون حاوی 2 آیتم را برمی گرداند:

  • تعداد موارد برگردانده شده توسط این پرس و جو
  • موارد واقعی که توسط پرس و جو برگردانده شده است

که در main.py، ما یک مسیر را تعریف می کنیم /item/new که الف را می پذیرد گرفتن درخواست. در اینجا ما نمی گذریم methods استدلال کلمه کلیدی به @app.route()، زیرا اگر از این پارامتر بگذریم، به صورت پیش فرض در نظر گرفته شده است گرفتن:

@app.route('/items/all')
def get_all_items():
    
    res_data = helper.get_all_items()

    
    response = Response(json.dumps(res_data), mimetype='application/json')
    return response

بیایید از cURL برای واکشی موارد و آزمایش مسیر خود استفاده کنیم:

$ curl -X GET http://127.0.0.1:5000/items/all

ما باید با پاسخ استقبال کنیم:

json {"count": 2, "items": (("Setting up Flask", "Not Started"), (Implement POST endpoint", "Not Started"))}

دریافت وضعیت اقلام فردی

مانند مثال قبلی، یک تابع کمکی برای این کار خواهیم نوشت:

def get_item(item):
try:
    conn = sqlite3.connect(DB_PATH)
    c = conn.cursor()
    c.execute("select status from items where item='%s'" % item)
    status = c.fetchone()(0)
    return status
except Exception as e:
    print('Error: ', e)
    return None

ما همچنین یک مسیر را در آن تعریف خواهیم کرد main.py برای تجزیه درخواست و ارائه پاسخ. برای پذیرش الف به مسیر نیاز داریم گرفتن درخواست و نام مورد باید به عنوان پارامتر پرس و جو ارسال شود.

یک پارامتر پرس و جو در قالب ارسال می شود ?name=value با URL به عنوان مثال http://base-url/path/to/resource/?name=value. اگر فضاهایی در ارزش شما باید آنها را با هر کدام جایگزین کنید + یا با %20، که نسخه رمزگذاری شده با URL یک فضا است. شما می توانید چندین جفت نام-مقدار با جدا کردن آنها با علامت داشته باشید & شخصیت.

در اینجا چند نمونه معتبر از پارامترهای پرس و جو آورده شده است:

  • http://127.0.0.1:8080/search؟query=what+is+flask
  • http://127.0.0.1:8080/search؟category=mobiles&brand=apple
@app.route('/item/status', methods=('GET'))
def get_item():
    
    item_name = request.args.get('name')

    
    status = helper.get_item(item_name)

    
    if status is None:
        response = Response("{'error': 'Item Not Found - %s'}"  % item_name, status=404 , mimetype='application/json')
        return response

    
    res_data = {
        'status': status
    }

    response = Response(json.dumps(res_data), status=200, mimetype='application/json')
    return response

دوباره، بیایید از cURL برای ارسال درخواست استفاده کنیم:

$ curl -X GET http://127.0.0.1:5000/item/status؟name=Setting+up+Flask

ما باید با پاسخ استقبال کنیم:

{"status": "Not Started"}

به روز رسانی موارد

از آنجایی که مدتی پیش کار “تنظیم فلاسک” را تکمیل کردیم، وقت آن رسیده است که وضعیت آن را به “تکمیل شده” به روز کنیم.

ابتدا اجازه دهید یک تابع در آن بنویسیم helper.py که کوئری به روز رسانی را اجرا می کند:

def update_status(item, status):
    
    if (status.lower().strip() == 'not started'):
        status = NOTSTARTED
    elif (status.lower().strip() == 'in progress'):
        status = INPROGRESS
    elif (status.lower().strip() == 'completed'):
        status = COMPLETED
    else:
        print("Invalid Status: " + status)
        return None

    try:
        conn = sqlite3.connect(DB_PATH)
        c = conn.cursor()
        c.execute('update items set status=? where item=?', (status, item))
        conn.commit()
        return {item: status}
    except Exception as e:
        print('Error: ', e)
        return None

این تمرین خوبی است که تکیه نکنید روی ورودی کاربر و تأیید اعتبار ما، زیرا ما هرگز نمی دانیم که کاربر نهایی با برنامه ما چه کند. اعتبارسنجی‌های بسیار ساده‌ای در اینجا انجام می‌شوند، اما اگر این یک برنامه واقعی بود، می‌خواهیم در برابر ورودی‌های مخرب دیگر محافظت کنیم، مانند تزریق SQL حملات

در مرحله بعد، مسیری را در آن تنظیم می کنیم main.py که الف را می پذیرد قرار دادن روش به روز رسانی منبع:

@app.route('/item/update', methods=('PUT'))
def update_status():
    
    req_data = request.get_json()
    item = req_data('item')
    status = req_data('status')

    
    res_data = helper.update_status(item, status)

    
    if res_data is None:
        response = Response("{'error': 'Error updating item - '" + item + ", " + status   +  "}", status=400 , mimetype='application/json')
        return response

    
    response = Response(json.dumps(res_data), mimetype='application/json')

    return response

بیایید از cURL برای آزمایش این مسیر استفاده کنیم، درست مثل قبل:

$ curl -X PUT http://127.0.0.1:5000/item/update -d '{"item": "Setting up Flask", "status": "Completed"}' -H 'Content-Type: application/json'

ما باید با پاسخ استقبال کنیم:

{"Setting up Flask": "Completed"}

حذف موارد

ابتدا یک تابع در آن می نویسیم helper.py که کوئری حذف را اجرا می کند:

def delete_item(item):
    try:
        conn = sqlite3.connect(DB_PATH)
        c = conn.cursor()
        c.execute('delete from items where item=?', (item,))
        conn.commit()
        return {'item': item}
    except Exception as e:
        print('Error: ', e)
        return None

توجه داشته باشید: لطفا توجه داشته باشید (item,) اشتباه تایپی نیست باید پاس کنیم execute() یک تاپل حتی اگر فقط یک مورد در تاپل وجود داشته باشد. اضافه کردن کاما این را مجبور می کند تا به یک تاپل تبدیل شود.

در مرحله بعد، مسیری را در آن تنظیم می کنیم main.py که می پذیرد حذف درخواست:

@app.route('/item/remove', methods=('DELETE'))
def delete_item():
    
    req_data = request.get_json()
    item = req_data('item')

    
    res_data = helper.delete_item(item)

    
    if res_data is None:
        response = Response("{'error': 'Error deleting item - '" + item +  "}", status=400 , mimetype='application/json')
        return response

    
    response = Response(json.dumps(res_data), mimetype='application/json')

    return response

بیایید از cURL برای آزمایش مسیر حذف خود استفاده کنیم:

$ curl -X DELETE http://127.0.0.1:5000/item/remove -d '{"item": "Setting up Flask"}' -H 'Content-Type: application/json'

ما باید با پاسخ استقبال کنیم:

{"item": "Temporary item to be deleted"}

و این برنامه را با تمام ویژگی‌های بک‌اند مورد نیاز ما تکمیل می‌کند!

نتیجه

امیدوارم این آموزش به شما درک خوبی از روش استفاده از Flask برای ساختن یک برنامه وب ساده مبتنی بر REST داده باشد. اگر با سایر فریمورک‌های پایتون مانند جنگو تجربه دارید، ممکن است مشاهده کرده باشید که استفاده از Flask بسیار آسان‌تر است.

این آموزش تمرکز بیشتری داشت روی جنبه بک‌اند برنامه، بدون هیچ رابط کاربری گرافیکی، اگرچه می‌توانید از Flask برای رندر صفحات و قالب‌های HTML نیز استفاده کنید، که برای مقاله دیگری ذخیره می‌کنیم.

در حالی که استفاده از Flask برای مدیریت قالب‌های HTML کاملاً خوب است، اکثر مردم از Flask برای ساخت خدمات باطن و ساخت بخش جلویی برنامه با استفاده از هر یک از کتابخانه‌های محبوب جاوا اسکریپت استفاده می‌کنند. شما می توانید آنچه را که برای شما بهتر کار می کند امتحان کنید. موفق باشید روی سفر فلاسک شما!

اگر می‌خواهید با کد منبع بازی کنید یا در اجرای آن از کد بالا مشکل دارید، اینجاست روی GitHub!

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-22 04:28:03

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید