lhl
首页
python
leetcode
产品思想
软件测试
博客 (opens new window)
github (opens new window)
首页
python
leetcode
产品思想
软件测试
博客 (opens new window)
github (opens new window)
  • python

    • Python 基础

    • Python 数据库

    • 面向对象

    • Python Web

      • flask 入门
      • flask 与 http
        • Request
        • Response
        • 服务端推送
      • flask模板
      • flask表单
      • flask数据库
    • Python 进阶

  • leetcode

  • 软件测试

  • Git

  • linux

  • 产品

  • MySql

  • docker

  • python
  • Python_Web
2024-05-06
目录

flask与http

# Request

# flask get

from flask import Flask
from flask import request

app = Flask(__name__)


## 1. 匹配 /hello
@app.route("/hello")
def hello_1():
    return 'hello flask'


## 2. 匹配 /hello/<params>
@app.route("/hello/<username>")
def hello_2(username):
    print('username:%s' % username)
    return 'hello ' + username


## 3. 匹配 /hello/args/<params>?id=xx&&age=xx
@app.route("/hello/args/<username>")
def hello_3(username):
    print('username:%s' % username)
    id = request.args.get("id")
    age = request.args.get("age")
    return 'hello, id from request %s, age from request %s' % (id, age)


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

  1. @app.route("/hello/<username>"), 匹配 /hello/<params>
  2. /hello/args/<params>?id=xx&&age=xx, id = request.args.get("id")取出参数id

# flask post

from flask import Flask
from flask import request

app = Flask(__name__)


@app.route('/form', methods=['post'])
def post_1():
    return 'post test'


## form
## application/x-www-form-urlencoded or multipart/form-data
@app.route('/form2', methods=['post'])
def post_2():
    username = request.form['username']
    password = request.form['password']
    return 'post received username:%s, password: %s' % (username, password)


## json
@app.route('/form4', methods=['post'])
def post_4():
    username = request.json['username']
    password = request.json['password']

    return 'post received username:%s, password: %s' % (username, password)


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

  1. username = request.json['username'], 相当于request.get_json()['username'],当 post 提交的是 json类型的数据
  2. username = request.form['username'], 相当于request.get_json()['username'],当 post 提交的是表单类型的数据

# 请求钩子

掘金 flask 请求钩子 (opens new window)

Flask 常用请求钩子如下:

  • before_first_request:在处理第一个请求之前运行
  • before_request:在每次请求之前运行,如果没有未处理的异常抛出,会在每个请求结束后运行
  • after_request:如果没有未处理的异常抛出,在每次请求结束后运行
  • teardown_request:即使有未处理的异常抛出,也会在每个请求结束后运行

# Response

完整地说,视图函数可以返回最多由三个元素组成的元组:响应主体、状态码、首部字段。

其中首部字段可以为字典,或是两元素元组组成的列表。

# 只包含主体
@app.route('/hello')
def hello():
    ...
    return '<h1>Hello, Flask!</h1>'

# 默认的状态码为200,下面指定了不同的状态码:
@app.route('/hello')
def hello():
    ...
    return '<h1>Hello, Flask!</h1>', 201

# 有时你会想附加或修改某个首部字段。
# 比如,要生成状态码为3XX的重定向响应,需要将首部中的Location字段设置为重定向的目标URL:
@app.route('/hello')
def hello():
    ...
    return '', 302, {'Location': 'http://www.example.com'}

# 重定向

from flask import Flask, redirect
# ...
@app.route('/hello')
def hello():
    return redirect('http://www.example.com')


# redirect, 重定向 路由 '/hello'
@app.route('/hi')
def hi():
    return redirect(url_for('hello'))

# 错误响应

# 404
from flask import Flask, abort
...
@app.route('/404')
def not_found():
    abort(404)

# 响应格式

from flask import Flask, make_response, request, redirect, url_for, abort, session, jsonify

# 测试如下 /note/xml 请求 xml /note/json 请求 json
@app.route('/note', defaults={'content_type': 'text'})
@app.route('/note/<content_type>')
def note(content_type):
    content_type = content_type.lower()
    # text
    if content_type == 'text':
        body = '''Note
to: Peter
from: Jane
heading: Reminder
body: Don't forget the party!
'''
        response = make_response(body)
        response.mimetype = 'text/plain'
        # html
    elif content_type == 'html':
        body = '''<!DOCTYPE html>
<html>
<head></head>
<body>
  <h1>Note</h1>
  <p>to: Peter</p>
  <p>from: Jane</p>
  <p>heading: Reminder</p>
  <p>body: <strong>Don't forget the party!</strong></p>
</body>
</html>
'''
        response = make_response(body)
        response.mimetype = 'text/html'
        # xml
    elif content_type == 'xml':
        body = '''<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Peter</to>
  <from>Jane</from>
  <heading>Reminder</heading>
  <body>Don't forget the party!</body>
</note>
'''
        response = make_response(body)
        response.mimetype = 'application/xml'
        # json
    elif content_type == 'json':
        body = {"note": {
            "to": "Peter",
            "from": "Jane",
            "heading": "Remider",
            "body": "Don't forget the party!"
        }
        }
        response = jsonify(body)
        # equal to:
        # response = make_response(json.dumps(body))
        # response.mimetype = "application/json"
    else:
        abort(400)
    return response

  1. 根据不同请求参数生成 body, 比如 json 就生成 json 对象, xml, html 同理
  2. make_response(body) 生成响应对象
  3. response.mimetype = 'application/xml',响应对象的mimetype属性设置MIME类型

# 设置 cookie

from flask import Flask, make_response
...
@app.route('/set/<name>')
def set_cookie(name):
    response = make_response(redirect(url_for('hello')))
    response.set_cookie('name', name)
    return response

  1. response = make_response(redirect(url_for('hello'))) 生成响应对象
  2. 响应对象设置 cookie, response.set_cookie('name', name)

# 设置 session

import os
from flask import redirect, session, url_for, request,

# 更安全的做法是把密钥写进系统环境变量(在命令行中使用export或set命令),或是保存在.env文件中
# 获取密钥
app.secret_key = os.getenv('SECRET_KEY', 'secret string')

# 模拟用户登入
@app.route('/login')
def login():
    session['logged_in'] = True  # 写入session
    return redirect(url_for('hello'))


@app.route('/')
@app.route('/hello')
def hello():
    name = request.args.get('name')
    if name is None:
        name = request.cookies.get('name', 'Human')
        response = '<h1>Hello, %s!</h1>' % name
    # 根据用户认证状态返回不同的内容
    if 'logged_in' in session:
        response += '[Authenticated]'
    else:
        response += '[Not Authenticated]'
    return response

# ajax

# AJAX
from jinja2.utils import generate_lorem_ipsum
@app.route('/post')
def show_post():
    post_body = generate_lorem_ipsum(n=2)
    return '''
<h1>A very long post</h1>
<div class="body">%s</div>
<button id="load">Load More</button>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
$(function() {
    $('#load').click(function() {
        $.ajax({
            url: '/more',
            type: 'get',
            success: function(data){
                $('.body').append(data);
            }
        })
    })
})
</script>''' % post_body


@app.route('/more')
def load_post():
    return generate_lorem_ipsum(n=1)
  1. $.ajax(), 请求 /more 接口
  2. /more 接口 返回 html

# 服务端推送

  1. 传统轮询
  2. 长轮询
  3. SSE
  4. websocket

stackoverflow 各种推送优劣 (opens new window)

flask 入门
flask模板

← flask 入门 flask模板→

最近更新
01
lhl learn notes
02
filter
06-09
03
decorator
06-09
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式