Hướng dẫn lập trình Flask – Phần 1: Hello World!

flask_tutorial_1

Loạt bài viết này sẽ hướng dẫn lập bạn cách tạo ra một ứng dụng Web đơn giản với Python và Flask framework.

Để giúp cho bạn dễ theo dõi, sau đây là danh sách các bài viết trong loạt bài hướng dẫn này:

Bạn có thể truy cập mã nguồn cho phần này tại GitHub.

Tại sao lại dùng Python mà không phải các ngôn ngữ khác?

Python là một ngôn ngữ đa năng và dễ học. Các chương trình viết bằng Python thường ngắn gọn và dễ hiểu. Nó cũng sở hữu một thư viện với các hàm và lớp xây dựng sẵn để tạo ra hầu hết các ứng dụng một cách nhanh chóng, từ các chương trình quản lý hệ thống cho đến các ứng dụng Web hoặc xa hơn nữa là các ứng dụng về trí tuệ nhân tạo hoặc phân tích dữ liệu. Nhược điểm của Python là chạy chậm hơn một số ngôn ngữ biên dịch (C/C++ hoặc thậm chí là Java hay C#). Tuy nhiên, với các hệ thống phần cứng hiện nay thì điểm yếu này có thể được bỏ qua trong một số điều kiện nhất định. Python là một ngôn ngữ hoàn hảo để xây dựng các ứng dụng nhỏ và vừa cho nhu cầu cá nhân hoặc doanh nghiệp.

Tại sao lại là Flask? Không phải Django mới là Web framework phổ biến nhất dựa trên Python hay sao?

Theo mức độ phổ biến, các ứng dụng Web trên nền tảng Django nhiều hơn là Flask. Tuy vậy, điều đó không đưa đến kết luận là Django tốt hơn Flask. Nếu muốn xây dựng một ứng dụng với thời gian ngắn nhất, Django dĩ nhiên là một lựa chọn tốt. Nhưng xét về tính linh hoạt, Django lại không bằng Flask. Với Django, các thành phần cơ bản của ứng dụng đã được định nghĩa sẵn, vì vậy khó tùy biến hơn. Ngược lại, Flask cho phép người lập trình lựa chọn và ghép nối các thành phần theo ý mình. Vì vậy, Flask là lựa chọn tốt cho những ai muốn tìm hiểu sâu về các Web framework và muốn có mức độ tùy biến cao.

Để thực hành theo loạt bài hướng dẫn này, bạn cần chuẩn bị các bước như sau:

Cài đặt Python

Nếu máy của bạn không có sẵn Python, bạn cần cài đặt nó. Tùy theo hệ điều hành bạn đang sử dụng, bạn sẽ dùng những trình cài đặt khác nhau (nếu là Windows, bạn có thể download trực tiếp trình cài đặt từ trang chủ của Python – https://www.python.org/downloads/. Nếu là Mac OS X, bạn cần dùng homebrew, nếu là Linux, bạn phải dùng trình quản lý gói thích hợp tùy theo bản phân phối bạn đang sử dụng – apt trên Ubuntu hoặc Debian, dnf trên Fedora, yum trên RHEL hoặc CentOS …). Tuy nhiên, dù dùng hệ điều hành nào đi nữa, hãy chắc rằng bạn cài đặt Python 3 vì Python 2 sẽ kết thúc vòng đời và không được hỗ trợ kể từ tháng 1 năm 2020.

Để kiểm tra xem Python đã được cài đặt và hoạt động tốt trên máy của bạn hay không, bạn có thể dùng cửa sổ lệnh (Command Prompt hoặc Windows PowerShell trên Window, terminal trên Mac OS X hoặc Linux) và dùng lệnh python3 (nếu lệnh này không hoạt động, bạn có thể thử chỉ dùng python). Nếu Python được cài đặt và hoạt động, sau khi dùng lệnh này, bạn sẽ thấy kết quả như sau:

Dấu nhắc >>> cho biết trình thông dịch Python đã sẵn sàng và đang đợi lệnh, bạn có thể bắt đầu nhập các lệnh tại dấu nhắc và bắt đầu phiên làm việc của mình. Trong những chương tiếp theo, bạn sẽ tìm hiểu kỹ hơn về dấu nhắc này. Tuy nhiên, trong lúc này, nó chỉ đơn giản cho chúng ta biết là Python đã được cài đặt và hoạt động tốt. Để thoát khỏi trình thông dịch Python, bạn có thể nhập lệnh exit() tại dấu nhắc hoặc dùng phím tắt (Ctrl-D trên Linux hoặc Mac OS X, Ctrl-Z trên Windows).

Cài đặt Flask

Bước tiếp theo là cài đặt Flask, có một vài cách khác nhau để làm điều này. Tuy nhiên, chúng ta sẽ tìm hiểu cách tốt nhất để cài đặt các gói thư viện (package) mà Flask là một trong số chúng.

Trong Python, bạn có thể tìm các gói thư viện như Flask từ các kho lưu trữ công cộng (public repository). Các kho lưu trữ này cho phép bất cứ người sử dụng nào có thể truy cập và tải về các gói thư viện Python. Kho lưu trữ công cộng chính thức của Python gọi là PyPI (viết tắt của Python Package Index). Việc cài đặt các gói từ PyPI rất đơn giản với một công cụ có sẵn trong trình cài đặt Pyhon gọi là pip (pip được tích hợp sẵn trong các phiên bản Python 3, trong Python 2, chúng ta cần cài pip riêng. Tuy vậy, vì chúng ta đang dùng Python3, việc cài đặt pip là không cần thiết).

Để cài đặt một gói Python, bạn có thể dùng lệnh pip như sau:

Tuy nhiên trong thực tế, việc sử dụng lệnh pip như trên không phổ biến vì một số lý do. Nếu trình thông dịch Python được cài đặt trên máy của bạn ở mức độ toàn phần (global) để mọi người sử dụng (user) đều có thể sử dụng được, có khả năng rất lớn là tài khoản mà bạn dùng để đăng nhập (login) không có đủ thẩm quyền để sao chép các file cần thiết trong quá trình cài đặt vào đúng vị trí của chúng (dĩ nhiên đều này không luôn luôn đúng – đặc biệt nếu bạn có quyền Admin với máy của bạn. Nhưng đây là nguyên tắc chung được áp dụng cho bất kỳ hệ thống nào tại các môi trường làm việc chung – công ty, tổ chức …). Và cho dù là bạn có thể chạy lệnh pip để cài đặt gói ở mức độ toàn phần, vẫn còn một rắc rối khác: nếu bạn cài đặt một gói thành công ở mức toàn phần, pip sẽ tải gói được yêu cầu từ PyPI và cài đặt vào trình Python có sẵn trong máy của bạn. Từ thời điểm này, tất cả các chương trình Python trên hệ thống của bạn sẽ sử dụng gói này. Giả sử như trước đó bạn sử dụng một phiên bản cũ của gói (ví dụ như Flask phiên bản 0.11) để viết một ứng dụng. Tại thời điểm bạn viết ứng dụng đó, Flask 0.11 là phiên bản mới nhất. Nhưng về sau, bạn cần viết một ứng dụng khác, và lúc đó, đã có một phiên bản Flask mới hơn, ví dụ như 0.12. Nếu bạn dùng pip để cài đặt Flask 0.12 ở mức độ toàn phần, phiên bản này sẽ thay thế hoàn toàn phiên bản 0.11 trong hệ thống của bạn. Điều gì sẽ xảy ra với ứng dụng cũ sử dụng Flask 0.11? Trong một số trường hợp nhất định, nó có thể sẽ không hoạt động nữa vì nó không tương thích với Flask phiên bản 0.12. Vì vậy, cách tốt nhất là tìm ra cách để cài đặt cả hai phiên bản Flask trong hệ thống của bạn, một cho ứng dụng cũ và một cho ứng dụng mới.

Để giải quyết vấn đề cài đặt song song nhiều phiên bản của cùng một gói thư viện cho các ứng dụng khác nhau, Python đưa ra khái niệm môi trường ảo (virtual environment). Một môi trường ảo là một bản sao hoàn chỉnh của trình thông dịch Python. Khi bạn cài đặt một gói thư viện trong một môi trường ảo, trình thông dịch Python đã được cài đặt cho toàn hệ thống (hay ở mức toàn phần) không bị ảnh hưởng, gói mới được cài đặt chỉ có tác dụng trong phạm vi của môi trường ảo mà thôi. Vì vậy, chúng ta có thể tự do cài đặt các gói cần thiết trong phạm vi của môi trường ảo mà không sợ rằng chúng sẽ ảnh hưởng đển các ứng dụng trong các môi trường ảo khác. Ngoài ra, mỗi một môi trường ảo hoàn toàn thuộc về người tạo ra nó, hay nói cách khác người tạo ra một môi trường ảo có toàn quyền thêm bớt các gói trong đó mà không cần đến quyền của quản trị hệ thống (Administrator).

Chúng ta có thể bắt đầu bằng cách tạo ra thư mục (directory) cho dự án nhỏ của chúng ta. Chúng ta có thể đặt tên cho nó là thư mục này myblog, đây cũng là tên của ứng dụng mà chúng ta sắp xây dựng. Sử dụng một cửa sổ lệnh, nhập vào các lệnh dưới đây:

Nếu bạn dùng Python 3 như đã được đề nghị ở trên, bạn có thể khởi tạo môi trường ảo với lệnh sau đây:

Lệnh này yêu cầu Python chạy gói venv để khởi tạo một môi trường ảo có tên là myenv. Tham số venv trong lệnh là tên của gói môi trường ảo trong Python, và tham số myenv là tên của môi trường ảo mà chúng ta muốn tạo ra (Một số phiên bản Python 3.x cần có gói python3-venv để chạy lệnh này) .

Xin lưu ý rằng trong một số môi trường, bạn có thể phải sử dụng lệnh python thay vì python3 như ở trên. Một số hệ thống dùng lệnh python cho Python phiên bản 2.x và python3 cho Python phiên bản 3.x, nhưng cũng có một số hệ thống dùng lệnh python cho phiên bản 3.x

Sau khi hệ thống thực hiện lệnh trên, nó sẽ tạo ra một môi trường ảo tên là myenv dưới hình thức một thư mục cùng tên. Thư mục này sẽ có các file dành cho môi trường ảo này.

Cũng xin lưu ý là các phiên bản Python cũ hơn 3.4 không hỗ trợ trực tiếp môi trường ảo. Nếu đang sử dụng một trong các phiên bản cũ này, bạn cần tải về và cài đặt một ứng dụng tên là virtualenv để tạo ra môi trường ảo. Sau khi cài đặt ứng dụng này, bạn có thể khởi tạo môi trường ảo với lệnh sau:

Sau khi khởi tạo môi trường ảo theo một trong hai cách trên, bạn sẽ có một môi trường ảo trong thư mục myenv. Đến đây, bạn cần phải yêu cầu hệ thống là bạn muốn dùng môi trường ảo này, và để làm điều này, bạn phải kích hoạt (activate) nó với lệnh sau:

Nếu bạn sử dụng Windows, lệnh kích hoạt môi trường ảo sẽ hơi khác một chút:

Khi bạn kích hoạt một môi trường ảo, cấu hình của cửa sổ lệnh (terminal) của bạn sẽ được thay đổi sao cho khi bạn dùng lệnh python thì trình thông dịch Python trong môi trường ảo của bạn sẽ chạy thay vì trình thông dịch Python mặc định của hệ thống. Thêm nữa là dấu nhắc của cửa sổ lệnh cũng được thay đổi để bao gồm luôn cả tên của môi trường ảo hiện hành (trong trường hợp này là myenv).

Sau khi đã kích hoạt môi trường ảo, bạn có thể cài đặt Flask trong môi trương ảo này:

Nếu muốn xác nhận rằng Flask đã được cài đặt thành công trong môi trường ảo, bạn có thể chạy trình thông dịch Python và import Flask:

Sau khi thi hành lệnh trên, nếu hệ thống không thông báo lỗi, bạn có thể chắc chắn rằng Flask đã được cài đặt thành công.

Ứng dụng “Hello, World” với Flask

Chương trình đầu tiên trong ngôn ngữ lập trình nào cũng bắt đầu với “Hello, World!”, Flask cũng không ngoại lệ. Nếu bạn vào trang chủ của Flask, bạn sẽ thấy một ứng dụng rất đơn giản chỉ với năm dòng lệnh. Thay vì lặp lại ứng dụng đó, chúng ta sẽ đi qua một ví dụ khác có thể giúp chúng ta hiểu các cấu trúc căn bản của Flask và áp dụng với các ứng dụng khác phức tạp hơn.

Một ứng dụng sẽ được phân vào gói tương ứng. Trong Python, một thư mục con có chứa file __init__.py sẽ được xem như là một gói và có thể được import vào các chương trình khác. Khi bạn import một gói, file __init__.py sẽ được thực thi và định nghĩa các chức năng mà một gói cho phép các ứng dụng khác có thể sử dụng.

Chúng ta hãy tạo một gói gọi là app cho ứng dụng của chúng ta. Đầu tiên, cần chắc chắn rằng chúng ta đang ở trong thư mục myblog và sau đó, nhập lệnh dưới đây:

File __init__.py trong thư mục app sẽ có mã như sau:

app/__init__.py:

Đoạn mã trên sẽ khởi tạo một thực thể của lớp Flask – được tham chiếu từ gói flask – đại diện cho ứng dụng. Biến __name__ được truyền vào lớp Flask là một biến được định nghĩa sẵn và được gán giá trị theo tên của module đang sử dụng nó. Flask dùng module được gán ở đây làm điểm bắt đầu để load các tài nguyên kèm theo như các file khuôn mẫu (template) – sẽ được giới thiệu chi tiết hơn trong Phần 2. Để cho dễ hiểu, bạn chỉ cần biết rằng truyền __name__ vào thực thể Flask hầu như sẽ là cách để cho Flask chạy đúng. Tiếp theo, mã ứng dụng khai báo tham chiếu đến module routes – hiện vẫn chưa tồn tại.

Có một điều có thể gây khó hiểu ở đây là có hai thực thể tên là app. Thứ nhất là gói thư viện app được định nghĩa bởi thư mục app và chương trình __init__.py, và được tham chiếu trong câu lệnh from app import routes. Thứ hai là biến app được định nghĩa là một thực thể của lớp Flask trong chương trình __init__.py – và vì vậy, nó là một thành phần của gói thư viện app.

Một điểm đáng lưu ý nữa là module routes được tham chiếu ở cuối chương trình chứ không phải ở đầu chương trình như hầu hết các lệnh tham chiếu khác. Đây là một giải pháp để tránh tình trạng tham chiếu vòng (circular imports), một vấn đề thường gặp ở các ứng dụng Flask. Bạn sẽ thấy rằng module routes cần tham chiếu đến biến app trong chương trình, vì vậy việc đặt tham chiếu đến routes ở cuối chương trình sẽ tránh được lỗi phát sinh do có sự tham chiếu lẫn nhau.

Vậy module routes có gì? Module routes (định tuyến) cho phép định nghĩa hành vi của ứng dụng khi user gởi yêu cầu đến các địa chỉ (URL) nhất định (route). Trong Flask, các chương trình xử lý (handler) URL sẽ được viết dưới dạng các hàm của Python gọi là hàm hiển thị (view functions). Các hàm hiển thị sẽ được ánh xạ vào một hay nhiều URL, nhờ đó Flask biết được phải xử lý như thế nào khi có một yêu cầu đến một URL nhất định.

Sau đây là hàm hiển thị đầu tiên được viết trong một module tên là routes.py trong thư mục app:

app/routes.py: Định tuyến cho trang chủ

Hàm hiển thị này khá đơn giản, nó chỉ trả về một chuỗi. Hai dòng lệnh có vẻ hơi lạ là @app.route trong đoạn mã ở trên gọi là mẫu thiết kế (decorator) – một chức năng khá độc đáo của Python. Một mẫu thiết kế sẽ điều chỉnh hàm theo sau nó. Cacs mẫu thiết kế thường được dùng để đăng ký các hàm sẽ được gọi (callback function) cho các sự kiện (event) nhất định. Trong trường hợp này, mẫu thiết kế @app.route sẽ tạo một liên kết giữa URL được gọi và hàm tương ứng để xử lý nó. Trong ví dụ này có hai mẫu thiết kế để tạo liên kết giữa URL //index đến hàm này. Điều này có nghĩa là khi người sử dụng nhập một trong hai URL này vào trình duyệt Web, Flask sẽ gọi hàm index và truyền kết quả trả về từ hàm này (chuỗi “Hello, World!”) về trình duyệt. Nếu bạn cảm thấy không hiểu điều này, hãy kiên nhẫn một chút nữa, bạn sẽ thấy rõ hơn khi chạy chương trình.

Cuối cùng, để hoàn tất chương trình, bạn cần có một chương trình Python ở thư mục gốc để định nghĩa thực thể Flask. Chúng ta hãy đặt tên cho chương trình này là myblog.py. Trong đó, chúng ta sẽ viết một câu lệnh để tham chiếu đến thực thể ứng dụng:

myblog.py: module chính của ứng dụng

Bạn có nhớ đến hai thực thể app mà chúng ta đã nói ở trên không? Ở đây bạn có thể thẩy rằng có cả hai trong câu lệnh. Thực thể ứng dụng Flask gọi là app và là một thành viên của gói app. Câu lệnh from app import app tham chiếu đến biến app là một thành viên của gói app. Nếu bạn cảm thấy không rõ ràng, bạn có thể đặt tên khác cho gói app hay là biến app theo ý của bạn.

Để chắc chắn rằng bạn làm chính xác theo các hướng dẫn ở trên, bạn có thể kiểm tra cấu trúc các tập tin và thư mục trong dự án theo sơ đồ dưới đây:

Đến đây thì phiên bản đầu tiên của ứng dụng Flask của chúng ta đã hoàn tất, dễ quá phải không? Nhưng trước khi chạy nó, bạn cần phải cho Flask biết làm cách nào để tham chiếu đến ứng dụng bằng cách khai báo biến môi trường FLASK_APP như sau:

Nếu bạn đang sử dụng hệ điều hành Windows, hãy dùng lệnh set thay cho export trong câu lệnh trên.

Nếu đã sẵn sàng, bạn hãy chạy ứng dụng Web đầu tiên với Flash bằng câu lệnh sau:

Sau câu lệnh này, Flask sẽ khởi tạo một chương trình máy chủ Web (Web Server) đơn giản và đi vào chế độ chờ đợi kết nối từ máy khách. Như bạn đã thấy ở phần thông báo của Flask ở trên, máy chủ Web đang đợi kết nối tại địa chỉ IP 127.0.0.1 – cũng chính là địa chỉ IP nội bộ đại diện cho máy của bạn. Địa chỉ này phổ biến đến nỗi nó có một bí danh mà bạn có thể đã thấy qua: localhost. Tuy vậy, để truy cập đến ứng dụng Web, ngoài địa chỉ IP, chúng ta còn cần đến sổ cổng (port number). Có một số quy ước chung cho việc sử dụng cổng của các ứng dụng phổ biến. Các ứng dụng Web trên các máy chủ chính thức thường được truy cập qua cổng 443, hay là 80 nếu không có mã hóa. Nhưng ở đây, bởi vì chúng ta đang ở trong chế độ viết mã thử nghiệm, Flask sẽ dùng cổng 5000. Do đó, để truy cập đến ứng dụng của chúng ta, hãy mở trình duyệt nào bạn thích (Chrome, Firefox, Edge…) và nhập URL này vào thanh địa chỉ:

Bạn cũng có thể nhập một địa chỉ khác với kết quả tương đương:

Đến đây thì bạn có thể thấy kết quả của bộ định tuyến mà chúng ta đã khai báo bằng mẫu thiết kế @app.route ở trên. URL đầu tiên được ánh xạ vào /, còn URL thứ hai được ánh xạ vào /index. Nhưng cả hai URL đều liên kết với một hàm hiển thị duy nhất, và do đó trả về cùng kết quả là chuỗi “Hello, World!”. Nếu bạn nhập vào một URL bất kỳ ngoài hai URL này, ứng dụng sẽ thông báo lỗi bởi vì nó chỉ nhận dạng được hai URL này mà thôi.

Đây là kết quả sau khi bạn nhập một trong hai URL vào trình duyệt:

Để chấm dứt chương trình, bạn có thể dùng tổ hợp phím Ctrl-C.

Xin chúc mừng, bạn đã hoàn thành một bước lớn đầu tiên để trở thành một lập trình viên cho ứng dụng Web.

Trước khi chúng ta chấm dứt ở đây, còn có một lưu ý nhỏ. Bởi vì các biến môi trường sẽ không được lưu lại giữa các phiên làm việc, bạn có thể sẽ cảm thấy khó chịu khi phải thường xuyên lặp lại việc khai báo biến môi trường FLASK_APP mỗi khi bạn mở một cửa sổ lệnh mới. Từ phiên bản 1.0, Flask cho phép chúng ta đăng ký các biến môi trường cần được từ động tham chiếu khi chúng ta chạy lệnh flask. Để dùng chức năng này, bạn phải cài đặt gói python-dotenv:

Sau đó bạn chỉ cần ghi lại tên biến môi trường và giá trị của nó vào file .flaskenv ở thư mục ngoài cùng của dự án

.flaskenv: Lưu trữ các biến môi trường cho lệnh flask

Lưu ý rằng đây chỉ là tùy chọn. Nếu bạn muốn tự khai báo cũng được, chỉ cần nhớ rằng cần khai báo biến môi trường trước khi bạn chạy lệnh flask.

Chúng ta sẽ kết thúc ở đây, hẹn gặp lại bạn trong phần tiếp theo.

2 thoughts on “Hướng dẫn lập trình Flask – Phần 1: Hello World!

  1. chào ad, em đã đọc bài viết, và thấy thú vị nhưng em chỉ mới bắt đầu học. Bắt đầu với Flask có ổn không ạ?

    1. Để dùng Flask, bạn cần biết một số khái niệm cơ bản về lập trình với Python và mô hình lập trình MVC (Model-View-Controller). Bạn chỉ cần biết ở mức cơ bản chứ không cần nâng cao. Nếu bạn đã có các kiến thức này thì không có vấn đề gì cả. Mục đích của loạt bài này là tìm hiểu về Flask và các khái niệm liên quan đển lập trình Web từ cơ bản đến nâng cao.

      Rất vui được gặp bạn.

Leave a Reply

Your email address will not be published. Required fields are marked *