Giới thiệu Flask và xây dựng API cơ bản

Cài đặt và khởi chạy ứng dụng Flask

Để bắt đầu, cài đặt Flask qua lệnh:

pip install flask

Từ hàm tính toán đến API web

Xét hàm cộng đơn giản:

def sum_two(x, y):
    return x + y

Khi tham số truyền vào là chuỗi số, cần chuyển đổi kiểu dữ liệu:

params = {'x': '3', 'y': '5'}

def calculate_sum():
    val1 = int(params.get('x'))
    val2 = int(params.get('y'))
    return val1 + val2

Chuyển thành API với Flask

# main.py
from flask import Flask, request

app = Flask(__name__)

@app.route('/sum')
def calculate():
    num1 = request.args.get('x', type=int)
    num2 = request.args.get('y', type=int)
    result = num1 + num2
    return str(result)

Khởi động server bằng lệnh flask run, hoặc thêm đoạn sau vào cuối file để chạy trực tiếp:

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

Truy cập thử nghiệm: http://127.0.0.1:5000/sum?x=3&y=5

Hỗ trợ nhiều phương thức HTTP

Cho phép cả GET và POST:

@app.route('/sum', methods=['GET', 'POST'])

Lấy dữ liệu từ request

  • request.args: tham số URL (query string)
  • request.form: dữ liệu form-urlencoded
  • request.json: dữ liệu JSON
  • request.values: kết hợp args và form

Trả về phản hồi đa dạng

  • Chuỗi đơn giản: return "8"
  • HTML: return "<h1>Kết quả: 8</h1>"
  • JSON: return jsonify(result=8, status="success")
  • Mã trạng thái kèm header: return "", 201, {"X-Custom": "Value"}

Render template

from flask import render_template

@app.route('/profile')
def show_profile():
    user_name = "nguyen_van_a"
    gender = "male"
    abilities = ['Python', 'SQL', 'Flask']
    return render_template('profile.html', 
                         username=user_name, 
                         gender=gender, 
                         skills=abilities)

File templates/profile.html:

<h2>{{ username }}</h2>
<h3>Giới tính:</h3>
{% if gender == "male" %}
Nam
{% else %}
Nữ
{% endif %}

<h3>Kỹ năng:</h3>
<ul>
{% for skill in skills %}
  <li>{{ skill }}</li>
{% endfor %}
</ul>

Chuyển hướng và xử lý lỗi

from flask import redirect, url_for, abort

@app.route('/home')
def go_home():
    return redirect(url_for('index'))

@app.route('/validate')
def validate_input():
    if not request.args.get('required_param'):
        abort(400)  # Bad Request

Ví dụ: API đăng ký người dùng

import pymysql
from flask import Flask, request, jsonify, abort

db_conn = pymysql.connect(
    host='115.28.108.130',
    port=3306,
    user='test',
    password='abc123456',
    db='api_test',
    charset='utf8'
)
cursor = db_conn.cursor()

@app.route('/api/register/', methods=['POST'])
def register_user():
    data = request.get_json()
    if not data:
        abort(400)
    
    username = data.get('username')
    pwd = data.get('password')
    
    if not username or not pwd:
        abort(400)

    cursor.execute('SELECT id FROM user WHERE name=%s', (username,))
    if cursor.fetchone():
        return jsonify(code='DUPLICATE', message='Tên người dùng đã tồn tại')

    try:
        cursor.execute(
            'INSERT INTO user (name, passwd) VALUES (%s, %s)',
            (username, pwd)
        )
        db_conn.commit()
        return jsonify(code='SUCCESS', message='Đăng ký thành công')
    except Exception:
        return jsonify(code='ERROR', message='Lỗi hệ thống')

Bài tập: API đăng nhập

File templates/login_form.html:

<form method="POST">
  <label>Tài khoản: <input type="text" name="username"></label><br>
  <label>Mật khẩu: <input type="password" name="password"></label><br>
  <button type="submit">Đăng nhập</button>
</form>

Code xử lý trong main.py:

@app.route('/login', methods=['GET', 'POST'])
def handle_login():
    if request.method == 'POST':
        user_id = request.form.get('username')
        user_pwd = request.form.get('password')
        
        if not user_id or not user_pwd:
            abort(400)

        cursor.execute(
            'SELECT id FROM user WHERE name=%s AND passwd=%s',
            (user_id, user_pwd)
        )
        if cursor.fetchone():
            return "<h1>✅ Đăng nhập thành công!</h1>"
        else:
            return "<h1>❌ Sai tài khoản hoặc mật khẩu</h1>"

    return render_template('login_form.html')

Giới thiệu ORM với SQLAlchemy

Cài đặt: pip install flask-sqlalchemy

Cấu hình kết nối

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

database = SQLAlchemy(app)

Định nghĩa model

class Article(database.Model):
    __tablename__ = 'articles'
    id = database.Column(database.Integer, primary_key=True)
    title = database.Column(database.String(200), nullable=False)
    content = database.Column(database.Text)
    created_at = database.Column(database.DateTime, default=datetime.utcnow)

Tạo bảng trong cơ sở dữ liệu

$ flask shell
>>> from main import database
>>> database.create_all()

Thao tác CRUD

Thêm bản ghi:

new_article = Article(title='Bài viết đầu tiên', content='Nội dung...')
database.session.add(new_article)
database.session.commit()

Truy vấn:

all_articles = Article.query.all()
first_article = Article.query.first()
specific = Article.query.filter_by(title='Bài viết đầu tiên').first()
by_id = Article.query.get(1)

Sửa bản ghi:

article_to_update = Article.query.get(1)
article_to_update.title = 'Tiêu đề mới'
database.session.commit()

Xóa bản ghi:

article_to_delete = Article.query.get(1)
database.session.delete(article_to_delete)
database.session.commit()

Thẻ: Flask sqlalchemy python-web rest-api orm

Đăng vào ngày 15 tháng 6 lúc 06:00