کدنویسی REST API با پایتون – از صفر تا صد


پیش از آن که دست به ساخت یک اپلیکیشن واقعی بزنیم باید یک گام به عقب بیاییم و با خود بیندیشیم که ماهیت یک REST API در سطح بالا به چه معنا است. REST API واقعاً چیز جدیدی محسوب نمیشود. این نوع از API از حدود سال 2000 معرفی شده است، اما اخیراً و با معرفی کتابخانههای جاوا اسکریپت بر محبوبیت آن اضافه شده است. در این مقاله با روش کدنویسی REST API با پایتون آشنا خواهیم شد.
اگر در مورد همه جزئیات دقیق آن کنجکاو هستید باید دست به جستجو زده و در مورد آن معلومات کسب کنید. اما در ادامه توضیح مختصری در مورد REST API ارائه میکنیم. REST API در سطح بالا روشی است که به توسعهدهنده امکان ارسال دادهها بین بخشهای فرانتاند و بکاند اپلیکیشن را میدهد. REST API از مفاهیم CRUD استفاده میکند. انواع مختلف عملیات CRUD روی بخشی از دادهها درون یک دیتابیس اجرا میشود اما ما در REST API نیز از فعلهای POST،GET، PUT و DELETE استفاده میکنیم.
اکنون که مختصری با REST API آشنا شدیم، اقدام به ساخت یک نمونه عملی از آن با پایتون میکنیم. اگر هیچ یک از این مفاهیم برای شما معنی ندارند، نگران نباشید، چون کدی که مینویسیم آن قدر گویا است که میتواند راهنمای شما باشد.
گام یکم: نصب Flask
نخستین گام برای ساخت این اپلیکیشن و راهاندازی آن، نصب Flask است. Flask به طور خلاصه یک میکرو فریمورک وب است که امکان ایجاد «نقاط انتهایی» (Endpoint) پایتون را فراهم میسازد. این میکرو فریمورک قابلیتهای دیگری نیز دارد، اما ما در این مقاله روی بخشهای مرتبط با REST API تمرکز میکنیم. فریمورکهای دیگری نیز وجود دارند که با استفاده از آنها میتوانیم این کار را انجام دهیم، اما فلسک فریمورک کاملاً محبوبی است و از این رو در این راهنما با آن کار میکنیم.
نصب فلسک کار کاملاً آسانی است. ما از پایتون نسخه 3.8 استفاده میکنیم، اما شما میتوانید از هر نسخه پایتون 3 استفاده کنید.
pip install flask
یا
pip3 install flask
اگر چند نسخه از pip روی رایانه خود نصب دارید، مطمئن شوید که از pip 3 استفاده میکنید. زمانی که فلسک نصب شد، مشاهده میکنید که برخی موارد الزامی دیگر نیز نصب میشوند.
اکنون برای این که مطمئن شویم فلسک روی رایانه نصب شده است دستور زیر را اجرا میکنیم:
flask --version
چنان که میبینید ما از پایتون 3.8.5 استفاده کردهایم و فلسک نسخه 1.1.2 را روی رایانه نصب نمودهایم. همچنین Werkzeug نیز نصب شده است.
گام دوم: راهاندازی اپلیکیشن فلسک
اکنون که فلسک روی رایانه نصب شده است، باید پروژه خود را راهاندازی کنیم. معنی این حرف آن است که باید یک فایل جدید پایتون ایجاد کنیم. بنابراین یک فایل به نام main.py میسازیم. زمانی که فایل جدید ایجاد شد، باید در آن کدهایی بنویسیم که امکان اجرای اپلیکیشن فلسک را به ما بدهند.
به این منظور از کدهای زیر استفاده میکنیم:
1#main.py
2
3# Import the Flask module that has been installed.
4from flask import Flask
5
6# Creating a new "app" by using the Flask constructor. Passes __name__ as a parameter.
7app = Flask(__name__)
8
9# Annotation that allows the function to be hit at the specific URL.
10@app.route("/")
11# Generic Python functino that returns "Hello world!"
12def index():
13 return "Hello world!"
14
15# Checks to see if the name of the package is the run as the main package.
16if __name__ == "__main__":
17 # Runs the Flask application only if the main.py file is being run.
18 app.run()
این قطعه کد کاملاً سرراست است. ما در ابتدا شیء Flask را در بخش ابتدای فایل ایمپورت میکنیم. پس از ایمپورت، یک شیء جدید Flask را با ایجاد متغیر app تعریف میکنیم. به این ترتیب سازنده Flask نام پکیج را در خط 7 از ما میگیرد.
بخش جالب ماجرا در خط 10 اتفاق میافتد. ما یک route تعریف میکنیم. در واقع هر رشتهای که درون آن قرار دهیم یک صفحه وب برای اپلیکیشن ما خواهد شد. این مسئله زمانی که شروع به پیادهسازی نقطه انتهایی REST خود بکنیم اهمیت دوچندان خواهد یافت. اکنون یک اپلیکیشن ساده فلسک داریم. در بخش بعد آن را آغاز میکنیم.
گام سوم: آغاز اپلیکیشن فلسک
به فایلی بروید که درون ترمینال ایجاد کردهاید و دستور زیر را اجرا کنید:
python main.py
اینک باید پس از اجرای فایل main.py یک خروجی مانند تصویر فوق ببینید.
اکنون دو کار است که میتوانید انجام دهید تا مطمئن شوید که اپلیکیشن کار خواسته شده را انجام میدهد یا نه. گزینه نخست این است که مرورگر را باز کنید و به سایتی که اجرا کرده است در نشانی زیر بروید:
http://127.0.0.1:5000/
یا این که میتوانید به نشانی زیر بروید:
http://localhost:5000/
به این ترتیب مرورگرتان عبارت Hello world! را نمایش میدهد.
گزینه دوم این است که به جای رفتن به یک صفحه وب در مرورگر، نشانی URL مورد نظر را curl کنید:
curl http://localhost:5000/
در این حالت خروجی Hello world! را در ترمینال مشاهده میکنید.
احتمالاً برخی خروجیها را در ترمینال مشاهده میکنید که اتفاقاتی که تا اینجا در اپلیکیشن استفاده است را بازگو میکنند.
اگر همه این موارد را مشاهده کردید، به این معنی است که همه کارها را به درستی انجام دادهاید. به این ترتیب یک اپلیکیشن ساده فلسک دارید که راهاندازی و اجرا شده است. احتمالاً در زمان کار روی مثال Hello world! متوجه شدهاید که فلسک تا چه حد در ایجاد وباپلیکیشنها قوی عمل میکند. با این حال ما قصد داریم با ایجاد نقطه انتهایی REST API قدرت آن را بیشتر نمایش دهیم.
گام چهارم: ایجاد نقطه انتهایی REST API
اکنون که یک مسیر اندیس ابتدایی داریم که کاربران میتوانند مشاهده کنند، اما باید به کاربران امکان دسترسی به یک نقطه انتهایی بدهیم که بتوانند به مدل خاصی که میخواهیم بسازیم دسترسی داشته باشند. این همان جایی است که نقطه انتهایی REST به کارمان میآید. این بخش نیز به همان میزان بخشهای قبلی ساده است. مفهوم کلی کار یکسان است و صرفاً باید به چند نکته مهم توجه کنیم.
به خاطر داشته باشید که REST API دادهها را از یک اپلیکیشن بازیابی کرده و همچنین دادهها را به یک اپلیکیشن ارائه میکند. در این مثال، ما یک نقطه انتهایی ایجاد میکنیم که کاربرانمان بتوانند دادهها را از اپلیکیشن دریافت کنند. ما قصد نداریم دادهها را درون اپلیکیشن قرار دهیم، چون به این منظور باید یک دیتابیس داشته باشیم. اگر میخواهید این کار را انجام دهید، میتوانید به عنوان یک تمرین برای اجرای آن تلاش کنید.
فرض کنید میخواهیم اپلیکیشنی ایجاد کنیم که در آن کتابها را ذخیره میسازیم. مدل ما که در دیتابیس ذخیره میشود چیزی مانند زیر است:
1{
2 "books": [
3 {
4 "id": 1,
5 "title": "Harry Potter and the Goblet of Fire",
6 "author": "J.K. Rowling",
7 "isbn": "1512379298"
8 },
9 {
10 "id": 2,
11 "title": "Lord of the Flies",
12 "author": "William Golding",
13 "isbn": "0399501487"
14 }
15 ]
16}
اکنون که مدل خود را میشناسیم، باید ببینیم که کد مورد نیاز برای ایجاد نقطه انتهایی کتابها چطور است:
1#main.py
2
3# Import the Flask module that has been installed.
4from flask import Flask, jsonify
5
6# Createing a "books" JSON / dict to emulate data coming from a database.
7books = [
8 {
9 "id": 1,
10 "title": "Harry Potter and the Goblet of Fire",
11 "author": "J.K. Rowling",
12 "isbn": "1512379298"
13 },
14 {
15 "id": 2,
16 "title": "Lord of the Flies",
17 "author": "William Golding",
18 "isbn": "0399501487"
19 }
20]
21
22# Creating a new "app" by using the Flask constructor. Passes __name__ as a parameter.
23app = Flask(__name__)
24
25# Annotation that allows the function to be hit at the specific URL.
26@app.route("/")
27# Generic Python function that returns "Hello world!"
28def index():
29 return "Hello world!"
30
31# Annotation that allows the function to be hit at the specific URL. Indicates a GET HTTP method.
32@app.route("/library/v1.0/books", methods=["GET"])
33# Function that will run when the endpoint is hit.
34def get_books():
35 # Returns a JSON of the books defined above. jsonify is a Flask function that serializes the object for us.
36 return jsonify({"books": books})
37
38# Checks to see if the name of the package is the run as the main package.
39if __name__ == "__main__":
40 # Runs the Flask application only if the main.py file is being run.
41 app.run()
در قطعه کد فوق، میبینید که لیست books به همراه تابع جدید get_books اضافه شده است. لیست books همه مدلهایی را که در اپلیکیشن هستند، در خود جای داده است. به طور سنتی این دادهها از پایگاه داده اخذ میشوند، اما از آنجا که ما دیتابیسی نداریم در این راهنما از یک واسطه استفاده میکنیم.
بخش دوم جایی است که تابع جدیدی به نام اضافه شده است. این تابع مشابه تابع قبلی است، اما URL آن شبیه یک REST API سنتی است. خصوصیت دیگری که اضافه شده است methods نام دارد. این خصوصیت به فلسک اعلام میکند که نوع متدی که باید اجرا کند چیست. در این مورد میخواهیم یک Get اجرا کنیم که معادل عملیات READ در استاندارد CRUD است. بنابراین زمانی که URL باز شود، همه کتابهای مختلف موجود در اپلیکیشن با اجرای یک نسخه JSON از دیکشنری که قبلاً در فایل ایجاد کردهایم به دست میآیند.
توجه کنید که jsonify یک تابع فلسک است که یک دیکشنری را به یک پاسخ JSON تبدیل میکند. اکنون میتوانیم گام را فراتر گذارده و این اپلیکیشن را با اجرای کارهایی که در گام قبلی انجام دادیم تست کنیم. تنها استثنا این است که این بار باید به URL جدید برویم تا تابع get_books اجرا شود. ما به جای مرورگر از curl استفاده میکنیم.
curl http://localhost:5000/library/v1.0/books
اکنون ما موفق شدهایم REST API خاص خودمان را بسازیم. این REST API یک JSON به ما بازگشت میدهد. این بدان معنی است که اگر تا کنون با هر نوع API کار کرده باشید، این همان قالب دادههایی است که از REST API دریافت کردهاید. بدیهی است که ما نمیخواهیم همه نقاط انتهایی مختلف که ایجاد کردیم را توضیح دهیم چون این مقاله بسیار طولانی میشود. با این حال یک GET با یک ID خاص از مدل ایجاد میکنیم که یک نمونه گویا برای بقیه موارد محسوب میشود.
بنابراین در ادامه یک نقطه انتهایی برای ID خاص را میبینید:
1# Annotation that allows the function to be hit at the specific URL with a parameter. Indicates a GET HTTP method.
2@app.route("/library/v1.0/books/<int:book_id>", methods=["GET"])
3# This function requires a parameter from the URL.
4def get_book(book_id):
5 # Create an empty dictionary.
6 result = {}
7
8 # Loops through all the different books to find the one with the id that was entered.
9 for book in books:
10 # Checks if the id is the same as the parameter.
11 if book["id"] == book_id:
12 # Sets the result to the book and makes it a JSON.
13 result = jsonify({"book": book})
14
15 # Returns the book in JSON form or an empty dictionary. Should handle the error like 404, but will not cover here.
16 return result
کد فوق شامل تابعی است که کتاب خاصی را بر اساس ID بازیابی میکند بخش مهمی که باید روی آن متمرکز شوید نه کد تابع، بلکه حاشیهنویسی (annotation) آن است. مسیر مشخصشده همان URL است به جز این که در انتهای آن عبارت <int:book_id> آمده است. این کار به کاربر امکان میدهد که شماره خاصی را مانند آن چه در تصویر زیر میبینید در URL قرار دهد.
این تابع هنوز امکان مدیریت خطا را ندارد و زمانی که کاربر به یک book_id دسترسی پیدا کند که وجود ندارد با خطا مواجه خواهیم شد. این حالت باید مانند هر برنامه دیگری مدیریت شود به جز این که در این حالت میخواهیم کاربر بداند که این یک خطای 404 است. با این حال نکته اصلی که باید روی آن متمرکز شوید فرایند ایجاد مسیرهای مختلف است تا کاربران بتوانند به آنها دسترسی پیدا کنند. مدیریت خطا موضوع کاملاً مجزایی است که بررسی آن خارج از حیطه این مقاله است.
سخن پایانی
در این مقاله با روش ایجاد یک REST API کاملاً ساده در پایتون آشنا شدیم. ساخت REST API چیزی است که هر توسعهدهنده وب باید با آن آشنا باشد. توجه کنید که ما در این مقاله تنها به بیان کلیات موضوع اکتفا کردیم و شما باید بیشتر تحقیق و مطالعه کنید تا با جزییات موضوع به خوبی آشنا شوید. کد کامل REST API که طراحی کردیم برای بررسی بیشتر در ادامه ارائه شده است.
1#main.py
2
3# Import the Flask module that has been installed.
4from flask import Flask, jsonify
5
6# Createing a "books" JSON / dict to emulate data coming from a database.
7books = [
8 {
9 "id": 1,
10 "title": "Harry Potter and the Goblet of Fire",
11 "author": "J.K. Rowling",
12 "isbn": "1512379298"
13 },
14 {
15 "id": 2,
16 "title": "Lord of the Flies",
17 "author": "William Golding",
18 "isbn": "0399501487"
19 }
20]
21
22# Creating a new "app" by using the Flask constructor. Passes __name__ as a parameter.
23app = Flask(__name__)
24
25# Annotation that allows the function to be hit at the specific URL.
26@app.route("/")
27# Generic Python function that returns "Hello world!"
28def index():
29 return "Hello world!"
30
31# Annotation that allows the function to be hit at the specific URL. Indicates a GET HTTP method.
32@app.route("/library/v1.0/books", methods=["GET"])
33# Function that will run when the endpoint is hit.
34def get_books():
35 # Returns a JSON of the books defined above. jsonify is a Flask function that serializes the object for us.
36 return jsonify({"books": books})
37
38# Annotation that allows the function to be hit at the specific URL with a parameter. Indicates a GET HTTP method.
39@app.route("/library/v1.0/books/<int:book_id>", methods=["GET"])
40# This function requires a parameter from the URL.
41def get_book(book_id):
42 # Create an empty dictionary.
43 result = {}
44
45 # Loops through all the different books to find the one with the id that was entered.
46 for book in books:
47 # Checks if the id is the same as the parameter.
48 if book["id"] == book_id:
49 # Sets the result to the book and makes it a JSON.
50 result = jsonify({"book": book})
51
52 # Returns the book in JSON form or an empty dictionary. Should handle the error like 404, but will not cover here.
53 return result
54
55# Checks to see if the name of the package is the run as the main package.
56if __name__ == "__main__":
57 # Runs the Flask application only if the main.py file is being run.
58 app.run()
امیدواریم این مطلب مورد توجه شما قرار گرفته باشد.
خیلی مفید بود .ممنونم.
سلام
ببخشید من api سایت دیوار رو دارم میخوام ازش تو پایتون استفاده کنم راهنمایی میکنید چگونه استفاده کنم؟