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
的默认请求。 我们将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。 通配符由括在尖括号中的名称组成(例如<名称>),并且可以接受一个或多个字符,直到下一个斜杠为止。
过滤器可用于定义更特定的通配符。
- :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 教程。