✨基于 Bottle 框架开发API 之 从零到简单封装到应用到上线部署(2)-bottle基础开篇

1,527 阅读8分钟

前言

接续篇开始,接下来我个人就不想逼逼叨叨得太多,主要还实实在在得实打实得记录下,我目前使用得这个框架得一些笔记和心得。

逼逼叨叨

关于我自己: 纯粹的是打杂的一个,似乎啥活都干过,小公司里搬砖久了,似乎啥都懂一些,所以博文有些地方估计有纰漏,还请各位大侠,多多担待! 这一系列的文字算不上是文章,反倒像我个人的日常的开发笔记,难免也有些事我自己的个人想法,如有什么问题,也希望各位多多海涵。

关于Bottle示例简介

一 、用法示例:

from bottle import route, run, template

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

@route('/nihao/<name>')
def index(name):
    return '你好 %s '%s(name)

run(host='localhost', port=8080)

将其保存为py文件并执行,用浏览器访问 http://localhost:8080/hello/world 即可看到返回的信息!

二、windows下的开发安装

1.1 使用Pycharm新建虚拟环境

1.2 安装bottle依赖

pycharm--->file--->settings---> 点击蓝色处

点击加号--->输入bottle搜索

1.3 安装运行官方示例

新建一个main.py

#!/usr/bin/evn python
# coding=utf-8
@Author : 小钟钟同学
@QQ: 308711822@qq.com 
@Time : 2020/3/4 17:28 
@version: v1.0.0
@Contact: 308711822@qq.com
@File : main.py
@desc: 
"""


from bottle import route, run, template

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

@route('/nihao/<name>')
def index(name):
    return '你好 %s '%s(name)

run(host='localhost', port=8080)

右键-run-运行访问浏览器

运行接口访问的形式:http://localhost:8080/nihao/ssss。

通过上面得这种形式,我们得就启动了一个web服务,当然距离我们的可以线上使用还是有一定距离,因为我们的业务不是这么简答一个输出,而且bottle自带的WSGI也只能用于开放状态下进行使用,等到正式上线部署的话,我们还需要使用uwsgi或Gunicorn等来部署我们的应用,还会涉及到使用NGINX做负载等。

二、bottle中的路由映射

2.1 静态路由

所谓的URL路由就是我们的访问浏览器请求资源的时候的对于对应的地址。在bottle这路由的映射是使用@route装饰器来处理的,

如:

@route('/nihao/<name>')
def index(name):
    return '你好 %s '%s(name)

当然我们还可以使用另一个形式来表达的路由映射,bottle提供的Http请求方法的装饰器:

如:

from bottle import get, post, request # or route

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

甚至于我们还支持多路由的映射,bottle一个回调函数可绑定多个route,就是说我们可以多个地址同时处理同一个业务逻辑。 如:

@route('/nihao/2/')
@route('/nihao/<name>')
def index(name):
    return '你好 %s '%s(name)

2.2 动态路由

包含通配符的route,我们称之为动态route(与之对应的是静态route),它能匹配多个URL地址


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

包含通配符的route中的过滤器 可以制定具体的参数相关的匹配规则说明:

:int 匹配一个数字,自动将其转换为int类型。
:float 与:int类似,用于浮点数。
:path 匹配一个路径(包含"/")
:re 匹配路由中部分的一个正则表达式,不更改被匹配到的值

2.3 类似Flask蓝图路由模式

Flask框架中蓝图可以组织封装好相关的组模块,把相关的功能模块包含在同一个组别下,而bottle可以使用子应用的模式来组织代码结构。

framwork_bottle.app01.py的内容如下:

from bottle import Bottle

app01 = Bottle()

@app01.route('/hello/', method='GET')
def index():
    return 'APP01'

framwork_bottle.app02.py的内容如下:

from bottle import Bottle

app02 = Bottle()


@app02.route('/hello/', method='GET')
def index():
    return 'APP02'

main.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 'Root'
 
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)

然后我运行我们的程序,使用POSTMAN提交获取到的结果如下:

请求:http://localhost:8080/hello/

请求:http://localhost:8080/app01/hello/

请求:http://localhost:8080/app02/hello/

2.4 路由钩子函数

钩子顾名思义就是在进入某个函数前先或执行完函数后需要的一些函数。bottle提供了相关的请求前和返回请求响应前的两个钩子函数的处理。如:

@hook('before_request')
def validate():
    """
    钩子函数,请求开始之前之前我们可以做的事情,比如拦截某些请求,比如对某些请求进行过滤
    :return:
    """
    if request.method == 'POST' and request.POST.get('_method'):
        request.environ['REQUEST_METHOD'] = request.POST.get('_method', '').upper()
    # 路由尾部斜杠处理
     request.environ['PATH_INFO'] = request.environ['PATH_INFO'].rstrip('/')
   

@hook('after_request')
def enable_cors():
    '''
    请求返回响应体之前需要做的事情,比如我们可以在响应体响应钱加入跨域支持,写入相关跨域请求头信息
     :return:
    '''
    response.headers['Access-Control-Allow-Origin'] = '*'


2.5 error路由错误装饰器的使用

error(code)这个装饰decorator可以捕捉到具体Http错误码,将错误处理程序安装到当前默认应用程序。


@error(404)
def callback():
    print('拦截http404错误处理')

@error(500)
def callback():
    print('拦截http500错误处理')

@error(403)
def callback():
    print('拦截http403错误处理')

@error(405)
def callback():
    print('拦截http405错误处理')

三、bottle中请求(request)和响应(response)

在bottle中无论是request还是response。都是一个线程安全实例对象,类似FLask中的equestcontest对象request和response。 既然他们本身是一个LocalReqeust对象和LocalResponse对象,说明他们只会针对当前请求进行处理。

所以我们的可以针对request提取出我们的很多字段信息,甚至可以自定义添加其他额外的属性信息。

后续我们的再自定义日志篇上会用到自定义的属性信息。

3.1 request请求体

对于Bottle中封装的可提取的信息主要有:

  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:环境相关相关

3.2 response响应体

其中response本身是一个线程安全实例LocalResponse对象,它存储要发送到客户端的HTTP状态代码以及头和cookie和具体报文信息。

对于Bottle中封装的可提取的信息主要有:

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

3.3 静态文件响应处理

以下说明来自官网文档

static_file() 是服务静态文件的推荐方法。它自动猜测mime类型,并添加 Last-Modified 头,将路径限制为 root 出于安全原因,目录并生成适当的错误响应(权限错误为403,丢失文件为404)。它甚至支持 If-Modified-Since 并最终生成 304 Not Modified 反应。您可以通过自定义的mime类型来禁用猜测。

如果确实需要,你可将 static_file() 的返回值当作异常raise出来。


from bottle import static_file
@route('/images/<filename:re:.*\.png>')
def send_image(filename):
    return static_file(filename, root='/path/to/image/files', mimetype='image/png')

@route('/static/<filename:path>')
def send_static(filename):
    return static_file(filename, root='/path/to/static/files')

3.4 强制下载

大多数浏览器在知道MIME类型的时候,会尝试直接调用相关程序来打开文件(例如PDF文件)。如果你不想这样,你可强制浏览器只是下载该文件,甚至提供文件名。:

如果 download 参数的值为 True ,会使用原始的文件名。


@route('/download/<filename:path>')
def download(filename):
    return static_file(filename, root='/path/to/static/files', download=filename)

3.5 HTTP错误和重定向

abort() 和 redirect()都会自动抛出 HTTPError 异常,终止回调函数的执行。

主动的抛出错误,abort() 函数是生成HTTP错误页面的一个捷径。


from bottle import route, abort
@route('/restricted')
def restricted():
    abort(401, "Sorry, access denied.")

将用户访问重定向到其他URL,你在 redirect() 函数中设置新的URL,接着返回一个 303 See Other 。


from bottle import redirect
@route('/wrong/url')
def wrong():
    redirect("/right/url")

(完)

总结

以上的的是对bottle使用一些简单总结,大部分的知识点,我们也可以从他们提供的官方的文档上提炼到,陈述上面那些基础,只是为了更好我们下一步封装,万丈高楼平地起!我们还是需要对框架一些基础有所了解才能更加深入去使用,应该是这样的吧!

END

好了各位,以上是关于bottle估计也是没什么营养,主要是对接下来封装进一步铺垫!

小钟同学 | 文 【原创】【转载请联系本人】| QQ:308711822