flask要点与坑

简介

Flask是一个用Python编写的Web应用程序框架,该框架简单易用、模块化、灵活性高。

该笔记主要记录Flask的关键要点和容易踩坑的地方

Flask 日志配置

Flask 中的自带logger模块(也是python自带的模块),通过简单配置可以实现将日志记录到日志文件中(记录关键日志有助于以后分析问题);更详细的logging配置可以自行去百度。

# 日志模配置
# coding : utf-8import os
import logging
from logging.handlers import RotatingFileHandlerdef init_app(app):'''param app : FLask实列(启动时的app)'''basedir = os.path.abspath(os.path.dirname(__file__))# Formatterformatter = logging.Formatter('%(asctime)s %(levelname)s %(lineno)s %(message)s')# 日志配置log_path = LOG_PATH = os.path.join(basedir, 'logs')log_info = os.path.join(log_path, 'flask.log')if not os.path.exists(log_path):os.mkdir(log_path)app.config['LOG_PATH'] = log_pathapp.config['LOG_PATH_INFO'] = log_infoapp.config['LOG_FILE_MAX_BYTES'] = 100 * 1024 * 1024# 轮转数量是 10 个app.config['LOG_FILE_BACKUP_COUNT'] = 10# FileHandler Infofile_handler_info = RotatingFileHandler(filename=log_info)file_handler_info.setFormatter(formatter)file_handler_info.setLevel(logging.INFO)app.logger.addHandler(file_handler_info)
from flask import Flask
from log_hander import init_appapp = Flask(__name__)init_app(app)@app.route('/')
def test():app.logger.info('hello world')return "hello world"

正常情况下,日志(flask.log)中会输出 ”hello world“信息,但实际情况却没有

这里有个坑,就是在init_app 函数最后需要再加上一段代码:

 app.logger.setLevel(logging.INFO) 

这个问题困扰我很长时间

Flask Blueprint

Flask的简单之处就是一个py文件就可以创建一个http服务

from flask import Flask
from log_hander import init_appapp = Flask(__name__)@app.route('/',methods=["GET"])
def test():app.logger.info('hello world')return "hello world"
# 添加任意数量的 处理函数
app.run()

实际项目中不能把所有的业务处理都放到一个py文件中,那么就需要划分模块了。

蓝图(Blueprint)可以帮助我们划分模块(有点类似asp.net mvc、java springboot中的控制器)

一般的做法:建立一个python包,在里面添加我们的模块文件(根据业务划分),每个模块中定义一个蓝图(Blueprint),最后在app中注册蓝图(Blueprint)。

home.py 模块

# coding : utf-8from flask import Blueprint
from flask import render_templatehome_blue=Blueprint('home',__name__)# 访问路径
# http://ip:port/home
# http://ip:port/home/index
@home_blue.route('/',methods=['GET'])
@home_blue.route('/index',methods=['GET'])
def index():'''首页@return render_template'''return render_template('index.html',title='Home Page')@home_blue.route('/welcom',methods=['GET'])
def welcomPage():return render_template('welcome_iframe.html',title='Welcom Page')pass

login.py 模块

# coding : utf-8
from flask import Blueprint
from flask import render_templatelogin_blue = Blueprint('login', __name__)# 访问路径
# http://ip:port/
# http://ip:port/index@login_blue.route('/', methods=['GET'])
@login_blue.route('/index', methods=['GET'])
def index():'''登陆首页@return render_template'''if user_id == None:return render_template('login.html',title='登录页')@login_blue.route('/login_user', methods=['POST'])
def user_login():'''登录:return:'''try:# 登录逻辑return jsonify(common_tools.get_res_model(None, '验证通过', True))except:return jsonify(common_tools.get_res_model(None, '验证未通过', False))

_init_.py

# coding : utf-8
from flaskAdmin.views.home import home_blue
from flaskAdmin.views.login import login_bluedef init_route(app):app.register_blueprint(login_blue,url_prefix='/')app.register_blueprint(home_blue,url_prefix='/home')

app.py中设置

from flask import Flask
from my_moudle import init_routeapp = Flask(__name__)
init_route(app)app.run()

templates 过滤器

在Flask中,过滤器(filters)是一种用于处理输入并生成输出的函数,用于在模板渲染过程中转换数据。Flask内置了多种过滤器,同时支持自定义过滤器。这里主要是说过自定义过滤器

app中定义过滤器

使用@app.template_filter(“filter name”) 添加

from flask import Flask
from log_hander import init_appapp = Flask(__name__)@app.template_filter("format_float") 
def formater_float(val:float):'''定义一个格式化浮点数据的过滤器'''return "{:.2f}".format(val)app.run()

使用过滤器

<div>{{my_value|format_float}}
</div>

Blueprint中定义

使用@blue.app_template_filter(“filter name”)添加

@blue.app_template_filter("format_float")
def formater_float(val:float):'''定义一个格式化浮点数据的过滤器'''return "{:.2f}".format(val)

注意:Blueprint中定义的过滤器是全局的,所有模板都可以使用

ORM

sqlalchemy 框架是我的首选。

安装:pip install Flask-SQLAlchemy

model定义

# coding: utf-8
from sqlalchemy import Column, DateTime, String, Text
from sqlalchemy.dialects.mysql import INTEGER
from sqlalchemy.ext.declarative import declarative_base
from flask_sqlalchemy import SQLAlchemyBase = declarative_base()
metadata = Base.metadataclass User(Base):__tablename__ = 'user'# 指定ID对应的数据字段(model定义字段与数据字段不一致时)ID = Column("uuid",String(64, 'utf8_bin'), primary_key=True) UserCode = Column(INTEGER(11), nullable=False)UserRealName = Column(String(64, 'utf8_bin'), nullable=False)DelFlag = Column(String(2, 'utf8_bin'), nullable=False)PassWord = Column(String(128, 'utf8_bin'), nullable=False)Remark = Column(Text(collation='utf8_bin'))CreateDate = Column(DateTime, nullable=False, comment='创建日期')LastLoginTime = Column(DateTime, comment='最后一次登录日期')ValidityOfTime = Column(DateTime, comment='账户有效期')UserRole = Column(String(64, 'utf8_bin'), nullable=True)# ...
db = SQLAlchemy()

app.py 中配置

from flask import Flask
from db_model import dbapp = Flask(__name__)# 关键步骤
# SQLALCHEMY_DATABASE_URI  数据库连接字符串
app.config["SQLALCHEMY_DATABASE_URI"] = 'mysql+pymysql://usermame:password@host:port/dbname?charset=utf8'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True # 跟踪对象修改,有点类似EF中的状态跟踪
app.config["SQLALCHEMY_ECHO"] = False # 是否打印SQL日志
db.init(app)app.run()

Session

web离不开session。可以使用Flask-Session模块,也可以自定义实现(原理并不复杂,这里不罗嗦了)

安装:pip install Flask-Session

app.py 中配置

from flask import Flask
from datetime import timedeltaapp = Flask(__name__)app.config["SESSION_TYPE"]='redis' # 需要额外安装redis模块
app.config["SESSION_REDIS"]=Redis(host="127.0.0.1",port=6379)
app.config["SESSION_USE_SIGNER"]=True # 使用字符存储
app.config["SECRET_KEY"]='FLASK_SYSADMIN' # session 加密key
app.config["SESSION_PERMANENT"]=False
app.config["PERMANENT_SESSION_LIFETIME"]=timedelta(seconds=60*20) # session超时时间app.run()

使用方式

# 导入session模块
from flask import sessiondef func():# ...session['user_id'] = user.IDsession['user_code'] = user.UserCode# ...

建议将session信息存储的redis中,方便后期分布式部署或作集群时共享登录信息

部署

Flask自带一个服务器,但是也明确指出自带的服务器只能用于开发环境,不能用于生产环境。

linux

Linux环境可以使用uwsgi部署,但是uwsgi需要自己编译。有兴趣的化可以百度查一下,这里不推荐。

windows

windows环境下可以部署到IIS中(IIS最低版本7.0,至少时winserver 2008以后的版本),IIS中部署python web的机会不多,但网上确实有部署教程,有兴趣的可以自行搜索。

uvicorn 、tornado承载

uvicorn 、tornado也是python的一种web框架,是一种异步框架,与Flask结合可以降低部署难度,还可以享受Flask开发带来的便利。

这里演示一下tornado的承载方式:

将Flask主项目放到一个pathon包中,经app的声明迁移到_init_.py 中

在这里插入图片描述

runserver.py

# coding: utf-8
from tornado.wsgi import  WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from flaskAdmin import app,config
import sys
import redef main():HOST = config.APP_HOSTPORT = config.APP_PORTif len(sys.argv) == 3:_ip_check=r"^(\d{1,3}\.){3}\d{1,3}$"ip_addr = sys.argv[1]ip_port = sys.argv[2]if re.match(_ip_check,ip_addr) !=None and re.match(r'^[1-9]\d{1,5}$',ip_port)!=None:PORT=int(ip_port)HOST=ip_addrhttp_server=HTTPServer(WSGIContainer(app))http_server.listen(PORT,HOST)IOLoop.instance().start()if __name__ == '__main__':main()

使用uvicorn 、tornado承载需要注意一点:如果你的服务需要处理高并发的场景,一定要在服务的前面加一个代理来限制最高并发数量,否则你的服务可能会出现崩溃的情况;这是uvicorn 、tornado一个大坑,两个库都没有做最大并发限制,如果并发超过服务器主机的最大限制,操作系统会报一个 select描述符错,而这两个库并不处理这个异常(针对这个问题stackoverflow论坛上有很多人吐槽)。

https

生成密钥(windows环境下需要自行安装openssl):

# 生成私钥,按照提示填写内容
openssl genrsa -des3 -out server.key 1024# 生成csr文件 ,按照提示填写内容
openssl req -new -key server.key -out server.csr# Remove Passphrase from key
cp server.key server.key.org 
openssl rsa -in server.key.org -out server.key# 生成crt文件,有效期1年(365天)
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Flask app中配置的方式

from flask import Flask
from log_hander import init_appapp = Flask(__name__)if __name__ == "__main__":app.run(host='127.0.0.1',port=10262,ssl_context = ("SLL_CRT_PATH","SSL_KEY_PATH")) # 设置ssl 密钥路径

tornado承载中配置

如果使用tornado承载部署,可以在tornado.httpserver.HTTPServer中设置密钥

http_server=HTTPServer(WSGIContainer(app),ssl_options={"certfile":"SLL_CRT_PATH","keyfile":"SSL_KEY_PATH"})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/134419.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

周易算卦流程c++实现

代码 #include<iostream> using namespace std; #include<vector> #include<cstdlib> #include<ctime> #include<Windows.h>int huaYiXiangLiang(int all, int& left) {Sleep(3000);srand(time(0));left rand() % all 1;while (true) {if…

【React】React入门

目录 一、何为React二、React与传统MVC的关系三、React的特性1、声明式编程①、实现标记地图 2、高效灵活3、组件式开发(Component)①、函数式组件②、类组件&#xff08;有状态组件&#xff09;③、一个组件该有的特点 4、单向式响应的数据流 四、虚拟DOM1、传统DOM更新①、举…

【ubuntu】修改系统及硬件时间

Linux系统时间分为两种&#xff1a;系统时间&#xff08;S有stem Clock&#xff09;和硬件&#xff08;Realtime Clock&#xff0c;简称RTC&#xff09;时间。 上网找了好多教程&#xff0c;每次修改完后&#xff0c;不到几秒钟&#xff0c;时间又恢复成之前的时间了。 -------…

pytorch代码实现之动态卷积模块ODConv

ODConv动态卷积模块 ODConv可以视作CondConv的延续&#xff0c;将CondConv中一个维度上的动态特性进行了扩展&#xff0c;同时了考虑了空域、输入通道、输出通道等维度上的动态性&#xff0c;故称之为全维度动态卷积。ODConv通过并行策略采用多维注意力机制沿核空间的四个维度…

VUE之proxy配置实现跨域

什么是跨域 要了解跨域&#xff0c;首先得知道浏览器的同源策略。 同源策略&#xff1a;是由Netscape提出的一个安全策略&#xff0c;能够阻挡恶意文档&#xff0c;保护本地数据。它能限制一个源的文档或脚本对另一个源的交互&#xff0c;使得其它源的文档或脚本&#xff0c;…

火山引擎 ByteHouse:ClickHouse 如何保证海量数据一致性

背景 ClickHouse是一个开源的OLAP引擎&#xff0c;不仅被全球开发者广泛使用&#xff0c;在字节各个应用场景中也可以看到它的身影。基于高性能、分布式特点&#xff0c;ClickHouse可以满足大规模数据的分析和查询需求&#xff0c;因此字节研发团队以开源ClickHouse为基础&…

docker 已经配置了国内镜像源,但是拉取镜像速度还是很慢(gcr.io、quay.io、ghcr.io)

前言 国内用户在使用 docker 时&#xff0c;想必都遇到过镜像拉取慢的问题&#xff0c;那是因为 docker 默认指向的镜像下载地址是 https://hub.docker.com&#xff0c;服务器在国外。 网上有关配置 docker 国内镜像源的教程很多&#xff0c;像 腾讯、阿里、网易 等等都会提供…

前后端跨域请求问题解决方法

如图&#xff1a; 1.在config配置包中创建一个CorsConfig配置类 2.将下面代码复制到这个类中即可 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfigurati…

华为云云耀云服务器L实例评测|服务器反挖矿防护指南

前言 本文为华为云云耀云服务器L实例测评文章&#xff0c;测评内容是 云耀云服务器L实例 反挖矿防护指南 系统配置&#xff1a;2核2G 3M CentOS7.9 之前的文章中『一文教你如何防御数据库恶意攻击』&#xff0c;我们讲到黑客如何通过攻击数据库来获取权限&#xff0c;以及我们…

Java面试常用函数

1. charAt() 方法用于返回字符串指定索引处的字符。索引范围为从 0 到 length() - 1。 map.getOrDefault(num, 0) :如果map存在num这个key&#xff0c;则返回num对应的value&#xff0c;否则返回0. Arrays.sort(nums); 数组排序 Arrays.asList("a","b",&q…

详细解释HiveSQL执行计划

一、前言 Hive SQL的执行计划描述SQL实际执行的整体轮廓&#xff0c;通过执行计划能了解SQL程序在转换成相应计算引擎的执行逻辑&#xff0c;掌握了执行逻辑也就能更好地把握程序出现的瓶颈点&#xff0c;从而能够实现更有针对性的优化。此外还能帮助开发者识别看似等价的SQL其…

java 封装一个将String类型转Long类型的函数

Long是一种超大类型的数字变量类型 但java无法直接生成这种数据 但我们可以封装一个函数 public Long getuniid(String number) {Long longNumber Long.parseLong(number);return longNumber; }这样 我们就可以传入一个字符串 然后将其转换为 long 然后我们调用这个函数 Sys…

向日葵无法连接服务器(无法登录)

最近在使用向日葵过程中&#xff0c;突然就不能登录向日葵了&#xff0c;网上查了各种解决方案&#xff0c;比如说防火墙是不是把向日葵给拦截了&#xff1f;更换不同的版本等等&#xff0c;都无法解决&#xff0c;最后突然想到是不是电脑对向日葵原安装目录限制了&#xff1f;…

虚拟化技术:深入浅出

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

PY32F003F18之输入捕获

输入捕获是定时器的功能之一&#xff0c;配合外部引脚&#xff0c;捕获脉宽时间或采集周期。 CPU中的定时器最基本的功能就是计数功能&#xff0c;其次是输入捕获(IC)&#xff0c;再次就是比较输出(OC)&#xff0c;还有就是使用引脚对外部时钟进行计数&#xff0c;触发信号捕捉…

关于阿里云服务器Ubuntu编译jdk8中遇到的坑及解决方案

关于阿里云服务器Ubuntu系统安装jdk8中遇到的坑及解决方案 记录一下困扰了很多天、到处查资料最后终于成功安装的过程 关于阿里云服务器无法登录的问题 基本反馈是这样的&#xff1a; 如果你添加了ip之后仍然登不进去&#xff0c;有一种方法是直接从第三个选项进去登录之后修…

JWT安全

文章目录 JWT是什么&#xff1f;为什么要使用JWT&#xff1f;JWT的数据结构JWT的工作过程 JWT是什么&#xff1f; JSON Web Token (JWT)是一个开放标准(RFC 7519)&#xff0c;它定义了一种紧凑的、自包含的方式&#xff0c;用于作为JSON对象在各方之间安全地传输信息。 JWT全称…

《Python趣味工具》——自制emoji2(2)

今天&#xff0c;我们将会完成以下2个内容&#xff1a; 绘制静态emoji总结turtle中常用的绘图函数 文章目录 一、绘制静态emoji&#xff1a;:sparkles: 画脸&#xff1a;:sparkles:绘制嘴巴&#xff1a;:sparkles:绘制眼白&#xff1a;绘制眼白-Part1&#xff1a;绘制眼白—pa…

积木报表 JimuReport v1.6.2-GA5版本发布—高危SQL漏洞安全加固版本

项目介绍 一款免费的数据可视化报表&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于excel操作风格&#xff0c;通过拖拽完成报…

Apache Spark 在爱奇艺的应用实践

01 Apache Spark 在爱奇艺的现状 Apache Spark 是爱奇艺大数据平台主要使用的离线计算框架&#xff0c;并支持部分流计算任务&#xff0c;用于数据处理、数据同步、数据查询分析等场景&#xff1a; 数据处理&#xff1a;在数据开发平台中支持开发者提交 Spark Jar 包任务或Spar…