105、 flask介绍、fastapi、wsgiref、Werkzeug、显示用户小案例

161 阅读5分钟

今日内容概要

  • flask介绍
  • fastapi
  • wsgiref
  • Werkzeug
  • 显示用户小案例

今日内容详细

flask介绍

Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。

1.python 界的web框架
	1.Django:大而全,快速开发,公司内部项目
  2.Flask:小而精,不具备web开发好多功能,丰富的第三方插件
  3.FastApi:异步框架,主要为了做前后端分离接口
  4.Sanic:异步框架,只支持python3.6 及以上,性能比较高
  5.Tornado:公司用的比较少
    
2.Flask框架
	pip3 install flask

fastapi

1.安装:
	pip install fastapi
  pip install uvicorn
2.代码
	from fastapi import FastAPI
  app = FastAPI()
  @app.get("/")
  async def root():
      return {"message": "Hello World"}
3.启动
	eg:uvicorn 1-fastapitest:app --reload 
  
	命令uvicorn main:app指的是:
  main:文件main.py(Python“模块”)。
  appmain.py:使用 line内部创建的对象app = FastAPI()。
  --reload:代码更改后重新启动服务器。仅用于开发。

测试

import time
from fastapi import FastAPI

app = FastAPI()

@app.get('/')
async def index():
    time.sleep(10)

    return {'code': 100, 'msg': '成功'}

@app.get('/home')
async def home():
    time.sleep(5)
    return {'code': 100, 'msg': 'home'}

@app.get('/order')
async def home():
    time.sleep(2)
    return {'code': 100, 'msg': 'order'}
1.如果是django,flask,这种同步框架,他会开启三个线程来处理这三个请求
2.fastapi,sanic这种框架,就只用一个线程处理这三个请求

flask

1.安装 pip3 install flask
2.代码
  from flask import Flask

  app = Flask(__name__)

  @app.route('/',methods=['GET'])
  def index():
      return 'hello word'
  if __name__ == '__main__':
      app.run()
3.运行:右键:run,直接运行
ps:请求来了,会执行 app(environ, start_response)--->Flask的__call__(environ, start_response)

flask1.png

wsgiref

1.wsgiref:基于wsgi协议的web服务器,django的web服务用的就是它
	1.相当于个socket服务端,可以接收客户端发送过来的请求,处理,返回给客户端
	2.wsgiref模块就是python基于wsgi协议开发的服务模块
  
  
"""
django中:
	如果请求来了,会执行wsgi中的application(environ, start_response),其返回值是WSGIHandler()-->类的对象,对象加括号会触发__call__(environ, start_response)
flask:
	请求来了,会执行 app(environ, start_response)--->Flask的__call__(environ, start_response)
"""

wsgiref简单应用

from wsgiref.simple_server import make_server
def mya(environ, start_response):
    print(environ)
    start_response('200 OK', [('Content-Type', 'text/html')])
    if environ.get('PATH_INFO') == '/index':
        with open('index.html','rb') as f:
            data=f.read()

    elif environ.get('PATH_INFO') == '/login':
        with open('login.html', 'rb') as f:
            data = f.read()
    else:
        data=b'<h1>Hello, web!</h1>'
    return [data]

if __name__ == '__main__':
    myserver = make_server('', 8011, mya)    # (host, port, app) 监听本地8011端口当请求来了,就会执行mya(),传入两个参数,一个是environ:http请求转成python的字典,一个是start_response:响应对象
    print('监听8011')
    myserver.serve_forever()

Werkzeug

1.Werkzeug是一个WSGI工具包(在它基础上,继续封装),他可以作为一个Web框架的底层库。这里稍微说一下, werkzeug 不是一个web服务器,也不是一个web框架,而是一个工具包,官方的介绍说是一个 WSGI 工具包,它可以作为一个 Web 框架的底层库,因为它封装好了很多 Web 框架的东西,例如 Request,Response 等等

2.flask基于Werkzeug封装的
  django是基于 wsgi封装的

简单使用

from werkzeug.wrappers import Request, Response

@Request.application
def hello(request):
    return Response('Hello World!')

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 4000, hello)
    
    

flask2.png

显示用户小案例

1.新手三件套: 1 直接返回字符串  2 render_template  3 redirect
2.flask的路由写法,是基于装饰器的  @app.route('/detail/<int:pk>' ,methods=['GET'])
3.路由转换器跟django一样
4.取出前端post请求提交的数据:request.form
5.取出请求方式:request.method
6.使用session设置值和取值   
    -session[key]=value
    -session.get('key')
7.flask的模板语法完全兼容dtl,并且它更强大,可以加括号执行

Flask-test.py


from flask import Flask,render_template,request,session,redirect

app = Flask(__name__,template_folder='templates')
app.debug = True
app.secret_key = 'sdfsdfsdfsdf'  # 等同于django的 配置文件有个很长的秘钥

USERS = {
    1:{'name':'张三','age':18,'gender':'男','text':"道路千万条"},
    2:{'name':'李四','age':28,'gender':'男','text':"安全第一条"},
    3:{'name':'王五','age':18,'gender':'女','text':"行车不规范"},
}

@app.route('/login',methods = ['GET','POST'])
def login():
    if request.method == "GET":
        return render_template('login.html')
    else:
        # post请求校验用户名,密码
        username = request.form.get('username')
        password = request.form.get('password')
        if username == 'nana' and password =='123':
            # 登陆成功,存session
            session['username']=username
            return redirect('/index')
        else:
            return render_template('login.html',error='用户名密码错误')

@app.route('/index')
def index():
    # 登陆才能访问
    if session.get('username'):
        return render_template('index.html',users=USERS)
    else:
        return redirect('/login')


# /detail/{{k}}
@app.route('/detail/<int:pk>')
def detail(pk):
    if session.get('username'):
        info = USERS.get(pk)
        return render_template('detail.html',info=info)
    else:
        return redirect('/login')

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

templates /login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method = 'post'>
    <div>
<label for="username">用户名</label>
        <input type="text" id="username" name="username">
    </div>
    <div>
        <label for="password">密码</label>
        <input type="password" id="password" name="password"></div>
    <div>

        <input type="submit" >{{error}}</div>
</form>

</body>
</html>

templates /index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>用户列表</h1>
    <table>
        {% for k,v in users.items() %}
        <tr>
            <td>{{k}}</td>
            <td>{{v.name}}</td>
            <td>{{v['name']}}</td>
            <td>{{v.get('name')}}</td>
            <td><a href="/detail/{{k}}">查看详细</a></td>
        </tr>
        {% endfor %}
    </table>

</body>
</html>

templates /detail.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
   <h1>详细信息 {{info.name}}</h1>
    <div>
        {{info.text}}
    </div>

</body>
</html>

flask写个登录认证装饰器



from flask import Flask,render_template,request,session,redirect
from functools import wraps

app = Flask(__name__,template_folder='templates')
app.debug = True
app.secret_key = 'sdfsdfsdfsdf'  # 等同于django的 配置文件有个很长的秘钥

USERS = {
    1:{'name':'张三','age':18,'gender':'男','text':"道路千万条"},
    2:{'name':'李四','age':28,'gender':'男','text':"安全第一条"},
    3:{'name':'王五','age':18,'gender':'女','text':"行车不规范"},
}


def login_outer(func_name):
    @wraps(func_name)
    def inner(*args,**kwargs):
        if session.get('username'):
            res = func_name(*args, **kwargs)
            return res
        else:
            return redirect('/login')
    return inner





@app.route('/login',methods = ['GET','POST'])
def login():
    if request.method == "GET":
        return render_template('login.html')
    else:
        # post请求校验用户名,密码
        username = request.form.get('username')
        password = request.form.get('password')
        if username == 'nana' and password =='123':
            # 登陆成功,存session
            session['username']=username
            return redirect('/index')
        else:
            return render_template('login.html',error='用户名密码错误')

@app.route('/index')
@login_outer   # index= login_outer(index)
def index():
    # 登陆才能访问
    return render_template('index.html',users=USERS)



# /detail/{{k}}

@app.route('/detail/<int:pk>')
@login_outer   # detail= login_outer(detail)
def detail(pk):

    info = USERS.get(pk)
    return render_template('detail.html',info=info)

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

了解-技术类博客

1.思否:https://segmentfault.com/channel/backend
2.掘金:https://juejin.cn/
	-https://juejin.cn/post/7220643710659657785
3.开发者头条:https://toutiao.io/
	-https://mp.weixin.qq.com/s/GSslajNsZ0xGqwDtDHRf6g
4.脉脉:
	-app--->投简历--->吐槽--->互联网公司爆料