{% raw %}
Bottle 教程
Bottle 教程展示了如何使用 Python Bottle 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
的默认请求。 我们将name
和age
参数添加到查询字符串。
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
目录中的主页。 静态资源的目录通常称为public
或static
。
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。 通配符由括在尖括号中的名称组成(例如<name>
),并且可以接受一个或多个字符,直到下一个斜杠为止。
过滤器可用于定义更特定的通配符。
: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 教程, Jinja 教程和 Python 教程。
{% endraw %}