0
点赞
收藏
分享

微信扫一扫

flask学习笔记

you的日常 2022-03-13 阅读 40

Flask学习笔记

flask简介

轻量级web开发框架,依赖jinja2(路由模块)和 Werkzeug WSGI(模版引擎) 服务的一个微型框架。

需要使用其他功能时需要装其他插件。

初识Flask

安装flask

pip install flask

入门-简单的使用demo

# 1.导入模块Flask类
from flask import Flask

#2.建立Flask的实例,__name__ 为了找到资源
app = Flask(__name__)

#3.装饰器,为函数指定路由即访问路径
@app.route("/")
def hello_world():
    return "欢迎使用flask"

运行flask web服务:

方法一:使用bash命令(windows使用cmd命令)

#bash命令(需要先进入执行文件的目录):
export FLASK_APP=b-flask-demo  #(脚本.py的文件名)
flask run

方法二:在python代码中插入代码

if __name__ == '__main__':
    app.run()   # app 是前面是实例化Flask()的对象

然后运行文件即可,右键run即可运行,在下方终端terminal能看到如下消息说明运行成功

 * Serving Flask app "b-flask-请求方法" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

此时,浏览器输入 http://127.0.0.1:5000/ 即可访问

接口与路由技术

什么是路由?

路由简单的说就是将url 路径与 一个函数建立对应的映射关系,在输入url后,会在路由表中查询url与函数的对应关系从而调用对应的函数。

以使用bing搜说iphone为例,搜说的完整url如下:

  • https: 使用的协议是https协议
  • cn.bing.com: 主机(host)的域名,在向域名解析服务器dns求情后会转换为ip地址
  • /search: 路由,请求的接口,通常通过不同的接口调用不同的函数
  • ?q=iphone : 请求的参数

PS: 通常在主机后面还有端口如: http:127.0.0.1:5000/ 其中5000即是端口,一般http协议使用80端口,https协议使用443端口,浏览器会自动给我门填充,因此浏览器访问使用https/http 协议可以不写端口,写的话也可以哦

通过上诉介绍大致了解了什么是 路由,即域名活着ip后面 紧紧跟着的即是路由。访问对应的url时会调用对应的方法。

在flask中使用app.route()来设置路由与函数的对应关系

举例:

@app.route("/get_info/")
def welcome():
    return "正在调用的是welcome 函数"

在浏览器中输入127.0.0.1:5000/get_info 进行浏览时会返回

“正在调用的是welcome 函数”, 说明get_info调用的便是 welcome() 函数

其中127.0.0.1:5000 是flask默认的主机和端口号,在启动服务器配置 中有介绍

注意: 在浏览器中 会自动在url中补充 ‘/’,因此如果在路由中没有配置’/'有可能会返回404,找不到资源

此时在浏览器中输入 127.0.0.1:50000/get_info 会报错找不大资源,引因为 浏览器自动路径加了 ‘/’

因此定义路由时可以将’/'加上

http请求方法

常用的请求方法及使用

常见的http请求有以下四种:

  • get :获取服务器资源
  • post:新增服务器资源
  • put:更新服务器资源
  • delete:删除服务器资源

具体使用:

  1. get请求:

    @app.route("/", methods=['get', "delete"])
    def welcome():
        logger.info("welcome")
        return {"code": 0, "msg": "get success"}
    
  2. post请求

    # post方法
    @app.route("/login/", methods=['post'])
    def login():
        logger.info("login")
        return {"code": 0, "msg": "post success"}
    

    可以使用postman 发送一个post请求,报文如下如下:

    POST /login/ HTTP/1.1
    Host: 127.0.0.1:5000
    Content-Type: application/json
    Cache-Control: no-cache
    Postman-Token: 52bfac5c-d82e-4b5f-a12a-6c8456c3444c

    {
    “name”:“aaa”
    }

    发送后的收到如下响应:

    {
        "code": 0,
        "msg": "post success"
    }
    
  3. put请求

    python代码

    # put方法
    @app.route("/update/<name>", methods=["put"])
    def update_case(name):
        logger.info(f"姓名修改为:{name}")
        return {"code": 0, "msg": f"{name } update success"}
    

    postman发送如下请求:

    PUT /update/lisi HTTP/1.1
    Host: 127.0.0.1:5000
    Content-Type: application/json
    Cache-Control: no-cache
    Postman-Token: 72f93571-965e-43de-84e8-dcf35af74517
    {
    	"name":"aaa"
    }
    

    postman接收响应

    {
        "code": 0,
        "msg": "lisi update success"
    }
    
  4. delete请求

    # delete方法
    @app.route("/del/<string:name>", methods=["delete"])
    def delete_user(name):
        return {"code": 0, "msg": f"{name} delete success"}
    

    postman发送测试报文

    DELETE /del/lisi HTTP/1.1
    Host: 127.0.0.1:5000
    Content-Type: application/json
    Cache-Control: no-cache
    Postman-Token: 9c91e7c0-518c-45e4-8ef2-7992f95728ad
    
    {
    	"name":"aaa"
    }
    

    返回的响应

    {
        "code": 0,
        "msg": "lisi delete success"
    }
    

处理请求的数据

在flask框架中 处理请求通常使用 flask的request库,因此第一步需要导入request

from flask import request

request的常用属性和方法:

属性/方法说明
args记录请求中的查询参数
json记录请求中的 json 数据
files记录请求上传的文件
form记录请求中的表单数据
method记录请求使用的 HTTP 方法
url记录请求的 URL 地址
host记录请求的域名
headers记录请求的头信息

处理get请求中的url参数

# 处理get请求的数据
# 浏览器中输入url:http://127.0.0.1:5000/login/?name=lili
@app.route("/login/", methods=["get"])
def get_data():
    print(request.args)
    args = request.args
    # 获取url中的 name 请求参数
    name = request.args.get("name")
    return {"code": 0, "msg": f"{name} login success"}

浏览器返回:

{
  "code": 0, 
  "msg": "lili login success"
}

请求参数为json格式

@app.route("/add",methods=["post"])
def add_user():
    # request.json  获取请求的json数据
    data = request.json.get("name")
    logger.info(data)
    return {"code": 0, "msg": f"{data} login success"}

表单请求

登陆网站有时候用户名和密码,前端会向后端提供一个form表单

处理方法:(ps:request 从flask中导入)

request.form

# 处理form表单
@app.route("/regist",methods=['post'])
def regist():
    form_data = request.form
    name = form_data.get("name")
    return {"code": 0, "msg:": f"{name} regist success"}

postman调试

POST /regist HTTP/1.1
Host: 127.0.0.1:5000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
cache-control: no-cache
Postman-Token: bb6f7dca-04a5-4cd7-8aa2-442db43742cf

Content-Disposition: form-data; name="name"

李雷

结果:

{
    "code": 0,
    "msg:": "李雷 regist success"
}

文件请求

用于前端传递图片之类的文件到后端服务器

处理方法:

  • request.files.get(‘file’) 获取文件对象
  • filename 获取文件名
  • save() 方法保存文件到指定路径

举例:

# 处理文件
@app.route('/file', methods=['post'])
def save_file():
    # 获取文件对象
    file_obj = request.files.get('file')
    # 获取文件对象的文件名
    file_name = file_obj.filename
    # 保存文件到当前目录下
    file_obj.save(f"./{file_name}")
    logger.info(f"收到文件 {file_name}")
    return {"code": 0, "msg:": f"{file_name} rec success"}

写一个脚本测试发送文件

def test_fle():
    url = 'http://127.0.0.1:5000/file'
    # 一般打开文件都是rb二进制打开
    file = {'file': open('/Users/yang/Pictures/截图.png', 'rb')}
    r = requests.post(url,files=file)
    print(r.json())
    assert r.status_code == 200

postman也可以,但是需要使用form表单,然后选择file,

POST /file HTTP/1.1
Host: 127.0.0.1:5000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
cache-control: no-cache
Postman-Token: 0761192e-664e-4d79-8705-ce59d2fb45ea

Content-Disposition: form-data; name="file"; filename="/Users/yang/Pictures/截图.png

处理响应数据

常见的响应有:

返回文本

@app.route('/text')
def get_text():
	return '返回文本'

返回元组

  • (response,status)
  • (response,headers)
  • (response,status,headers
# 返回元组
# - (response,status)
# - (response,headers)
# - (response,status,headers)
@app.route("/tuple")
def tuple_rtn():
    # 返回体body为: "code": "0", "msg":"tuple success"}
    # 返回的状态码为:900 ,一般成功是200,这里测试
    # 返回的header中 token为123456
    return '{"code": "0", "msg":"tuple success"}', 900, {"token": "123456"}

返回json 最常见、重要

  • 直接返回dict() 会转换为json

    # 返回json 使用返回字典
    @app.route("/json/")
    def json_rtn():
        return {"status": 0, "msg": "return json success"}
    
  • 使用jsonify(),通过键值对参数传入

    # 返回json 使用返回字典
    @app.route("/jsonify/")
    def jsonify_rtn():
        return jsonify(status=1, msg="return josnify success")
    

返回html

  • 使用模版渲染技术
  • html文档必须在统计目录的templates目录下(PS:不要拼写错了)

如下目录所示:执行的.py文件与templates 在同级目录下,需要返回的html文档放到templates中

├── d-flask-处理响应.py
├── templates
│   └── hello.html
# d-flask-处理响应.py文件中
# 返回html
@app.route('/get_html/')
def html_rtn():
    return render_template('hello.html')

html文件

<html>
  <body>
    <p>
    <h1>
      这是一个一集标题
    </h1>
    这是一个html
    </p>
  </body>
</html>

设置额外的数据

使用make_response()可以添加更多的响应信息

  • 设置cookie
  • 设置响应头信息等
# 设置额外的返回,如返回header中的其他信息
# 设置cookie等
@app.route('/more/')
def more_rtn():
    resp = make_response(render_template('hello.html'))
    # 设置cookie
    resp.set_cookie('cookie', 'dadasda')
    # 设置响应头信息
    resp.headers["hosdaas"] = "dsad"
    return resp

启动服务配置

监听的主机

设置host参数

  • 127.0.0.1 只可以本机访问
  • 0.0.0.0 服务可以发布到局域网,其他电脑(同一个局域网)访问时输入服务器的ip和端口可以访问
app.run(host="0.0.0.0")

监听的端口

if __name__ == '__main__':
    app.run(host="0.0.0.0",port=10000)

debug模式

设置debug=True(默认为production)

  • 实现热加载
  • 开发调试更为方便
if __name__ == '__main__':
    app.run(host="0.0.0.0",port=10000,debug=True)

接口—flask-restx

介绍

接口编写需要统一,目前尽量遵循restful接口规范

什么是接口文档

在项目开发中,web项目的前后端分离开发,APP开发,需要由前后端工程师共同定义接口,编写接口文档,之后大家都根据这个接口文档进行开发,到项目结束前都要一直维护

为什么要写接口文档

1、项目开发过程中前后端工程师有一个统一的文件进行沟通交流开发
2、项目维护中或者项目人员更迭,方便后期人员查看、维护

flask-restx的安装

python 2.7 或则 3.4+

pip install flask-restx

简单的demo

from flask import Flask
# 导入flask_restx的Api、Resource类
from flask_restx import Resource, Api

# 实例化flask
app = Flask(__name__)
# 实例化flask_restx 的Api对象,绑定flask的app
api = Api(app)

# 注意这里使用api.route()
# 而不是app.route()
@api.route('/hello/') # 有时候浏览器中输入url会在url的后面自动加一个 '/'
# 定义一个helloworld,需要基础fask_restx 中的Resource类
class HelloWorld(Resource):
    # restful 风格的get方法
    def get(self):
        return {'hello': 'world'}
    # resful 风格的post方法
    def post(self):
        return {"post": "success"}

if __name__ == '__main__':
  	# 注意启动时依旧用app.run()
    app.run(debug=True)

添加路由的方式

  • 装饰器
  • api的add_resource()方法
from flask import Flask
from flask_restx import Api, Resource

# 实例化Flask()
app = Flask(__name__)
# flask_restx的api绑定到Flask()实例
api = Api(app)


# flask_restx 的api通过装饰器添加路由
@api.route('/login')
class Test(Resource):
    def get(self):
        return {"code": 0, "msg": "flask restx login ssuccess"}

# 通过add_resource()新增一个地址
api.add_resource(Test, '/login2')

if __name__ == '__main__':
    app.run(debug=True)

flask restx集成Swagger

swagger 用于编写一个清晰的接口文档,入参、返回值等信息,自动生成接口文档。

namespace的使用

解决路由分类问题。

不实用namespace进行分类时

from flask import Flask
from flask_restx import Resource, Api

app = Flask(__name__)
api = Api(app)


# 接口路径定义到类上,对应的不同请求操作创建不同的方法

@api.route("/case")
class TestCase(Resource):
    # restful 风格的 get 方法
    def get(self):
        return {"code": 0, "msg": "get success"}

    # restful 风格的 post 方法
    def post(self):
        return {"code": 0, "msg": "post success"}

    # restful 风格的 put 方法
    def put(self):
        return {"code": 0, "msg": "put success"}

    # restful 风格的 delete 方法
    def delete(self):
        return {"code": 0, "msg": "delete success"}


@api.route("/demo")
class Demo(Resource):
    # restful 风格的 get 方法
    def get(self):
        return {"code": 0, "msg": "get success"}

    # restful 风格的 post 方法
    def post(self):
        return {"code": 0, "msg": "post success"}

    # restful 风格的 put 方法
    def put(self):
        return {"code": 0, "msg": "put success"}

    # restful 风格的 delete 方法
    def delete(self):
        return {"code": 0, "msg": "delete success"}


if __name__ == '__main__':
    app.run(debug=True)

效果:

image-20220313150309502

swagger接口文档配置

举报

相关推荐

0 条评论