Hướng dẫn sử dụng Cherrypy cơ bản cho ứng dụng web Python

Để xây dựng một ứng dụng web Python, bạn có thể sử dụng Cherrypy vì nó tích hợp sẵn máy chủ web, không cần cài đặt thêm phần mềm như Tomcat (Java). Dưới đây là các thao tác cơ bản để bắt đầu.

1. Thiết lập tối giản

Mục tiêu: Tạo một trang HTML có nút, khi nhấn sẽ gọi hàm Python và hiển thị kết quả.

File HTML (demo_cherry.html):

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Cherry Demo</title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
    <h1>Cherry Demo</h1>
    <p id="output"></p>
    <button type="button" onclick="fetchGreeting()">Chào</button>
    <script>
        function fetchGreeting() {
            $.get('/greet', function(data, status) {
                alert('Dữ liệu: ' + data);
                alert('Trạng thái: ' + status);
            });
        }
    </script>
</body>
</html>

File Python (app.py):

# -*- coding: utf-8 -*-
import cherrypy

class MyApp:
    @cherrypy.expose()
    def greet(self):
        return 'Xin chào từ Cherrypy!'

    @cherrypy.expose()
    def index(self):
        return open('demo_cherry.html', encoding='utf-8')

cherrypy.quickstart(MyApp(), '/')

Chạy file app.py, bạn sẽ thấy thông báo:

[27/May/2020:09:04:42] ENGINE Serving on http://127.0.0.1:8080

Mở trình duyệt với http://127.0.0.1:8080/ hoặc http://127.0.0.1:8080/index. Nhấn nút "Chào" sẽ gửi yêu cầu GET đến /greet và nhận về chuỗi "Xin chào từ Cherrypy!".

Lưu ý: Nếu gặp lỗi Port 8080 not free, hãy kết thúc tiến trình Python cũ trong Task Manager để giải phóng cổng.

2. Tự động mở trình duyệt

Thêm webbrowser để tự động mở trang khi khởi động:

# -*- coding: utf-8 -*-
import cherrypy
import webbrowser

class MyApp:
    @cherrypy.expose()
    def greet(self):
        return 'Xin chào!'

    @cherrypy.expose()
    def index(self):
        return open('demo_cherry.html', encoding='utf-8')

def open_browser():
    webbrowser.open('http://127.0.0.1:8080/')

cherrypy.engine.subscribe('start', open_browser)
cherrypy.quickstart(MyApp(), '/')

Khi chạy, trình duyệt sẽ tự động mở. Nếu HTML không cập nhật, hãy xóa cache trình duyệt.

3. Truyền tham số qua POST

Thêm hàm nhận tham số và xử lý dữ liệu gửi từ form.

File Python cập nhật:

# -*- coding: utf-8 -*-
import cherrypy
import webbrowser

class MyApp:
    @cherrypy.expose()
    def greet(self):
        return 'Xin chào!'

    @cherrypy.expose()
    def index(self):
        return open('demo_cherry.html', encoding='utf-8')

    @cherrypy.expose()
    def process_data(self, name, age, **kwargs):
        print('Tên:', name)
        print('Tuổi:', age)
        print('Khác:', kwargs)
        return 'Đã nhận dữ liệu thành công'

def open_browser():
    webbrowser.open('http://127.0.0.1:8080/')

cherrypy.engine.subscribe('start', open_browser)
cherrypy.quickstart(MyApp(), '/')

File HTML thêm nút mới và xử lý jQuery:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Cherry Demo</title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
    <h1>Cherry Demo</h1>
    <p id="output"></p>
    <button type="button" onclick="fetchGreeting()">Chào</button>
    <button type="button" id="sendData">Gửi dữ liệu</button>
    <p id="result"></p>
    <script>
        function fetchGreeting() {
            $.get('/greet', function(data, status) {
                alert('Dữ liệu: ' + data);
                alert('Trạng thái: ' + status);
            });
        }

        $(document).ready(function() {
            $('#sendData').click(function() {
                $.post('/process_data',
                    {
                        name: 'Nguyễn Văn A',
                        age: 25,
                        extra: 'test'
                    },
                    function(data, status) {
                        if (status === 'success') {
                            $('#result').text(data);
                        }
                    }
                );
            });
        });
    </script>
</body>
</html>

Kết quả: nhấn nút "Gửi dữ liệu" sẽ gửi POST đến /process_data với các tham số name, age, extra. Python in ra thông tin và trả về "Đã nhận dữ liệu thành công".

4. Cấu hình chi tiết và phục vụ tài nguyên tĩnh

Ví dụ cấu hình cổng, host, thư mục static và trả về JSON.

# -*- coding: utf-8 -*-
import json
import os
import webbrowser
import cherrypy

class WebService:
    def __init__(self, port):
        self.media_folder = os.path.abspath(os.path.join(os.getcwd(), 'static'))
        self.host = '0.0.0.0'
        self.port = int(port)
        self.index_file = 'index.html'

    @cherrypy.expose()
    def index(self):
        return open(os.path.join(self.media_folder, self.index_file), 'rb')

    @cherrypy.expose()
    def api(self, sn):
        cherrypy.response.headers['Content-Type'] = 'application/json'
        cherrypy.response.headers['Access-Control-Allow-Origin'] = '*'
        data = {'id': sn, 'status': 'ok'}
        return json.dumps(data).encode('utf-8')

def main():
    service = WebService(8090)
    conf = {
        'global': {
            'server.socket_host': service.host,
            'server.socket_port': service.port,
            'engine.autoreload.on': False
        },
        '/': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': service.media_folder
        },
        '/static': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': service.media_folder
        }
    }

    def auto_open():
        webbrowser.open('http://127.0.0.1:{}/'.format(service.port))

    cherrypy.engine.subscribe('start', auto_open)
    cherrypy.quickstart(service, '/', conf)

if __name__ == '__main__':
    main()

Với cấu hình trên, bạn có thể truy cập http://127.0.0.1:8090/ để xem index.html, http://127.0.0.1:8090/static/js/jquery.js để lấy file tĩnh, và http://127.0.0.1:8090/api?sn=ABC để nhận JSON.

Thẻ: Cherrypy Python Web Framework Web Development python HTTP Server

Đăng vào ngày 10 tháng 8 lúc 05:23