用Bottle开发web程序(一)
Bottle
Bottle是一个轻量级的web app框架。相较与django等框架,bottle几乎没有任何依赖,而且只有一个文件。而相对于python默认的SimpleHTTPServer,功能更加丰富,实用更加灵活。如果只是开发一个小型的web程序,bottle已经足够了。easy_install bottle
即可完成bottle的安装。
本文使用的bottle版本是v0.12.9的稳定版。
Hello, world
最简单的程序当然要从hello,world写起。以下是基于bottle的一个程序。
import sys
from bottle import run, route
@route('/')
def hello():
return 'hello, world'
def main():
run(host='0.0.0.0', port=9001)
if __name__ == "__main__":
sys.exit(main())
可以从浏览器直接访问127.0.0.1:9001,当然也可以使用命令行直接访问。
[root@localhost ~]# curl 127.0.0.1:9001
hello, world[root@localhost ~]#
可扩展的server
我们可以看到run(host='0.0.0.0', port=9001)
,这一行是用来启动服务器的。但是这个服务器是阻塞式的,当一个用户请求的时候,其他用户的请求会被阻塞。不要着急,你可以很简单的使用其他的框架来配合bottle来实现无阻塞的web服务器。
目前支持的框架有paste, fapws3, bjoern, gae, cherrypy or any other WSGI capable HTTP server。
不过我这里比较推荐的是paste,用起来也比较简单。首先需要easy_install paste
安装paste。然后把启动命令改为
run(server='paste', host='0.0.0.0', port=9001)
动态路由
bottle可以支持动态的路由,即可以根据路径进行不同的处理。
@route('/path/<subpath>')
def do_path(subpath):
return 'You are visiting /path/%s' % subpath
从这里可以看到,路径作为参数进入到了request
函数中。并可以在函数中可以进行进一步的处理。
[root@localhost ~]# curl 127.0.0.1:9001/path/test
You are visiting /path/test[root@localhost ~]#
文件服务器
bottle可以轻松开发成一个文件服务器,可以支持上传和下载功能。
文件下载
这里使用bottle开发了一个可以下载/tmp文件的服务器。
from bottle import static_file
@route('/static/<filename>')
def do_download(filename):
return static_file(filename, root="/tmp")
根据前面的动态路由可以知道,路径会作为参数进入到函数中。
[root@localhost ~]# ll /tmp/
total 8
-rw-r--r--. 1 root root 648 Apr 5 17:20 test.yaml
可以看到/tmp下有test.yaml文件。然后尝试对其进行下载。
[root@localhost ~]# wget 127.0.0.1:9001/static/test.yaml
--2016-04-06 16:43:20-- http://127.0.0.1:9001/static/test.yaml
Connecting to 127.0.0.1:9001... connected.
HTTP request sent, awaiting response... 200 OK
Length: 648 [text/html]
Saving to: ‘test.yaml’
2016-04-06 16:43:20 (7.84 MB/s) - ‘test.yaml’ saved [648/648]
可以看到可以成功下载该文件。
文件上传
文件的上传需要使用form的方式进行提交。这里举个例子。
@route('/upload/<savename>', method='POST')
def do_upload(savename):
upload = request.files.get('filename')
save_path = os.path.join('/tmp', savename)
upload.save(save_path)
return 'OK'
这个函数的主要功能是首先从提交的文件中,取出name为filename
的文件,然后将其保存在/tmp目录下。
这里form提交文件时,需要设置提交文件的name为filename
。这里使用curl命令进行验证。
[root@localhost ~]# curl -g -i 127.0.0.1:9001/upload/test.txt -X POST -F "filename=@/root/test.txt"
HTTP/1.1 100 Continue
HTTP/1.0 200 OK
Server: PasteWSGIServer/0.5 Python/2.7.5
Date: Wed, 06 Apr 2016 09:39:37 GMT
Content-Length: 2
Content-Type: text/html; charset=UTF-8
OK[root@localhost ~]#
curl命令需要使用-F参数以 multipart/form-data 的方式发送POST请求。-F参数以name=value的方式来指定参数内容,如果值是一个文件,则需要以name=@file的方式来指定。因为程序中要求key为filename
,所以这里使用"filename=@/root/test.txt"
。
可以看到返回值为OK,说明已经上传成功,可以到/tmp下查看。
[root@localhost ~]# ll /tmp/
-rw-r--r--. 1 root root 2 Apr 6 17:07 test.txt
-rw-r--r--. 1 root root 648 Apr 5 17:20 test.yaml
JSON支持
bottle很好的支持了json的请求。当请求是json形式的时候,bottle将会直接将其load进来,程序就可以直接进行处理。
@route('/json', method='POST')
def do_json():
data = request.json
message = data.get('message')
re = {}
re['message'] = 'Your message is %s.' % message
re['status'] = 'success'
return re
这里可以看到,data直接是使用dict的方式进行处理。同时,如果返回的是dict的话,bottle也会自动将其转换为json进行返回。
[root@localhost ~]# curl 127.0.0.1:9001/json -H "Content-type: application/json" -d '{"message":"hello,world"}' -X POST -g -i
HTTP/1.0 200 OK
Server: PasteWSGIServer/0.5 Python/2.7.5
Date: Wed, 06 Apr 2016 09:32:39 GMT
Content-Length: 64
Content-Type: application/json
{"status": "success", "message": "Your message is hello,world."}[root@localhost ~]#
这里特别注意,request需要在header里增加
Content-type: application/json
进行说明请求体是json格式。否则的话不会进行处理。
其他
bottle还有更多更为丰富的功能,比如对函数的请求进行限制,限制其为GET还是POST还是其他方式,设置header,cookie以及其他http metadata的处理。又比如模板功能等等。这些功能可以在官网文档中进一步学习。这里就不一一赘述了。
完整样例
import sys
import os
from bottle import run, request, route, static_file
@route('/')
def hello():
return 'hello, world'
@route('/json', method='POST')
def do_json():
data = request.json
message = data.get('message')
re = {}
re['message'] = 'Your message is %s.' % message
re['status'] = 'success'
return re
@route('/path/<subpath>')
def do_path(subpath):
return 'You are visiting /path/%s' % subpath
@route('/static/<filename>')
def do_download(filename):
return static_file(filename, root="/tmp")
@route('/upload/<filename>', method='POST')
def do_upload(filename):
upload = request.files.get('filename')
save_path = os.path.join('/tmp', filename)
upload.save(save_path)
return 'OK'
def main():
run(server='paste', host='0.0.0.0', port=9001)
if __name__ == "__main__":
sys.exit(main())
用Bottle开发web程序(一)的更多相关文章
- 用Bottle开发web程序(二)
返回码 在开发web程序时,除了一些服务器错误等,常常需要自定义返回码,以便告诉用户处理请求的结果或者状态.bottle支持自定义的返回码,可以通过以下几种方式进行实现. abort 在bottle中 ...
- ASP.NET 5系列教程 (五):在Visual Studio 2015中使用Grunt、Bower开发Web程序
基于Visual Studio 2015,你可以: 方便的管理前端包,如jQuery, Bootstrap, 或Angular. 自动运行任务,如LESS.JavaScript压缩.JSLint.Ja ...
- IDEA开发web程序配置Tomcat
1.下载zip版的Tomcat 7,并解压2.在IDEA中配置Tomcat 7 在idea中的Settings(Ctrl+Alt+s)(或者点击图标 ) 弹出窗口左上过滤栏中输入“Applicatio ...
- eclipse 开发web程序,启动tomcat插件服务器的时候。部署目录在那里?
不在tomcat-home/webapps/下面, 你做一个文件上传功能看看就知道了,临时目录一般是你的工作区间workspace\.metadata\.plugins\org.eclipse.wst ...
- Web程序员开发App系列 - 开发我的第一个App,源码下载
Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...
- Web程序员开发App系列 - 调试Android和IOS手机代码(补图)
Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...
- Web程序员开发App系列 - 申请苹果开发者账号
Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...
- Web程序员开发App系列 - 认识HBuilder
Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...
- 使用Node.js的socket.io模块开发实时web程序
首发:个人博客,更新&纠错&回复 今天的思维漫游如下:从.net的windows程序开发,摸到nodejs的桌面程序开发,又熟悉了一下nodejs,对“异步”的理解有了上上周对操作系统 ...
随机推荐
- 浅析深究什么是SOA?
浅析深究什么是SOA? http://blog.vsharing.com/fengjicheng/A1059842.html 金蝶中间件有限公司总经理 奉继承 博士 阅读提示: 本文探讨SOA概念背后 ...
- 4. SQL Server数据库状态监控 - 作业状态
原文:4. SQL Server数据库状态监控 - 作业状态 有很多地方可以设置定时任务,比如:Windows的计划任务,Linux下的crontab,各种开发工具里的timer组件.SQL Serv ...
- MVC的TryUpdateModel
MVC的TryUpdateModel 我们在使用MVC的时候,给model赋值只需要 TryUpdateModel(model) 就搞定了,而在webForm,winForm中,我们要写长长的 xx. ...
- Erlang运行时的错误
Erlang运行时发生错误时,会返回一些错误信息,理解这些信息,对于学好.用好Erlang来说是必要. Erlang中的运行错误包括:badarg, badarith, badmatch, funct ...
- 基于Asterisk的VoIP开发指南——(2)Asterisk AGI程序编写指南
原文:基于Asterisk的VoIP开发指南--(2)Asterisk AGI程序编写指南 5. Asterisk AGI程序编写指南 5.1概述 很多时候,我们需要在拨号方案中做某些业务逻辑的判断或 ...
- Android总结的基本机制监控事件
研究上午Android底层机制事件监视器,例如下面的摘要: 内核驱动监控硬件状态和行为,由uevent机制将事件发送到用户空间: 通过用户空间UeventObserver从内核监控uevent,处理. ...
- 谈Linux
新手谈Linux 目录: 什么是Linux? Linux与UNIX的区别 Linux与Windows比较 什么是Linux发布版? Linux应用领域 Linux版本的选择 怎么学习Linux? ...
- .NET的微型Web框架 Nancy
.NET的微型Web框架 Nancy .NET的微型Web框架 Nancy 大部分微软平台的开发人员如果选择开发框架只能是在ASP.NET WEBFORM和ASP.NET MVC两个之间选择. 而 ...
- WebService使用DataSetSurrogate压缩Dataset的序列化和解压反序列化传输 (转)
转自:http://blog.163.com/hehong0925@126/blog/static/1339333372012102242920521/ 在WebService中将dataset序列化 ...
- php中session和cookie
cookie 每次请求页面的时候进行验证,如果用户信息存储在数据库中,每次都要执行一次数据库查询,给数据库造成多余的负担.cookie可以被修改的,所以安全系数太低. session是存储在服务器端面 ...