Bottle

官网:http://bottlepy.org/docs/dev/index.html

Bottle是一个快速、简洁、轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块。

$ pip install bottle
$ apt-get install python-bottle
$ wget http://bottlepy.org/bottle.py

Bottle框架大致可以分为以下部分:

  • 路由系统,将不同请求交由指定函数处理
  • 模板系统,将模板中的特殊语法渲染成字符串,值得一说的是Bottle的模板引擎可以任意指定:Bottle内置模板、makojinja2cheetah
  • 公共组件,用于提供处理请求相关的信息,如:表单数据、cookies、请求头等
  • 服务,Bottle默认支持多种基于WSGI的服务,如:
server_names = {
'cgi': CGIServer,
'flup': FlupFCGIServer,
'wsgiref': WSGIRefServer,
'waitress': WaitressServer,
'cherrypy': CherryPyServer,
'paste': PasteServer,
'fapws3': FapwsServer,
'tornado': TornadoServer,
'gae': AppEngineServer,
'twisted': TwistedServer,
'diesel': DieselServer,
'meinheld': MeinheldServer,
'gunicorn': GunicornServer,
'eventlet': EventletServer,
'gevent': GeventServer,
'geventSocketIO':GeventSocketIOServer,
'rocket': RocketServer,
'bjoern' : BjoernServer,
'auto': AutoServer,
}

框架的基本使用:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from bottle import template, Bottle
root = Bottle() @root.route('/hello/')
def index():
return "Hello World"
# return template('<b>Hello {{name}}</b>!', name="redhat") root.run(host='localhost', port=8080)

一、路由系统

路由系统是的url对应指定函数,当用户请求某个url时,就由指定函数处理当前请求,对于Bottle的路由系统可以分为一下几类:

  • 静态路由
  • 动态路由
  • 请求方法路由
  • 二级路由

1、静态路由

@root.route('/hello/')
def index():
return template('<b>Hello {{name}}</b>!', name="redhat")

2、动态路由  

@root.route('/wiki/<pagename>')
def callback(pagename):
... @root.route('/object/<id:int>')
def callback(id):
... @root.route('/show/<name:re:[a-z]+>')
def callback(name):
... @root.route('/static/<path:path>')
def callback(path):
return static_file(path, root='static')

3、请求方法路由  

@root.route('/hello/', method='POST')
def index():
... @root.get('/hello/')
def index():
... @root.post('/hello/')
def index():
... @root.put('/hello/')
def index():
... @root.delete('/hello/')
def index():
...

4、二级路由  

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from bottle import template, Bottle app01 = Bottle() @app01.route('/hello/', method='GET')
def index():
return template('<b>App01</b>!')

app01.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from bottle import template, Bottle app02 = Bottle() @app02.route('/hello/', method='GET')
def index():
return template('<b>App02</b>!')

app02.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from bottle import template, Bottle
from bottle import static_file
root = Bottle() @root.route('/hello/')
def index():
return template('<b>Root {{name}}</b>!', name="redhat") from framwork_bottle import app01
from framwork_bottle import app02 root.mount('app01', app01.app01)
root.mount('app02', app02.app02) root.run(host='localhost', port=8080)

二、模板系统

模板系统用于将Html和自定的值两者进行渲染,从而得到字符串,然后将该字符串返回给客户端。我们知道在Bottle中可以使用 内置模板系统、makojinja2cheetah等,以内置模板系统为例:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>{{name}}</h1>
</body>
</html>

hello_template.html

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from bottle import template, Bottle
root = Bottle() @root.route('/hello/')
def index():
# 默认情况下去目录:['./', './views/']中寻找模板文件 hello_template.html
# 配置在 bottle.TEMPLATE_PATH 中
return template('hello_template.tpl', name='redhat') root.run(host='localhost', port=8080)

1、语法

  • 单值
  • 单行Python代码
  • Python代码快
  • Python、Html混合
<h1>1、单值</h1>
{{name}} <h1>2、单行Python代码</h1>
% s1 = "hello" <h1>3、Python代码块</h1>
<%
# A block of python code
name = name.title().strip()
if name == "Alex":
name="seven"
%> <h1>4、Python、Html混合</h1> % if True:
<span>{{name}}</span>
% end
<ul>
% for item in name:
<li>{{item}}</li>
% end
</ul>

2、函数

(1)include(sub_template, **variables)

# 导入其他模板文件

% include('header.html', title='Page Title')
Page Content
% include('footer.html')

(2)rebase(name, **variables)

<html>
<head>
<title>{{title or 'No title'}}</title>
</head>
<body>
{{!base}}
</body>
</html>

base.html

# 导入母版

% rebase('base.html', title='Page Title')
<p>Page Content ...</p>

(3)其他函数

defined(name):检查当前变量是否已经被定义,已定义True,未定义False
get(name, default=None):获取某个变量的值,不存在时可设置默认值
setdefault(name, default):如果变量不存在时,为变量设置默认值

扩展:自定义函数  

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>自定义函数</h1>
{{ myfunc() }} </body>
</html>

hello_tempalte.html

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from bottle import template, Bottle,SimpleTemplate
root = Bottle() def custom():
return '' @root.route('/hello/')
def index():
# 默认情况下去目录:['./', './views/']中寻找模板文件 hello_template.html
# 配置在 bottle.TEMPLATE_PATH 中
return template('hello_template.html', name='alex', myfunc=custom) root.run(host='localhost', port=8080)

man.py

注:变量或函数前添加 【 ! 】,则会关闭转义的功能

三、公共组件

由于Web框架就是用来【接收用户请求】-> 【处理用户请求】-> 【响应相关内容】,对于具体如何处理用户请求,开发人员根据用户请求来进行处理,而对于接收用户请求和相应相关的内容均交给框架本身来处理,其处理完成之后将产出交给开发人员和用户。

【接收用户请求】

当框架接收到用户请求之后,将请求信息封装在Bottle的request中,以供开发人员使用

【响应相关内容】

当开发人员的代码处理完用户请求之后,会将其执行内容相应给用户,相应的内容会封装在Bottle的response中,然后再由框架将内容返回给用户

所以,公共组件本质其实就是为开发人员提供接口,使其能够获取用户信息并配置响应内容。

1、request

Bottle中的request其实是一个LocalReqeust对象,其中封装了用户请求的相关信息:

request.headers
请求头信息 request.query
get请求信息 request.forms
post请求信息 request.files
上传文件信息 request.params
get和post请求信息 request.GET
get请求信息 request.POST
post和上传信息 request.cookies
cookie信息 request.environ
环境相关相关

2、response

Bottle中的request其实是一个LocalResponse对象,其中框架即将返回给用户的相关信息:

response.status_line
状态行 response.status_code
状态码 response.headers
响应头 response.charset
编码 response.set_cookie
在浏览器上设置cookie response.delete_cookie
在浏览器上删除cookie

实例:

from bottle import route, request

@route('/login')
def login():
return '''
<form action="/login" method="post">
Username: <input name="username" type="text" />
Password: <input name="password" type="password" />
<input value="Login" type="submit" />
</form>
''' @route('/login', method='POST')
def do_login():
username = request.forms.get('username')
password = request.forms.get('password')
if check_login(username, password):
return "<p>Your login information was correct.</p>"
else:
return "<p>Login failed.</p>"

基于Form请求

<form action="/upload" method="post" enctype="multipart/form-data">
Category: <input type="text" name="category" />
Select a file: <input type="file" name="upload" />
<input type="submit" value="Start upload" />
</form> @route('/upload', method='POST')
def do_upload():
category = request.forms.get('category')
upload = request.files.get('upload')
name, ext = os.path.splitext(upload.filename)
if ext not in ('.png','.jpg','.jpeg'):
return 'File extension not allowed.' save_path = get_save_path_for_category(category)
upload.save(save_path) # appends upload.filename automatically
return 'OK'

上传文件

四、服务

对于Bottle框架其本身未实现类似于Tornado自己基于socket实现Web服务,所以必须依赖WSGI,默认Bottle已经实现并且支持的WSGI有:

server_names = {
'cgi': CGIServer,
'flup': FlupFCGIServer,
'wsgiref': WSGIRefServer,
'waitress': WaitressServer,
'cherrypy': CherryPyServer,
'paste': PasteServer,
'fapws3': FapwsServer,
'tornado': TornadoServer,
'gae': AppEngineServer,
'twisted': TwistedServer,
'diesel': DieselServer,
'meinheld': MeinheldServer,
'gunicorn': GunicornServer,
'eventlet': EventletServer,
'gevent': GeventServer,
'geventSocketIO':GeventSocketIOServer,
'rocket': RocketServer,
'bjoern' : BjoernServer,
'auto': AutoServer,
}

WSGI

使用时,只需在主app执行run方法时指定参数即可:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from bottle import Bottle
root = Bottle() @root.route('/hello/')
def index():
return "Hello World"
# 默认server ='wsgiref'
root.run(host='localhost', port=8080, server='wsgiref')

默认server="wsgiref",即:使用Python内置模块wsgiref,如果想要使用其他时,则需要首先安装相关类库,然后才能使用。如:  

# 如果使用Tornado的服务,则需要首先安装tornado才能使用

class TornadoServer(ServerAdapter):
""" The super hyped asynchronous server by facebook. Untested. """
def run(self, handler): # pragma: no cover
# 导入Tornado相关模块
import tornado.wsgi, tornado.httpserver, tornado.ioloop
container = tornado.wsgi.WSGIContainer(handler)
server = tornado.httpserver.HTTPServer(container)
server.listen(port=self.port,address=self.host)
tornado.ioloop.IOLoop.instance().start()

bottle.py源码

PS:以上WSGI中提供了19种,如果想要使期支持其他服务,则需要扩展Bottle源码来自定义一个ServerAdapter

更多参见:http://www.bottlepy.org/docs/dev/index.html

  

Python自动化运维之29、Bottle框架的更多相关文章

  1. Python自动化运维:技术与最佳实践 PDF高清完整版|网盘下载内附地址提取码|

    内容简介: <Python自动化运维:技术与最佳实践>一书在中国运维领域将有“划时代”的重要意义:一方面,这是国内第一本从纵.深和实践角度探讨Python在运维领域应用的著作:一方面本书的 ...

  2. Day1 老男孩python自动化运维课程学习笔记

    2017年1月7日老男孩python自动化运维课程正式开课 第一天学习内容: 上午 1.python语言的基本介绍 python语言是一门解释型的语言,与1989年的圣诞节期间,吉多·范罗苏姆为了在阿 ...

  3. python自动化运维学习第一天--day1

    学习python自动化运维第一天自己总结的作业 所使用到知识:json模块,用于数据转化sys.exit 用于中断循环退出程序字符串格式化.format字典.文件打开读写with open(file, ...

  4. 【目录】Python自动化运维

    目录:Python自动化运维笔记 Python自动化运维 - day2 - 数据类型 Python自动化运维 - day3 - 函数part1 Python自动化运维 - day4 - 函数Part2 ...

  5. python自动化运维篇

    1-1 Python运维-课程简介及基础 1-2 Python运维-自动化运维脚本编写 2-1 Python自动化运维-Ansible教程-Ansible介绍 2-2 Python自动化运维-Ansi ...

  6. Python自动化运维的职业发展道路(暂定)

    Python职业发展之路 Python自动化运维工程 Python基础 Linux Shell Fabric Ansible Playbook Zabbix Saltstack Puppet Dock ...

  7. Python自动化运维 技术与最佳实践PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书

    点击获取提取码:7bl4 一.内容简介 <python自动化运维:技术与最佳实践>一书在中国运维领域将有"划时代"的重要意义:一方面,这是国内第一本从纵.深和实践角度探 ...

  8. python自动化运维之CMDB篇-大米哥

    python自动化运维之CMDB篇 视频地址:复制这段内容后打开百度网盘手机App,操作更方便哦 链接:https://pan.baidu.com/s/1Oj_sglTi2P1CMjfMkYKwCQ  ...

  9. python自动化运维之路~DAY5

    python自动化运维之路~DAY5 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.模块的分类 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数 ...

随机推荐

  1. 常用的MySQL图形化管理软件

    本博文的主要内容有 .SQLyog软件的安装.下载和使用 .Navicat for MySQL软件的安装.下载和使用 1.SQLyog软件的安装.下载和使用 2.Navicat for MySQL软件 ...

  2. cf493A

    Description Vasya has started watching football games. He has learned that for some fouls the player ...

  3. Intellij IDEA 导入Eclipse或MyEclipse的Web项目(旧版 转载)

    Intellij IDEA 导入Eclipse或MyEclipse的Web项目 博客分类: Intellig IDEA Intellij IDEAEclipseWeb  Intellij IDEA 导 ...

  4. bzoj4447 SCOI2015 小凸解密码 password

    传送门:bzoj4447 题解: 调试简直恶心,不过调完发现其实还是挺好写的. 用\(\mathrm{set}\)维护一段\(0\)区间的左右端点,每次最多修改两个点,所以很好维护. 查询的时候在\( ...

  5. iOS开发雕虫小技之傻瓜式定位神器-超简单方式解决iOS后台定时定位

    1.概述 由于公司一款产品的需求,最近一直在研究iOS设备的后台定位.主要的难点就是,当系统进入后台之后,程序会被挂起,届时定时器.以及代码都不会Run~ 所以一旦用户将我的App先换到了后台,我的定 ...

  6. LeetCode201 Bitwise AND of Numbers Range Java 题解

    题目: Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all num ...

  7. Android 仿PhotoShop调色板应用(一)概述

    版权声明:本文为博主原创文章,未经博主允许不得转载. 在前面的系列我已经将Android中颜色渲染的原理及使用做了一个整体上概述. 现在开始根据一个比较复杂的实现进行具体的分析,这就是PhotoSho ...

  8. [转] JavaScript 和事件

    与浏览器进行交互的时候浏览器就会触发各种事件.比如当我们打开某一个网页的时候,浏览器加载完成了这个网页,就会触发一个 load 事件:当我们点击页面中的某一个“地方”,浏览器就会在那个“地方”触发一个 ...

  9. 关于在MDK4.5以上版本不能使用JLINK V8的解决办法

    如果安装MDK4.50版本以上不能使用jlink8的话,请安装jlink 4.36k版本(或以下)驱动,安装完成后,把\SEGGER\JLinkARM_V436k目录下的JLinkARM.dll拷贝到 ...

  10. native跟volatile

    native是告知编译器 该方法是其他语言实现的 比如C 呵呵 private native void CoutSea();没有方法实现部分的 volatile是Java语言的关键字,用在变量的声明中 ...