1、WEB与HTTP
浏览器 开发者工具
web服务器都是基于http协议的;
服务器 接受请求-- 发送响应
http版本
1991发布第一个版本:0.9 ,最简单的协议,只有get
1996发布了1.0版本,引入了post、head命令;
1997发布了1.1版本,引入了持久连接;
2015发布了2.0版本, 引入了(多路复用,帧,流) – 快;
目前为止1.1还是主流版本;
web应用处理流程
1、浏览器发送http请求
2、服务器收到请求,生成一个html文档
3、服务器把html文档作为http响应body数据发送给浏览器
4、浏览器收到http响应,从http body取出html 文档并显示
2、WSGI
wsgi
web server gateway interface
解释1: 是python语言定义的web服务器和程序框架之间一种简单而通用的接口规范;
解释2:wsgi 是一个协议,实现常见的web服务器和我们自己使用flask框架写的web服务器之间交流通信,wsgi是一套规范,可以这样理解
gunicorn / uwsgi
gunicorn 和 uwsgi 都是python的web服务器,跟nginx平级
有专门的python web 服务器来帮你处理原始的tcp连接,http原始请求和响应
底层的代码有专门的服务器实现
gunicorn 的规范:wusgi,gunicorn 处理请求响应的
flask也遵循wusgi规范
3、Flask
Flask基于jinja模块和werkzeug WSGI套件开发的
特性:“微框架”,很轻
Flask比较灵活 自由 可扩展性强。Flask入门简单Flask非常适合api(应用程序接口)开发
django VS flask
使用django就不用写前端, 本身集成了很多模块;
flask全部自己定制,比较灵活自由,可扩展性强,非常适合api开发。同时学习难度大一点django是比较重量级的框架,会自动配好东西,但是得按照它的来(甚至于前端都有大体框架不需要自己编写前端了)Django很多写好了,但是定制自己想要功能很麻烦,太冗余了,容易出错,但是操作很方便,
flask可以定制自己想要的功能,很灵活,
Django可以渲染模板,前端省的写组装的台式机(Flask)跟笔记本电脑
(Django)的区别Django饭喂到嘴边
flask从买菜开始自己做
Python常见的web框架:Tornado,flask,twisted,django(用的比较多的是flask和django)
前端:能看到的页面内容 跟用户交互的
浏览器的架构是B(brower浏览器)/S(server服务器)架构:用浏览器带动页面展示 为了方便 我们一般前后端分离:
api 应用程序接口
前端的代码运行在前端的服务器上;
后端的代码运行咋后端的服务器上;
3.1 创建虚拟环境
我们这个项目主要是应用的前后端分离 。
pip和pip3无区别 path只是其中一个环境变量 有很多环境变量 。
虚拟环境:虚拟环境一个项目一个房间保持项目的环境纯净 互不影响
创建一个新的虚拟环境:
在项目代码文件(cjh-flask)平级目录创建虚拟环境(myenv)
# 在命令行进入你的python项目文件夹,输入命令
python -m venv myenv
# 我们用的是系统的pip,以后需要用虚拟环境的pip和python3.加载虚拟环境每次进入虚拟环境都要输入这条命令 才能使用pip和python
# 加载你的虚拟环境,输入命令
source myenv/Scripts/activate
# 在linux系统
# source myenv/bin/activate
虚拟环境作用?
项目环境隔离,保持项目纯净;
HJ@DESKTOP-FS410H1 MINGW64 /e/桌面/myenv/Scripts
$ ll # 里面包含了虚拟环境的pip和python
total 1509
-rw-r--r-- 1 HJ 197121 20372 Jan 19 16:11 Activate.ps1
-rw-r--r-- 1 HJ 197121 1961 Jan 19 16:11 activate
-rw-r--r-- 1 HJ 197121 953 Jan 19 16:11 activate.bat
-rw-r--r-- 1 HJ 197121 368 Jan 19 16:11 deactivate.bat
-rwxr-xr-x 1 HJ 197121 106345 Jan 19 16:11 pip.exe*
-rwxr-xr-x 1 HJ 197121 106345 Jan 19 16:11 pip3.9.exe*
-rwxr-xr-x 1 HJ 197121 106345 Jan 19 16:11 pip3.exe*
-rwxr-xr-x 1 HJ 197121 597904 Jan 19 16:11 python.exe*
-rwxr-xr-x 1 HJ 197121 597392 Jan 19 16:11 pythonw.exe*
HJ@DESKTOP-FS410H1 MINGW64 /e/桌面
$ source myenv/Scripts/activate
(myenv) # 表示已经进入虚拟环境
HJ@DESKTOP-FS410H1 MINGW64 /e/桌面
$ pip -V
pip 21.2.4 from E:\▒▒▒▒\myenv\lib\site-packages\pip (python 3.9)
(myenv)
HJ@DESKTOP-FS410H1 MINGW64 /e/桌面
$ which pip
/e/桌面/\桌面\myenv/Scripts/pip
(myenv)
windows里面Script里面放脚本
PS E:\桌面\cjh-flask> pip freeze # 显示这个程序安装过的库和版本
click==8.0.3
colorama==0.4.4
Flask==2.0.2
itsdangerous==2.0.1
Jinja2==3.0.3
MarkupSafe==2.0.1
Werkzeug==2.0.2
pip freeze >requirements.txt
#将当前虚拟环境安装的东西写入到requirements.txt文件,
#一般存当前项目正常运行需要安装的哪些库,以及对应的版本库
#这样项目迁移的时候,直接按照requirements.txt文件里指定的版本和库安装就行。
#传入Linux后,在新的环境执行
pip3 install -r requirements.txt
#按照requirements.txt文件进行安装:当我们项目移动到一个新的环境的时候 就可以直接安装这个依赖文件里面的东西
#没有虚拟环境,生成的这个requirements.txt里面会有很多无用的包
3.2 创建第一个flask项目
flask本身自带一个小型的web服务器,在开发环境里使用,生产环境建议使用gunicorn或者uwsgi
监听5000端口
from flask import Flask
# 作为主程序 __name__== “__main__”
# 实例化对象,需要给一个字符串,通常用__name__ 的值
# 这个名字将作为flask核心对象的标识
app = Flask(__name__)
app.run()
# flusk自带一个小型的web服务器,这只是用在测试开发环境,不要用在生产环境
启动结果:
* Serving Flask app 'web开发' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
警告:这是一个开发服务器。 不要在生产部署中使用它
Use a production WSGI server instead.
使用一个生产WSGI服务器代替
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
服务帮转到127.0.0.1:5000
# 添加功能
@app.route("/index/")
def index1():
return '{"key1":1,"key2":2}'
# 添加功能2
#@app.route("/")
def index2():
return "hello world"
app.add_url_rule("/", view_func=index2) # 功能类似于@app.route("/")
app.run()
我们输入127.0.0.1:5000默认访问的是根(/)
127.0.0.1 - - [19/Jan/2022 17:10:25]“GET / HTTP/1.1” 404 – http://127.0.0.1:5000/index/
这个就相当于写了一个接口,接口一般会返回json格式的字符串,这个返回的是一个字典一样的json接口 也可以不用装饰器为它添加路由,下面可以达到一样的效果
def index2(): return “gogogo"app.add_url_rule(”/",view_func=index2) app.add_url_rule():
在flask内部,每个核心对象都会维护两张表 一张为url_map 一张为view_functionsurl_map:维护的是url和endpoint的映射关系view_functions:维护的是endpoint和function的映射关系
3.3 debug
调试模式:会自动加载新的配置,不需要重启服务;生产环境不使用
3.4 endpoint
endpoint就是把url和function解耦的中间层endpoint在view_function表需要全局唯一(也就是对应唯一一个function),函数名可以重复
路由查找原理
在flask内部,每个核心对象(add)都会维护俩张表;
url_map: 维护的是url和endpoint的映射关系
view_functions: 维护的是endpoint和function的映射关系
endpoint将url和function解耦
endpoint没有明显的定义的话,默认使用函数名作为
相同的endpoint 对应不同的函数,会报错
endpoint在view_functions表全局唯一,函数名可以重复(多对一),相当于view_functions表里面只有一行
app.run(debug=True, host="192.168.2.111", port=8000)
# 设置成debug调试模式,代码修改不需要重启应用,它回重新加载
# 127.0.0.0 本地回环地址,代表本机
# 端口找服务,ip地址找主机
# 对外发布访问的时候,要自己设置ip和端口号
127.0.0.1
localhost等于127.0.0.1,不过localhost是域名,127.0.0.1是IP地址;
localhost和127.0.0.1不需要联网,都是本机访问;
本机IP需要联网,本机IP是本机或外部访问, 本机 IP 就是本机对外放开访问的IP地址,这个网址就是与物理网卡绑定的IP地址;
3.5 目录结构
config
config.setting.py
DEBUG = True
HOST = "192.168.2.111"
PORT = 8000
router
router.view01.py
# from server import app
# flask自带的一个内置函数 current_app
# 只要执行都会返回当前的app对象
from flask import current_app
app = current_app
# 添加功能
@app.route("/index/")
def index1():
return '{"key1":1,"key2":2}'
# 添加功能2
# @app.route("/")
def index2():
return "hejin,hello world"
app.add_url_rule("/", endpoint="index", view_func=index2) # 功能类似于@app.route("/")
app.add_url_rule("/home", endpoint="index", view_func=index2)
app.add_url_rule("/index1", endpoint="index", view_func=index2)
server.py
一开始
拆分后
import app
app = app.create_app() # 创建核心对象
# 将上下文推到内存里面去(栈空间)
# ctx = app.app_context()
# ctx.push()
# from router import view01
# from router import study
app.run(debug=app.config["DEBUG"], host=app.config["HOST"], port=app.config["PORT"])
3.6 配置文件的读取方式
通过导入模块访问配置文件
from config import settings
app.run(debug=settings.DEBUG, host=settings.HOST, port=settings.PORT)
通过调用app.config 字典去访问配置文件
app.config.from_object('config.settings')
print(app.config)
app.run(debug=app.config.DEBUG, host=app.config.HOST, port=app.config.PORT)
从系统的环境变量里面读取配置
# 加载系统环境配置
# 生产环境那就加载生产环境配置
# 测试环境那就加载测试环境配置
if 'FLASK_CONF' in os.environ:
app.config.from_envvar('FLASK_CONF')
import os
from flask import Flask
def create_app(config=None):
app = Flask(__name__)
# 加载配置文件里的内容,到app.config里
app.config.from_object('config.settings')
# 加载系统环境配置
# 生产环境那就加载生产环境配置
# 测试环境那就加载测试环境配置
if 'FLASK_CONF' in os.environ:
app.config.from_envvar('FLASK_CONF')
# 加载特殊配置
if config:
if isinstance(config, dict):
app.config.update(config) #将讲获取到的配置更新到app.config字典里面去
elif config.endswith(".py"):
app.config.from_pyfile(config)
return app
导入app.py模块,产生一个app对象
import app
app = app.create_app()
从导入create_app,产生一个app对象
from app import create_app
app1 = create_app()
3.7 蓝图blue print
让路由管理更加模块化
蓝图的原理:自动帮你修改endpoint,自动加前缀
通过蓝图之后,创建的study_bp 获得的endpoint是url_prefix+fun名字
定义蓝图
router/study.py
from flask import Blueprint
# 创建了蓝图
study_bp = Blueprint("study", __name__,url_prefix="/study")
# 路由绑定到蓝图上面了
@study_bp.route("/index")
def index():
return "study index"
@study_bp.route("/english")
def english():
return "study english"
蓝图注册到app上
修改app.py
# 加载特殊配置
if config:
if isinstance(config, dict):
app.config.update(config) # 将讲获取到的配置更新到app.config字典里面去
elif config.endswith(".py"):
app.config.from_pyfile(config)
# 导入router里的__init__.py,里面定义了注册蓝图
import router # 都会执行,执行study.py
router.init_app(app) # 调用注册蓝图
return app
运行server.py