FA-TOOLS — Header Component

ساخت API ساده با Flask و پایتون

رفیق برنامه‌نویس! تا حالا شده بخوای یه راه ارتباطی هوشمند بین بخش‌های مختلف اپلیکیشن‌هات یا حتی سرویس‌های جداگونه بسازی؟ خب، اینجاست که API به کمک میاد و Flask پایتون مثل یه دوست کاربلد، کارتو خیلی آسون می‌کنه. تو این مقاله قراره با هم قدم به قدم یه API ساده ولی کارآمد بسازیم که بتونی داده‌ها رو بفرستی، بگیری، آپدیت کنی و حذف کنی. این مسیر، دروازه ورود تو به دنیای سرویس‌های بک‌اند و میکروسرویس‌هاست. اگه دنبال ابزارها و اسنیپت‌های خفن پایتون یا هر زبان دیگه‌ای می‌گردی که کارت رو راه بندازه، حتما یه سر به فروشگاه ابزارهای برنامه‌نویسی fa-tools.ir بزن؛ مطمئنم دست خالی برنمی‌گردی!

🗺️ نقشه راه: ساخت API با Flask در یک نگاه

ساخت API ساده با Flask و پایتون — تصویر 1
+-------------------------------------------------------------+
|               🚀 ساخت API با Flask و پایتون                |
+-------------------------------------------------------------+
|                                                             |
| 1️⃣  مقدمه: API و Flask چرا خوبن؟                     |
|    - تعریف ساده API                                         |
|    - مزایای Flask (سبک، منعطف، سریع)                         |
|                                                             |
| 2️⃣  آماده‌سازی محیط: پیش‌نیازها                     |
|    - نصب پایتون و pip                                       |
|    - نصب Flask (pip install Flask)              |
|                                                             |
| 3️⃣  اولین API: Hello World!                        |
|    - کدنویسی یه endpoint ساده                               |
|    - راه‌اندازی و تست                                        |
|                                                             |
| 4️⃣  Endpointهای پیشرفته: GET و POST             |
|    - دریافت داده (GET)                                      |
|    - ارسال داده (POST) و کار با JSON                        |
|    - پارامترهای URL و کوئری                                 |
|                                                             |
| 5️⃣  ذخیره‌سازی داده (اختیاری): SQLite/JSON       |
|    - مفهوم CRUD (Create, Read, Update, Delete)             |
|                                                             |
| 6️⃣  امنیت: احراز هویت ساده با API Key           |
|    - بررسی هدرها برای API Key                               |
|                                                             |
| 7️⃣  دیپلوی: از لوکال تا سرور                    |
|    - WSGI servers (Gunicorn)                                |
|    - پلتفرم‌های میزبانی                                      |
|                                                             |
| 8️⃣  عیب‌یابی: مشکلات رایج و راه‌حل‌ها           |
|                                                             |
| 9️⃣  جمع‌بندی و گام‌های بعدی                     |
|                                                             |
+-------------------------------------------------------------+
| 📞 سوالی داری؟ تماس بگیر: 09202232789      |
+-------------------------------------------------------------+

API چیه اصلاً و چرا با Flask؟

ساخت API ساده با Flask و پایتون — تصویر 2

ببین رفیق، فرض کن دو نفر دارن با هم حرف می‌زنن، اما زبون همدیگه رو نمی‌فهمن. API یا Application Programming Interface دقیقاً نقش مترجم رو بازی می‌کنه. این یه مجموعه قوانین و پروتکل‌های مشخصه که به اپلیکیشن‌های مختلف اجازه می‌ده با هم ارتباط برقرار کنن و داده تبادل کنن. مثلاً وقتی تو اینستاگرام یه عکس آپلود می‌کنی، در پشت صحنه یه API داره با سرور اینستاگرام صحبت می‌کنه.

حالا چرا Flask برای ساخت API؟ دلایلش زیاده، ولی مهم‌تریناش ایناست:

  • سبک و مینی‌مال: Flask یه میکرو-فریم‌ورکه. یعنی برخلاف جنگو که کلی ابزار تو خودش داره، Flask فقط چیزای ضروری رو ارائه می‌ده. این باعث می‌شه خیلی سبک و سریع باشه.
  • انعطاف‌پذیری بالا: چون مینی‌ماله، دستت بازه که هر کتابخونه یا ابزاری که دوست داری رو بهش اضافه کنی و دقیقاً اون چیزی رو بسازی که نیاز داری.
  • یادگیری آسون: سینتکس ساده و مستندات عالی، Flask رو به یه انتخاب عالی برای شروع‌کننده‌ها تبدیل کرده. تو کمترین زمان می‌تونی اولین API خودتو بالا بیاری.
  • جامعه فعال: کلی برنامه‌نویس از Flask استفاده می‌کنن، پس اگه به مشکلی خوردی، پیدا کردن کمک خیلی آسونه.

پیش‌نیازهای شروع کار: ابزارت رو آماده کن!

ساخت API ساده با Flask و پایتون — تصویر 3

قبل از اینکه کدنویسی رو شروع کنیم، باید مطمئن بشیم همه ابزارهای لازم رو داریم. نگران نباش، کارای زیادی نیست.

نصب پایتون و pip

اولین و مهم‌ترین چیز، خود پایتونه. اگه رو سیستمت نصبه که هیچی، وگرنه از سایت رسمی پایتون (python.org) آخرین نسخه پایدار رو دانلود و نصب کن. موقع نصب حتماً تیک “Add Python to PATH” رو بزن تا تو خط فرمان راحت بتونی بهش دسترسی داشته باشی. `pip` هم مدیر بسته پایتونه که معمولاً همراه با پایتون نصب می‌شه. می‌تونی با این دستور چک کنی که هر دو درست کار می‌کنن:

python --version
pip --version

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

محیط مجازی (Virtual Environment)

این بهترین روش برای ایزوله کردن پروژه‌هاته. هر پروژه پایتون بهتره محیط مجازی خودشو داشته باشه تا وابستگی‌هاش با پروژه‌های دیگه قاطی نشن. برای ساخت و فعال‌سازی یه محیط مجازی:

# ساخت محیط مجازی (اسم پوشه رو میذاریم venv)
python -m venv venv

# فعال‌سازی در ویندوز
.venvScriptsactivate

# فعال‌سازی در مک/لینوکس
source venv/bin/activate

بعد از فعال‌سازی، اسم محیط مجازی (اینجا `(venv)`) رو اول خط فرمانت می‌بینی.

نصب Flask

حالا که محیط مجازیت فعاله، می‌تونی Flask رو نصب کنی:

pip install Flask

گام به گام: ساخت اولین API فلسک تو

خب، وقتشه دست به کار شیم و یه API واقعی بسازیم! یه فایل به اسم `app.py` درست کن و کد زیر رو توش کپی کن:

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/')
def hello_world():
    return jsonify({"message": "سلام دنیا، این اولین API منه با فلک!"})

if __name__ == '__main__':
    app.run(debug=True)

توضیح کد:

  • `from flask import Flask, jsonify`: اینجا ما کلاس `Flask` رو برای ساخت اپلیکیشن و تابع `jsonify` رو برای برگردوندن داده‌های JSON وارد می‌کنیم.
  • `app = Flask(__name__)`: یه نمونه از کلاس `Flask` می‌سازیم. `__name__` به Flask می‌گه که فایل اصلی اپلیکیشن کجاست.
  • `@app.route(‘/’)`: این یه دکوراتوره که مشخص می‌کنه تابع `hello_world` باید وقتی کاربر به آدرس روت (مثلاً `http://127.0.0.1:5000/`) درخواست می‌فرسته، اجرا بشه.
  • `def hello_world(): return jsonify({“message”: “سلام دنیا، این اولین API منه با فلک!”})`: این تابع یه دیکشنری پایتون رو به فرمت JSON تبدیل می‌کنه و برمی‌گردونه.
  • `if __name__ == ‘__main__’: app.run(debug=True)`: این بخش مطمئن می‌شه که وقتی فایل رو مستقیماً اجرا می‌کنی، سرور Flask شروع به کار کنه. `debug=True` هم برای توسعه عالیه، چون تغییرات کد رو اتوماتیک تشخیص می‌ده و سرور رو ریستارت می‌کنه.

راه‌اندازی اپلیکیشن

بعد از اینکه فایل `app.py` رو ذخیره کردی، تو خط فرمان (در پوشه پروژه و با محیط مجازی فعال) این دستور رو اجرا کن:

python app.py

بعد از اجرا، پیامی شبیه به این می‌بینی:

* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debug mode: on

حالا اگه آدرس `http://127.0.0.1:5000/` رو تو مرورگرت باز کنی، باید یه پیام JSON ببینی: `{“message”: “سلام دنیا، این اولین API منه با فلک!”}`. تبریک می‌گم، اولین API شما با موفقیت راه‌اندازی شد!

ساخت Endpoints برای کارهای مختلف

API فقط “Hello World” نیست! معمولاً برای انجام کارهای مختلف، endpointهای متفاوتی تعریف می‌کنیم. مثلاً یه endpoint برای گرفتن لیست محصولات، یه دونه برای اضافه کردن محصول جدید و الی آخر.

جدول: متدهای اصلی HTTP برای API

متد HTTP کاربرد اصلی
GET دریافت (خواندنی) داده از سرور
POST ایجاد/ارسال (نوشتنی) داده جدید به سرور
PUT به‌روزرسانی کامل یک منبع موجود
DELETE حذف یک منبع

(این جدول برای نمایش بهتر در موبایل، به صورت ستونی هم قابل نمایش است)

درخواست‌های GET (دریافت داده)

این رایج‌ترین نوع درخواسته و برای گرفتن اطلاعات از سرور استفاده می‌شه. بیا یه لیست از کتاب‌ها رو برگردونیم. داخل `app.py`، این کد رو اضافه کن:

from flask import Flask, jsonify, request # request رو هم ایمپورت می‌کنیم

app = Flask(__name__)

books = [
    {'id': 1, 'title': 'کیمیاگر', 'author': 'پائولو کوئلیو'},
    {'id': 2, 'title': 'شازده کوچولو', 'author''آنتوان دو سنت اگزوپری'} # غلط املایی عمدی: 'author'' به جای 'author':
]

@app.route('/books', methods=['GET'])
def get_books():
    return jsonify(books)

@app.route('/books/<int:book_id>', methods=['GET'])
def get_book(book_id):
    for book in books:
        if book['id'] == book_id:
            return jsonify(book)
    return jsonify({"error": "کتاب یافت نشد"}), 404 # برگرداندن کد وضعیت 404

# (همانند قبل)
if __name__ == '__main__':
    app.run(debug=True)

حالا می‌تونی به `http://127.0.0.1:5000/books` درخواست GET بزنی تا لیست همه کتاب‌ها رو بگیری. همچنین با `http://127.0.0.1:5000/books/1` می‌تونی اطلاعات کتاب با شناسه 1 رو بگیری. `<int:book_id>` به Flask می‌گه که این بخش از URL یه عدد صحیحه و باید به عنوان پارامتر `book_id` به تابع ارسال بشه.

درخواست‌های POST (ارسال داده)

برای ارسال داده جدید به سرور (مثلاً اضافه کردن یه کتاب جدید)، از متد `POST` استفاده می‌کنیم. تو Flask، از آبجکت `request` برای دسترسی به داده‌های ارسالی استفاده می‌شه.

@app.route('/books', methods=['POST'])
def add_book():
    if not request.json or 'title' not in request.json:
        return jsonify({"error": "عنوان کتاب الزامی است"}), 400 # Bad Request

    new_book = {
        'id': books[-1]['id'] + 1 if books else 1,
        'title': request.json['title'],
        'author': request.json.get('author', '')
    }
    books.append(new_book)
    return jsonify(new_book), 201 # Created

برای تست این قسمت، به یه ابزار مثل Postman یا VS Code Rest Client نیاز داری. درخواست `POST` رو به `http://127.0.0.1:5000/books` با یه `JSON` در بدنه درخواست (Body) می‌فرستی. مثلاً:

{
    "title": "1984",
    "author": "جورج اورول"
}

پارامترها و URL داینامیک: API هوشمندتر!

دیدیم که چطور با “ می‌تونیم یه بخش از URL رو به عنوان متغیر استفاده کنیم. این‌ها رو URL Parameters می‌گن. علاوه بر این، می‌تونیم از Query Parameters هم استفاده کنیم. Query Parameters بعد از علامت سوال (?) تو URL میان و با `&` از هم جدا می‌شن. مثلاً: ` /search?q=flask&sort=date`.

@app.route('/search', methods=['GET'])
def search_books():
    query = request.args.get('q') # گرفتن پارامتر 'q'
    results = []
    if query:
        for book in books:
            if query.lower() in book['title'].lower() or query.lower() in book['author'].lower():
                results.append(book)
    return jsonify(results)

حالا با `http://127.0.0.1:5000/search?q=شازده` می‌تونی کتاب “شازده کوچولو” رو پیدا کنی.

مدیریت داده‌ها: یه دیتابیس ساده برای API (اختیاری)

تا اینجا، داده‌های ما (لیست `books`) موقت بودن و با هر بار ریستارت شدن سرور، از بین می‌رفتن. برای اینکه داده‌ها دائمی بشن، باید از یه دیتابیس استفاده کنیم. برای یه API ساده، SQLite یه گزینه عالیه چون نیازی به نصب سرور جداگونه نداره و یه فایل ساده است.

برای ارتباط با SQLite می‌تونی از ماژول `sqlite3` پایتون استفاده کنی. یا حتی اگه کارت خیلی ساده‌ست و نمی‌خوای درگیر دیتابیس بشی، می‌تونی داده‌هات رو تو یه فایل JSON ذخیره و بارگذاری کنی. مفهوم CRUD (Create, Read, Update, Delete) دقیقاً همینجاست که معنی پیدا می‌کنه. ما برای هر کدوم از این عملیات، یه endpoint تو APIمون تعریف می‌کنیم.

برای مثال، اضافه کردن متدهای `PUT` (آپدیت) و `DELETE` (حذف) شبیه به `POST` و `GET` هستن، فقط متد HTTP و منطق داخلیشون فرق می‌کنه. اگر نیاز به کدهای آماده برای CRUD با SQLite داری، حتماً بخش کدهای آماده و اسنیپت‌های ما رو بررسی کن.

@app.route('/books/<int:book_id>', methods=['PUT'])
def update_book(book_id):
    book_to_update = next((book for book in books if book['id'] == book_id), None)
    if book_to_update is None:
        return jsonify({"error": "کتاب یافت نشد"}), 404
    book_to_update['title'] = request.json.get('title', book_to_update['title'])
    book_to_update['author'] = request.json.get('author', book_to_update['author'])
    return jsonify(book_to_update)

@app.route('/books/<int:book_id>', methods=['DELETE'])
def delete_book(book_id):
    global books # باید به Flask گفت که داریم لیست گلوبال رو تغییر میدیم
    initial_len = len(books)
    books = [book for book in books if book['id'] != book_id]
    if len(books) == initial_len:
        return jsonify({"error": "کتاب یافت نشد"}), 404
    return jsonify({"message": "کتاب با موفقیت حذف شد"})

امنیت و احراز هویت: API رو قفل و بست کن!

ساختن یه API بدون در نظر گرفتن امنیت، مثل ساختن خونه بدون در و پنجره است. هر کی می‌تونه بیاد و بره! برای APIهای ساده، یه روش اولیه برای احراز هویت استفاده از API Key هست.

ایده اینه که هر کاربری که می‌خواد از API شما استفاده کنه، یه API Key منحصر به فرد داشته باشه و اون رو تو هدر (Header) درخواست‌های HTTP خودش بفرسته. شما هم تو APIتون این Key رو چک می‌کنید.

# تو یه اپلیکیشن واقعی، این key رو تو یه دیتابیس یا فایل امن نگهداری می‌کنیم
VALID_API_KEY = "YOUR_SUPER_SECRET_API_KEY" # اینو تغییر بده!

@app.before_request # این دکوراتور قبل از هر درخواستی اجرا میشه
def authenticate():
    api_key = request.headers.get('X-API-Key')
    if request.path != '/' and api_key != VALID_API_KEY:
        return jsonify({"error": "Unauthorized"}), 401

با اضافه کردن این کد، هر درخواستی به جز روت اصلی (`/`)، نیاز به هدر `X-API-Key` با مقدار صحیح داره. برای امنیت بیشتر، می‌تونی از JWT (JSON Web Tokens) یا OAuth استفاده کنی که بحثش مفصله. می‌تونی تو اسنیپت‌های پایتون دنبال مثال‌های پیشرفته‌تر امنیتی بگردی.

نکته: هیچ‌وقت کلید API رو تو کد به صورت “Hardcode” نذار. همیشه از متغیرهای محیطی یا سرویس‌های مدیریت Secret استفاده کن.

دیپلوی API: چطوری ببریش رو سرور؟

تا الان API ما روی کامپیوتر خودمون (لوکال هاست) کار می‌کرد. برای اینکه بقیه هم بتونن ازش استفاده کنن، باید ببریمش روی یه سرور. Flask خودش یه سرور داخلی برای توسعه داره (همین `app.run(debug=True)`)، ولی برای محیط پروداکشن به یه سرور قوی‌تر نیاز داریم.

اینجا WSGI servers (مثل Gunicorn یا uWSGI) وارد صحنه می‌شن. این سرورها کار مدیریت درخواست‌ها و اتصال به اپلیکیشن Flask شما رو انجام می‌دن. مثلاً برای Gunicorn:

pip install gunicorn
gunicorn -w 4 app:app # -w تعداد workerها، app:app یعنی فایل app.py و شیء app داخلش

بعد از نصب Gunicorn، می‌تونی سرور رو با دستور بالا راه‌اندازی کنی. حالا دیگه نوبت انتخاب هاستینگ مناسبه. پلتفرم‌هایی مثل Heroku، Vercel (برای سرورلس)، DigitalOcean، Linode یا حتی سرویس‌های ابری مثل AWS و Google Cloud می‌تونن میزبان API شما باشن. هر کدوم مزایا و معایب خودشون رو دارن که بسته به نیاز و بودجه‌ات باید انتخاب کنی. اگه دنبال اسنیپت‌های HTML، CSS یا JS برای فرانت‌انتد پروژه‌هات هستی، به لینک‌های HTML، CSS و JS ما سر بزن.

عیب‌یابی سریع: مشکلات رایج و راه‌حل‌هاشون

مشکلات متداول در ساخت API با Flask

  • “ModuleNotFoundError: No module named ‘flask'”

    راه‌حل: این ارور یعنی Flask نصب نیست یا در محیط مجازی فعال نیست. مطمئن شو که محیط مجازی رو فعال کردی و بعد با `pip install Flask` Flask رو نصب کن.

  • “Port already in use” یا `Address already in use`

    راه‌حل: این یعنی یه برنامه دیگه داره از پورت 5000 (پورت پیش‌فرض Flask) استفاده می‌کنه. می‌تونی سرور قبلی رو ببندی یا پورت Flask رو تو `app.run(debug=True, port=5001)` تغییر بدی.

  • “JSONDecodeError: Expecting value: line 1 column 1 (char 0)”

    راه‌حل: وقتی درخواست `POST` می‌فرستی، مطمئن شو که `Content-Type` درخواستت `application/json` هست و بدنه درخواستت (Body) هم یه JSON معتبره.

  • تغییرات کد رو سرور اعمال نمی‌شه (با وجود `debug=True`)

    راه‌حل: گاهی اوقات تغییرات ذخیره نشده یا مشکل از IDE هست. مطمئن شو فایل رو ذخیره کردی. اگه بازم نشد، سرور رو یک بار دستی با Ctrl+C ببند و دوباره اجرا کن. همچنین، حواست باشه که `debug=True` فقط برای توسعه‌ست و تو پروداکشن باید `debug=False` باشه.

  • بروز خطای `TypeError: ‘NoneType’ object is not callable` هنگام استفاده از `jsonify`

    راه‌حل: این خطا معمولا زمانی رخ می‌دهد که شما `jsonify` را از ماژول `flask` ایمپورت نکرده‌اید. مطمئن شوید که خط `from flask import Flask, jsonify` در ابتدای فایل شما وجود دارد و هیچ متغیری با نام `jsonify` ایجاد نکرده‌اید که مقدار `None` داشته باشد.

همیشه از ابزارهای دیباگینگ (مثل چاپ کردن متغیرها با `print()`) یا لاگ‌های Flask استفاده کن تا مشکل رو پیدا کنی. Flask ابزارهای دیباگینگ خوبی داره که تو محیط توسعه خیلی به کارت میان.

جمع‌بندی و گام‌های بعدی

خب رفیق، تا اینجا با هم یه API ساده با Flask و پایتون ساختیم و مفاهیم اصلی مثل Endpointها، متدهای HTTP، مدیریت داده‌ها و یه ذره امنیت رو بررسی کردیم. Flask با سادگی و انعطاف‌پذیریش یه ابزار فوق‌العاده برای شروع ساخت API هست.

اما این تازه شروع راهه! برای اینکه یه برنامه‌نویس فول‌استک یا بک‌اند کار قهار بشی، باید بری سراغ مباحث پیشرفته‌تر:

  • Flask Blueprints: برای سازماندهی بهتر کد تو پروژه‌های بزرگتر.
  • ORMها (مثل SQLAlchemy): برای کار راحت‌تر با دیتابیس‌ها.
  • Serializing/Deserializing (مثل Marshmallow): برای مدیریت بهتر داده‌های JSON.
  • Authentication/Authorization پیشرفته: مثل JWT یا OAuth2.
  • Testing: نوشتن تست برای اطمینان از صحت عملکرد API.
  • Docker: برای بسته‌بندی و دیپلوی راحت‌تر اپلیکیشن.

فراموش نکن که تمرین و تجربه، بهترین معلمه‌. شروع کن به ساختن! اگه تو مسیر برنامه‌نویسی به هر ابزار، اسنیپت، یا کدی نیاز داشتی، fa-tools.ir همیشه در کنارت هست. بیا و از کلی اسنیپت وردپرس، CSS، و پایتون لذت ببر و کارت رو راه بنداز!

سوالات متداول (FAQ)

سوالات پر تکرار در مورد ساخت API با Flask

  • Q: API دقیقاً چیست؟

    A: API (Application Programming Interface) مجموعه‌ای از قوانین و پروتکل‌هاست که به نرم‌افزارهای مختلف اجازه می‌دهد با یکدیگر ارتباط برقرار کرده و داده مبادله کنند. مثل یک رابط کاربری برای برنامه‌ها، نه انسان‌ها.

  • Q: چرا Flask برای ساخت API مناسب است؟

    A: Flask یک میکرو-فریم‌ورک پایتون است که بسیار سبک، انعطاف‌پذیر و آسان برای یادگیری است. این ویژگی‌ها آن را به گزینه‌ای عالی برای ساخت APIهای کوچک تا متوسط و یا شروع یادگیری بک‌اند تبدیل می‌کند، زیرا شما کنترل کاملی بر انتخاب ابزارها و کتابخانه‌ها دارید.

  • Q: آیا Flask برای APIهای بزرگ و پیچیده هم مناسب است؟

    A: بله، با استفاده از الگوهایی مانند Blueprints برای سازماندهی کد، ORMها برای دیتابیس، و افزودن کتابخانه‌های مناسب برای احراز هویت و اعتبارسنجی، Flask می‌تواند پایه و اساس APIهای بزرگ و مقیاس‌پذیر باشد. هرچند برای پروژه‌های بسیار بزرگ که نیاز به قابلیت‌های “out-of-the-box” بیشتری دارند، فریم‌ورک‌های کامل‌تری مانند Django ممکن است انتخاب شوند.

  • Q: چگونه می‌توان یک API ساخته شده با Flask را روی سرور دیپلوی کرد؟

    A: برای دیپلوی در محیط پروداکشن، شما باید از یک سرور WSGI (مثل Gunicorn یا uWSGI) استفاده کنید که درخواست‌های HTTP را مدیریت کرده و به اپلیکیشن Flask شما ارسال می‌کند. سپس می‌توانید این مجموعه را روی پلتفرم‌های میزبانی مانند Heroku، DigitalOcean، AWS، یا یک VPS اختصاصی قرار دهید.

Table of Contents

آخرین نوشته‌ها