简单介绍Python的轻便web框架Bottle


Posted in Python onApril 08, 2015

基本映射

映射使用在根据不同URLs请求来产生相对应的返回内容.Bottle使用route() 修饰器来实现映射.

from bottle import route, run@route('/hello')def hello():
  return "Hello World!"run() # This starts the HTTP server

运行这个程序,访问http://localhost:8080/hello将会在浏览器里看到 "Hello World!".
GET, POST, HEAD, ...

这个映射装饰器有可选的关键字method默认是method='GET'. 还有可能是POST,PUT,DELETE,HEAD或者监听其他的HTTP请求方法.

from bottle import route, request@route('/form/submit', method='POST')def form_submit():
  form_data = request.POST
  do_something(form_data)
  return "Done"

动态映射

你可以提取URL的部分来建立动态变量名的映射.
 

@route('/hello/:name')def hello(name):
  return "Hello %s!" % name

默认情况下, 一个:placeholder会一直匹配到下一个斜线.需要修改的话,可以把正则字符加入到#s之间:

@route('/get_object/:id#[0-9]+#')def get(id):
  return "Object ID: %d" % int(id)

或者使用完整的正则匹配组来实现:

@route('/get_object/(?P<id>[0-9]+)')def get(id):
  return "Object ID: %d" % int(id)

正如你看到的,URL参数仍然是字符串, 即使你正则里面是数字.你必须显式的进行类型强制转换.
@validate() 装饰器

Bottle 提供一个方便的装饰器validate() 来校验多个参数.它可以通过关键字和过滤器来对每一个URL参数进行处理然后返回请求.

from bottle import route, validate# /test/validate/1/2.3/4,5,6,7@route('/test/validate/:i/:f/:csv')@validate(i=int, f=float, csv=lambda x: map(int, x.split(',')))def validate_test(i, f, csv):
  return "Int: %d, Float:%f, List:%s" % (i, f, repr(csv))

你可能需要在校验参数失败时抛出ValueError.
返回文件流和JSON

WSGI规范不能处理文件对象或字符串.Bottle自动转换字符串类型为iter对象.下面的例子可以在Bottle下运行, 但是不能运行在纯WSGI环境下.

@route('/get_string')def get_string():
  return "This is not a list of strings, but a single string"@route('/file')def get_file():
  return open('some/file.txt','r')

字典类型也是允许的.会转换成json格式,自动返回Content-Type: application/json.

@route('/api/status')def api_status():
  return {'status':'online', 'servertime':time.time()}

你可以关闭这个特性:bottle.default_app().autojson = False
Cookies

Bottle是把cookie存储在request.COOKIES变量中.新建cookie的方法是response.set_cookie(name, value[, **params]). 它可以接受额外的参数,属于SimpleCookie的有有效参数.

from bottle import responseresponse.set_cookie('key','value', path='/', domain='example.com', secure=True, expires=+500, ...)

设置max-age属性(它不是个有效的Python参数名) 你可以在实例中修改 cookie.SimpleCookie inresponse.COOKIES.
 

from bottle import responseresponse.COOKIES['key'] = 'value'response.COOKIES['key']['max-age'] = 500

模板

Bottle使用自带的小巧的模板.你可以使用调用template(template_name, **template_arguments)并返回结果.
 

@route('/hello/:name')def hello(name):
  return template('hello_template', username=name)

这样就会加载hello_template.tpl,并提取URL:name到变量username,返回请求.

hello_template.tpl大致这样:

<h1>Hello {{username}}</h1><p>How are you?</p>

模板搜索路径

模板是根据bottle.TEMPLATE_PATH列表变量去搜索.默认路径包含['./%s.tpl', './views/%s.tpl'].
模板缓存

模板在编译后在内存中缓存.修改模板不会更新缓存,直到你清除缓存.调用bottle.TEMPLATES.clear().
模板语法

模板语法是围绕Python很薄的一层.主要目的就是确保正确的缩进块.下面是一些模板语法的列子:

  •     %...Python代码开始.不必处理缩进问题.Bottle会为你做这些.
  •     %end关闭一些语句%if ...,%for ...或者其他.关闭块是必须的.
  •     {{...}}打印出Python语句的结果.
  •     %include template_name optional_arguments包括其他模板.
  •     每一行返回为文本.

Example:

%header = 'Test Template'
%items = [1,2,3,'fly']
%include http_header title=header, use_js=['jquery.js', 'default.js']<h1>{{header.title()}}</h1><ul>%for item in items: <li>
  %if isinstance(item, int):
   Zahl: {{item}}
  %else:
   %try:
    Other type: ({{type(item).__name__}}) {{repr(item)}}
   %except:
    Error: Item has no string representation.
   %end try-block (yes, you may add comments here)
  %end  </li>
 %end</ul>%include http_footer

Key/Value数据库

Bottle(>0.4.6)通过bottle.db模块变量提供一个key/value数据库.你可以使用key或者属性来来存取一个数据库对象.调用 bottle.db.bucket_name.key_name和bottle.db[bucket_name][key_name].

只要确保使用正确的名字就可以使用,而不管他们是否已经存在.

存储的对象类似dict字典, keys和values必须是字符串.不支持 items() and values()这些方法.找不到将会抛出KeyError.
持久化

对于请求,所有变化都是缓存在本地内存池中. 在请求结束时,自动保存已修改部分,以便下一次请求返回更新的值.数据存储在bottle.DB_PATH文件里.要确保文件能访问此文件.
Race conditions

一般来说不需要考虑锁问题,但是在多线程或者交叉环境里仍是个问题.你可以调用 bottle.db.save()或者botle.db.bucket_name.save()去刷新缓存,但是没有办法检测到其他环境对数据库的操作,直到调用bottle.db.save()或者离开当前请求.
Example
 

from bottle import route, db@route('/db/counter')def db_counter():
  if 'hits' not in db.counter:
    db.counter.hits = 0
  db['counter']['hits'] += 1
  return "Total hits: %d!" % db.counter.hits

使用WSGI和中间件

bottle.default_app()返回一个WSGI应用.如果喜欢WSGI中间件模块的话,你只需要声明bottle.run()去包装应用,而不是使用默认的.
 

from bottle import default_app, runapp = default_app()newapp = YourMiddleware(app)run(app=newapp)

默认default_app()工作

Bottle创建一个bottle.Bottle()对象和装饰器,调用bottle.run()运行. bottle.default_app()是默认.当然你可以创建自己的bottle.Bottle()实例.

from bottle import Bottle, runmybottle = Bottle()@mybottle.route('/')def index():
 return 'default_app'run(app=mybottle)

发布

Bottle默认使用wsgiref.SimpleServer发布.这个默认单线程服务器是用来早期开发和测试,但是后期可能会成为性能瓶颈.

有三种方法可以去修改:

  1.     使用多线程的适配器
  2.     负载多个Bottle实例应用
  3.     或者两者

多线程服务器

最简单的方法是安装一个多线程和WSGI规范的HTTP服务器比如Paste, flup, cherrypy or fapws3并使用相应的适配器.
 
from bottle import PasteServer, FlupServer, FapwsServer, CherryPyServerbottle.run(server=PasteServer) # Example

如果缺少你喜欢的服务器和适配器,你可以手动修改HTTP服务器并设置bottle.default_app()来访问你的WSGI应用.

def run_custom_paste_server(self, host, port):
  myapp = bottle.default_app()
  from paste import httpserver
  httpserver.serve(myapp, host=host, port=port)

多服务器进程

一个Python程序只能使用一次一个CPU,即使有更多的CPU.关键是要利用CPU资源来负载平衡多个独立的Python程序.

单实例Bottle应用,你可以通过不同的端口来启动(localhost:8080, 8081, 8082, ...).高性能负载作为反向代理和远期每一个随机瓶进程的新要求,平衡器的行为,传播所有可用的支持与服务器实例的负载.这样,您就可以使用所有的CPU核心,甚至分散在不同的物理服

Python 相关文章推荐
深入解析Python的Tornado框架中内置的模板引擎
Jul 11 Python
视觉直观感受若干常用排序算法
Apr 13 Python
PyChar学习教程之自定义文件与代码模板详解
Jul 17 Python
100行python代码实现跳一跳辅助程序
Jan 15 Python
Python基于opencv调用摄像头获取个人图片的实现方法
Feb 21 Python
Python参数解析模块sys、getopt、argparse使用与对比分析
Apr 02 Python
python opencv 二值化 计算白色像素点的实例
Jul 03 Python
Python-Tkinter Text输入内容在界面显示的实例
Jul 12 Python
在Python中使用MongoEngine操作数据库教程实例
Dec 03 Python
Python3.7 基于 pycryptodome 的AES加密解密、RSA加密解密、加签验签
Dec 04 Python
在 Windows 下搭建高效的 django 开发环境的详细教程
Jul 27 Python
Python自动发送和收取邮件的方法
Aug 12 Python
常见的在Python中实现单例模式的三种方法
Apr 08 #Python
分析Python的Django框架的运行方式及处理流程
Apr 08 #Python
给Python的Django框架下搭建的BLOG添加RSS功能的教程
Apr 08 #Python
在Python中使用NLTK库实现对词干的提取的教程
Apr 08 #Python
使用Python操作Elasticsearch数据索引的教程
Apr 08 #Python
用Python实现协同过滤的教程
Apr 08 #Python
在Python中调用ggplot的三种方法
Apr 08 #Python
You might like
收音机鉴频器对声音的影响和频偏分析
2021/03/02 无线电
给初学PHP的5个入手程序
2006/11/23 PHP
PHP远程调试之XDEBUG
2015/12/29 PHP
php的api数据接口书写实例(推荐)
2016/09/22 PHP
PHP利用超级全局变量$_POST来接收表单数据的实例
2016/11/05 PHP
thinkphp5框架调用其它控制器方法 实现自定义跳转界面功能示例
2019/07/03 PHP
javascript xml为数据源的下拉框控件
2009/07/07 Javascript
JQuery将文本转化成JSON对象需要注意的问题
2011/05/09 Javascript
一种新的javascript对象创建方式Object.create()
2015/12/28 Javascript
jQuery插件FusionCharts绘制2D柱状图和折线图的组合图效果示例【附demo源码】
2017/04/10 jQuery
vue封装第三方插件并发布到npm的方法
2017/09/25 Javascript
Layui组件Table绑定行点击事件和获取行数据的方法
2018/08/19 Javascript
vue组件tabbar使用方法详解
2018/11/06 Javascript
JS实现的点击按钮图片上下滚动效果示例
2019/01/28 Javascript
vue2 v-model/v-text 中使用过滤器的方法示例
2019/05/09 Javascript
SpringBoot+Vue开发之Login校验规则、实现登录和重置事件
2020/10/19 Javascript
python网络编程学习笔记(八):XML生成与解析(DOM、ElementTree)
2014/06/09 Python
python通过exifread模块获得图片exif信息的方法
2015/03/16 Python
介绍Python的Django框架中的静态资源管理器django-pipeline
2015/04/25 Python
python如何使用正则表达式的前向、后向搜索及前向搜索否定模式详解
2017/11/08 Python
python编程通过蒙特卡洛法计算定积分详解
2017/12/13 Python
pycharm双击无响应(打不开问题解决办法)
2020/01/10 Python
详解Python中的分支和循环结构
2020/02/11 Python
Python paramiko 模块浅谈与SSH主要功能模拟解析
2020/02/29 Python
python 调用Google翻译接口的方法
2020/12/09 Python
Python使用tkinter实现小时钟效果
2021/02/22 Python
Myprotein荷兰官网:欧洲第一运动营养品牌
2020/07/11 全球购物
会计专业大学生职业生涯规划书
2014/02/11 职场文书
初中毕业生的自我评价
2014/03/03 职场文书
学习三严三实对照检查材料思想汇报
2014/09/22 职场文书
党员剖析材料范文
2014/09/30 职场文书
2014年为民办实事工作总结
2014/12/20 职场文书
本科毕业论文指导教师评语
2014/12/30 职场文书
学习焦裕禄观后感
2015/06/09 职场文书
铁人观后感
2015/06/16 职场文书
医务人员医德医风心得体会
2016/01/25 职场文书