Python Bottle 教程

Python Bottle 教程展示了如何使用 Python Bottle micro Web 框架在 Python 中创建简单的 Web 应用。

Bottle

Bottle 是用于 Python 的快速,简单且轻量级的 WSGI 微型网络框架。 它作为单个文件模块分发,除 Python 标准库外,没有其他依赖项。

Web 服务器网关接口(WSGI)是 Web 服务器的简单调用约定,用于将请求转发到以 Python 编程语言编写的 Web 应用或框架。

Bottle 安装

$ sudo pip3 install bottle

我们使用pip3工具安装 Bottle。

Bottle简单的例子

在下面的示例中,我们创建一个简单的 Bottle 应用。

$ mkdir simple && cd simple
$ touch simple.py

我们创建一个项目目录一个 Python 文件。

simple.py

#!/usr/bin/env python3

from bottle import route, run

@route('/message')
def hello():
    return "Today is a beautiful day"  

run(host='localhost', port=8080, debug=True)

该示例向客户端发送一条消息。

from bottle import route, run

我们导入route装饰器和run函数。 route装饰器用于将功能绑定到请求 URL。 run功能启动服务器实例。 默认情况下,它是开发服务器。

@route('/message')
def hello():
    return "Today is a beautiful day"  

使用@route()装饰器,我们定义了一条路线。 路由是 URL 与 Web 服务器功能之间的映射。 在我们的例子中,该功能返回一条简单的文本消息。

run(host='localhost', port=8080, debug=True)

我们以调试模式在端口 8080 上启动服务器。

$ ./simple.py 
Bottle v0.12.13 server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.

我们启动开发服务器。

$ curl localhost:8080/message
Today is a beautiful day

我们使用curl工具创建一个请求。 服务器以一条简单消息响应。

Bottle JSON 响应

Web 应用通常以 JSON 格式发送响应。 Bottle 自动将 Python 词典转换为 JSON。

json_response.py

#!/usr/bin/env python3

from bottle import route, run

@route('/cars')
def getcars():

    cars = [ {'name': 'Audi', 'price': 52642},
        {'name': 'Mercedes', 'price': 57127},
        {'name': 'Skoda', 'price': 9000},
        {'name': 'Volvo', 'price': 29000},
        {'name': 'Bentley', 'price': 350000},
        {'name': 'Citroen', 'price': 21000},
        {'name': 'Hummer', 'price': 41400},
        {'name': 'Volkswagen', 'price': 21600} ]

    return dict(data=cars)

run(host='localhost', port=8080, debug=True)

该应用将有关汽车的数据作为 JSON 发送到客户端。

return dict(data=cars)

Bottle 将 Python 字典转换为 JSON。

$ curl localhost:8080/cars
{"data": [{"name": "Audi", "price": 52642}, {"name": "Mercedes", "price": 57127}, 
{"name": "Skoda", "price": 9000}, {"name": "Volvo", "price": 29000}, 
{"name": "Bentley", "price": 350000}, {"name": "Citroen", "price": 21000}, 
{"name": "Hummer", "price": 41400}, {"name": "Volkswagen", "price": 21600}]}

我们收到一个命名的 JSON 数组。

Bottle 获取请求

HTTP GET 方法请求指定资源的表示形式。 在 Bottle 中,我们可以使用@route@get装饰器映射 GET 请求。 从request.query检索数据。

GET 请求通常是默认的请求方法。

get_request.py

#!/usr/bin/env python3

from bottle import route, run, request, get

@get('/msg')
def message():

    name = request.query.name
    age = request.query.age

    return "{0} is {1} years old".format(name, age)

run(host='localhost', port=8080, debug=True)

该应用根据 GET 请求的数据构建一条消息。

@get('/msg')
def message():

message()函数通过/msg路径映射到 GET 请求。 @get('msg')装饰器等效于@route('msg', method='GET'),或更短的@route('msg')

name = request.query.name
age = request.query.age

我们从查询字符串中检索数据。

$ curl "localhost:8080/greet?name=Peter&age=34"
Peter is 34 years old

我们使用curl工具发出 GET 请求。 GET 请求是curl的默认请求。 我们将nameage参数添加到查询字符串。

Bottle 静态文件

使用static_file(),我们可以在 Bottle 中提供静态文件。

$ mkdir botstat && cd botstat
$ mkdir public 
$ touch public/home.html app.py

我们为应用创建目录和文件。

public/home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home page</title>
</head>
<body>
    <p>This is home page</p>
</body>
</html>

这是位于public目录中的主页。 静态资源的目录通常称为publicstatic

app.py

#!/usr/bin/env python3

from bottle import route, run, static_file

@route('/<filepath:path>')
def server_static(filepath):
    return static_file(filepath, root='./public/')

run(host='localhost', port=8080, debug=True)

在此示例中,我们提供静态文件。 为了获得主页,我们必须导航到localhost:8080/home.html

@route('/<filepath:path>')

filepath:path是仅允许出现在包含斜杠的路径中的字符的过滤器。

return static_file(filepath, root='./public/')

通过static_file()功能,我们可以提供静态文件。 静态文件所在的目录在root参数中指定。

Bottle 过滤器

包含通配符的路由称为动态路由(与静态路由相对)。 它们可以同时匹配多个 URL。 通配符由括在尖括号中的名称组成(例如<名称>),并且可以接受一个或多个字符,直到下一个斜杠为止。

过滤器可用于定义更特定的通配符。

  • :int 匹配(带符号)数字
  • :float 匹配十进制数字
  • :path 路径段中允许使用的数学字符
  • :re 允许指定自定义正则表达式

filters.py

#!/usr/bin/env python3

from bottle import route, run

@route('/app/<myid:int>/')
def provide(myid):
    return "Object with id {} returned".format(myid)

@route('/app/<name:re:[a-z]+>/')
def provide(name):
    return "Name {} given".format(name)    

run(host='localhost', port=8080, debug=True)

该示例使用整数过滤器和正则表达式过滤器。

$ curl localhost:8080/app/3/
Object with id 3 returned

在这里,我们向路径添加一个整数。

Bottle 例子

在下面的示例中,我们将表单发送到 Bottle 应用。

$ mkdir simple_form && cd simple_form
$ mkdir public 
$ touch public/index.html simple_form.py

我们为应用创建目录和文件。

public/index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home page</title>
</head>

<body>

    <form method="post" action="doform">
        <div>
            <label for="name">Name:</label>
            <input type="text" id="name" name="name">
        </div>
        <div>
            <label for="occupation">Occupation:</label>
            <input type="text" id="occupation" name="occupation">
        </div>
        <button type="submit">Submit</button>
    </form>

</body>

</html>

在 HTML 文件中,我们有一个表单标签。 该表格包含两个输入字段:名称和职业。

simple_form.py

#!/usr/bin/env python3

from bottle import route, run, post, request, static_file

@route('/')
def server_static(filepath="index.html"):
    return static_file(filepath, root='./public/')

@post('/doform')
def process():

    name = request.forms.get('name')
    occupation = request.forms.get('occupation')
    return "Your name is {0} and you are a(n) {1}".format(name, occupation)

run(host='localhost', reloader=True, port=8080, debug=True)

simple_form.py文件中,我们提供一个表格并处理该表格。

@route('/')
def server_static(filepath="index.html"):
    return static_file(filepath, root='./public/')

对于根路径(/),我们从public目录提供index.html

@post('/doform')
def process():

    name = request.forms.get('name')
    occupation = request.forms.get('occupation')
    return "Your name is {0} and you are a(n) {1}".format(name, occupation)

在这里,我们处理表格。 我们使用@post装饰器。 我们从request.forms获取数据并构建消息字符串。

Bottle 错误处理程序

可以使用@error装饰器创建自定义错误页面。

error_handler.py

#!/usr/bin/env python3

from bottle import route, run, error

@route('/app/<myid:int>')
def provide(myid):
    return "Object with id {} returned".format(myid)

@error(404)
def error404(error):
    return '404 - the requested page could not be found'   

run(host='localhost', port=8080, debug=True)

在此示例中,我们在自定义错误处理程序中处理 404 错误。

@error(404)
def error404(error):
    return '404 - the requested page could not be found'   

@error装饰器将错误代码作为参数。

$ curl localhost:8080/app/Peter
404 - the requested page could not be found

我们尝试访问未定义的路由; 我们会收到自定义错误消息。

Bottle MongoDB 示例

在以下示例中,我们从 MongoDB 数据库以 JSON 形式返回数据。

create_cars.py

#!/usr/bin/python3

from pymongo import MongoClient

cars = [ {'name': 'Audi', 'price': 52642},
    {'name': 'Mercedes', 'price': 57127},
    {'name': 'Skoda', 'price': 9000},
    {'name': 'Volvo', 'price': 29000},
    {'name': 'Bentley', 'price': 350000},
    {'name': 'Citroen', 'price': 21000},
    {'name': 'Hummer', 'price': 41400},
    {'name': 'Volkswagen', 'price': 21600} ]

client = MongoClient('mongodb://localhost:27017/')

with client:

    db = client.testdb

    db.cars.insert_many(cars)

使用此脚本,我们创建一个 Mongo 集合。 有关在 Python 中使用 MongoDB 的更多信息,请参考 PyMongo 教程

bottle_mongo.py

#!/usr/bin/env python3

from bottle import route, run, HTTPResponse
from pymongo import MongoClient
import json

client = MongoClient('mongodb://localhost:27017/')

@route('/cars')
def getcars():

    db = client.testdb
    cars = list(db.cars.find({}, {'_id': 0}))

    if cars:

        return json.dumps(cars)
    else: 
        raise HTTPResponse(status=204)

run(host='localhost', port=8080, debug=True)

该示例从 Mongo 集合返回数据作为 JSON。

client = MongoClient('mongodb://localhost:27017/')

创建一个MongoClient实例。

db = client.testdb
cars = list(db.cars.find({}, {'_id': 0}))

我们从两个字段中检索所有数据; 我们排除_id字段。

if cars:

    return json.dumps(cars)
else: 
    raise HTTPResponse(status=204)

如果有数据,我们将使用json.dumps()将其转换为 JSON,然后将其返回给客户端。 否则,我们会发送 204 状态代码。

Bottle 模板示例

模板引擎是一个旨在将模板与数据模型结合以生成结果文档的库。 默认情况下,Bottle 使用简单的模板引擎。

$ mkdir botview && cd botview
$ mkdir views 
$ touch views/show_cars.tpl app.py

我们为应用创建目录和文件。

views/show_cars.tpl

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cars</title>
</head>
<body>

    <table>

        <tr>
            <th>Name</th>
            <th>Price</th>
        </tr>
        % for car in cars:
        <tr>
            <td>{{car['name']}}</td>
            <td>{{car['price']}}</td>
        </tr>
        % end

    </table>

</body>
</html>

在此模板中,我们浏览接收到的cars对象并从中生成一个表。 模板文件位于views目录中。

app.py

#!/usr/bin/env python3

from bottle import route, run, template, HTTPResponse
from pymongo import MongoClient

client = MongoClient('mongodb://localhost:27017/')

@route('/cars')
def getcars():

    db = client.testdb
    data = db.cars.find({}, {'_id': 0})

    if data:

        return template('show_cars', cars=data)
    else: 
        return HTTPResponse(status=204)

run(host='localhost', port=8080, debug=True)

在应用中,我们从 MongoDB 集合中检索数据。 我们使用template()功能将模板文件与数据结合在一起。

在本教程中,我们使用 Bottle 在 Python 中创建简单的 Web 应用。

您可能也对以下相关教程感兴趣: PyMongo 教程Python 教程Python Jinja 教程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程