Flask-0-最小原型
Posted jiangmingbai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask-0-最小原型相关的知识,希望对你有一定的参考价值。
一、从selenium的原理讲起
selenium操作游览器是需要webderiver驱动的,这个驱动其实就可以理解为服务应用(application),selenium只是通过HTTP协议向webdriver发送请求,webdriver接收到请求后,在去驱动游览器做一些列的操作。
我们打开双击运行webdriver.exe,然后通过游览器访问本地localhost:port,是可以访问通的。其实webdriver此时就开启了一个web服务
而我们运行falsk或者django也是开启一个服务。和webdriver其实是大同小异的。
from selenium import webdriver
import requests
import time
url = "http://www.baidu.com"
driver = webdriver.Chrome(port=7005)
# driver.get(url)
"""
get方法做了哪些事情,游览器是怎么打开了百度呢?
通过源码可以看到执行了一个Command.GET,参数是我们传的url
1、self.execute(Command.GET, {‘url‘: url})
Command.GET: 就是以POST的方式向webdriver发起请求
Command.GET:(‘POST‘, ‘/session/$sessionId/url‘) 请求方法POST和地址localhost:7005
{‘url‘: url}: 参数
"""
# 利用http协议与webdriver交互,实现驱动游览器访问百度
requests.post(url=f"http://localhost:7005/session/{driver.session_id}/url", json={‘url‘: url})
time.sleep(2)
driver.close()
driver.quit()
二、make_server实现简易的基于WSGI服务的server
本次分享先抛开falsk,用python内置的wsgiref库实现的一个简易服务器。其实flask内置的服务原理也是这一套东西,这些都是本地我们本地调试时,开启的服务,实际生产环境我需要用uwsgi,ngnix等。
1、最小简易服务器实现步骤
- 创建一个WSGI服务器:make_server(host,port,app)
- 处理程序app方法实现:app(env,start_response)构造url 响应对象
- 运行服务器:serve_forever() 监听动作
2、make_server(host,port,app)
- host:ip地址,传空字符串默认localhost
- port:端口
- app:应用程序(application),需要定义url,构造响应对象,定义返回值。
- env:app 与服务器如何通信的呢,其实就是通过环境变量environment,前端传输信息都会保存在里面
- start_response: 响应对象,定义接口响应状态码,定义响应头信息
- return:返回值到前端
3、案例:可以通游览器访问调试
from wsgiref.simple_server import make_server
def app(env, start_response):
"""
application 应用程序
:param env: 环境变量
:param start_response: 响应结果,需要构造
:return:
"""
# 定义首页,url从边境变量里取,字段:PATH_INFO
if env.get("PATH_INFO") == "/":
# 构造响应对象
start_response("200 ok", [("content-type", "text/plain")])
return [b"hello index page"]
elif env.get("PATH_INFO") == "/home":
start_response("200 ok", [("content-type", "text/plain")])
return [b"hello home page"]
else:
start_response("404 not found", [("content-type", "text/plain")])
return [b"not found page"]
if __name__ == ‘__main__‘:
# 创建server
server = make_server(‘‘, 8005, app)
# 永久开启
server.serve_forever()
4、注意:
1、 status_code 必须是一个字符串,不能是200的数字,且要4位以上
2、header 是一个元素构成的列表,不能字典
3、返回值是一个列表且要是byte类型,encode
5、如何确认服务器-application交互是通过环境变量的传输信息的
我们只要断点debug调试即可,或者打印env查看
- 包括本地环境变量信息
- 包括前端请求服务器的数据都会保存环境里
- ip、port、接口地址、host
- 请求方法
- 请求参数
- 请求头
- 以及本地配置的环境变量信息
‘REMOTE_HOST‘ = {str} ‘‘
‘CONTENT_LENGTH‘ = {str} ‘‘
‘SCRIPT_NAME‘ = {str} ‘‘
‘SERVER_PROTOCOL‘ = {str} ‘HTTP/1.1‘
‘SERVER_SOFTWARE‘ = {str} ‘WSGIServer/0.2‘
‘REQUEST_METHOD‘ = {str} ‘GET‘
‘PATH_INFO‘ = {str} ‘/home‘
‘QUERY_STRING‘ = {str} ‘‘
‘REMOTE_ADDR‘ = {str} ‘127.0.0.1‘
‘CONTENT_TYPE‘ = {str} ‘text/plain‘
‘HTTP_HOST‘ = {str} ‘localhost:8005‘
‘HTTP_CONNECTION‘ = {str} ‘keep-alive‘
‘HTTP_PRAGMA‘ = {str} ‘no-cache‘
‘HTTP_CACHE_CONTROL‘ = {str} ‘no-cache‘
‘SERVER_PORT‘ = {str} ‘8005‘
三、application优化
当我们访问地址越来越多时,我们需要不断添加if,来判断,其他语言有switch语句,其实python有更强大的字典对象,以用映射的方法来处理,把url定义成key,
响应对象单独写成方法,value就时方法名。
此时,我们的app方法内,只需要url是不是在字典内,如果存在我们只需要调用对应的value,并返回值即可,如果不存在则直接返回定义的404的方法即可。
这样就实现了集中管理,当我们在有新的url时,我们app方法内的逻辑是不需要维护的,我们只需要添加新url方法(构造响应结果,返回值),然后添加到字典内即可。
而url和函数(构造响应对象、并返回值)组合起来就叫做路由
其实flask中也有集中注册路由的机制,内部原理也时采用的这种映射原理,只不过flask准对中小型来说实现了更为方便装饰器,只需要把url通过装饰在视图函数上即可
优化代码
from wsgiref.simple_server import make_server
# 函数实现
def home(response):
response("200 OK", [("content-type", "text/html")])
return "<p style=‘color:red‘>home</p>"
def project(response):
response("200 OK", [("content-type", "text/html")])
return "<p style=‘color:red‘>project</p>"
def interface(response):
response("200 OK", [("content-type", "text/html")])
return "<p style=‘color:red‘>interface</p>"
def not_found(response):
response("404 not found", [("content-type", "text/plain"), ("charset", "UTF-8")])
return "page not found"
# 建立映射关系
route_path = {
"/": home,
"/project": project,
"/project/interface": interface
}
def app(env, response):
"""
application 应用程序,通过映射,app基本可以保持不变
:param env: 环境变量
:param response: 响应结果函数,需要构造
:return:
"""
url = env.get("PATH_INFO")
# 先判断不存在
if url is None or route_path.get(url) is None:
# 直接调用not_found()方法,返回404
return [not_found(response).encode()]
# 存在,调用对应url key的函数被返回
return [route_path.get(url)(response).encode()]
if __name__ == ‘__main__‘:
my_server = make_server(‘‘, 6005, app)
my_server.serve_forever()
四、总结
1、app应用程序和服务器通信是通过环境变量
2、app内必须需要构造响应对象
3、 status_code 必须是一个字符串,不能是200的数字,且要4位以上
4、header 是一个元素构成的列表,不能字典
5、返回值是一个列表且要是byte类型,encode
6、可以使用字典的方式保存映射关系,达到更好管理路由。
以上是关于Flask-0-最小原型的主要内容,如果未能解决你的问题,请参考以下文章