Package: fast-server
[toc]fast-server1.安装pip install fast-serverversion=0.6.02.使用框架启动服务器1、新建一个py文件，输入以下代码：fromfast_serverimportFastdefhello():return"<h1>HelloWorld</h1>"if__name__=='__main__':fast=Fast(server=("0.0.0.0",8084))fast.add_router(hello,'/hello')fast.start()2、启动这个代码，待控制台提示：The module 'controller' has been identified
controller loading completed
------------------------------
reject_list loading completed
------------------------------
'resource' folder scanning completed
resource loading completed
------------------------------
The module 'filter' has been identified
filter loading completed
------------------------------
serve on 0.0.0.0:8084服务器启动成功，端口启动在80893、在浏览器输入http://localhost:8089/hello可以看到结果3.工程结构如下是一个项目的初始结构，如下所示：project
│   main.py
│   setting.json    
│
└───controller
│   │   __init__.py
|   |   ...
|
└───filter
│   │   __init__.py
|   |   ...
|
└───resource
│   │   index.html
|   |   ...
│Controller包中是所有的routerFilter包中是所有的过滤器Main.py为fast.start()所在主函数位置Setting.json配置文件Controller，Filter，Setting.py 这三个文件应该和main.py同级3.1.setting.json{"container":{"controller":["controller"],"filter":["filter"],"resources":["resource"],"reject":[],"allow":["0.0.0.0"]},"server":{"host":"0.0.0.0","port":"8086","workers":"1000","waiters":"0","process":"True"},"log":{"path":"log.txt","max":"1000"}}将上面的数据保存为文件setting.json后你可以使用fromfast_serverimportFastfast=Fast(setting_path="setting.json")来加载配置文件上面的值有几个暂时用不上上面的值都是可选值，可以不指定若不指定。上面给出的也是系统的默认值或者，你不想另外创建一个文件，你可以使用字典：setting_data={"container":{"controller":["controller"],"filter":["filter"],"resources":["resource"],"reject":[]},"server":{"host":"0.0.0.0","port":"8086","workers":"1","waiters":"0","process":"False"},"log":{"path":"log.txt","max":"1000"}}fromfast_serverimportFastfast=Fast(setting_data=setting_data)这些命名可以使用_合并：比如说："server": {"host": "0.0.0.0"}可以写成："server_host":"0.0.0.0"或者你还可以使用fast.setting.server_host="0.0.0.0"3.2.controller3.2.1 @controller() @router()你需要使用@controller来注解类，from fast_server import controller这个注解也只能用在类上。这个注解有一个可选参数value，可以设置router的父路径。在类中的方法要使用@router来注解。from fast_server import router这个注解有一个参数value，用来设置router的子路径。他有一个可选参数method，可以设定请求方式。Controller类中的方法可以有参数，这些参数的参数名需要和请求表单中的参数名一样这些参数可以给定参数类型或者默认值。服务器的派发器在启动对应的业务方法时会按照一定规则，设定传入的实参可以有一个名叫request的参数，这个参数包含了当前请求的所有数据如下是一个controller的使用演示fromfast_serverimportcontroller,router,HttpRequest@controller(value="/user")classTest3(object):@router(value="/login")deftest(self,name,pwd,request:HttpRequest):data={'name':name,'pwd':pwd,'method':request.method}returndata你可以在参数中添加request来获取一个HttpRequest对象这个对象包含了该次请求所需要的所有数据包括请求头，请求体，parameter，form，cookie等你的controller包下应该有一个__init__.py的文件比如你的包下面有一个test.py的模块中有controller方法__init__.py中需要添加from .test import *3.3.filter你需要使用@web_filter来注解过滤器类from fast_server import web_filter他的参数value为路径，priority为优先级， method为针对的请求方式priority越小，这个filter执行的优先级越高，这个值理论上可以无限小也可以无限大优先级相同的filter执行顺序是随机的所有过滤器类都需要继承一个为Filter的抽象类from fast_server import Filter他有两个方法需要实现，分别是before和afterbefore方法有一个request的参数，这个函数需要返回requestafter方法有一个request对象和一个response对象，他需要将这两个参数都返回如图下是一个完整的过滤器fromfast_serverimportweb_filter,Filter,POST@web_filter(value=["/"],priority=0,method=POST)classfilterTest(Filter):defbefore(self,request):print("执行了filter before post")returnrequestdefafter(self,request,response):print("执行了filter after post")returnrequest,response你的filter包下应该有一个__init__.py的文件比如你的包下面有一个test.py的模块中有filter方法__init__.py中需要添加from .test import *3.4.resource你可以创建一个名为resource的文件夹，这个文件夹需要和main.py同级资源文件夹可以有多个，你需要在配置文件的container_resources中配置这些资源文件夹的名字在资源文件夹下的所有资源都会被加载到服务器的router中，你可以按照名字来访问这些资源文件访问时服务器将文件的格式对应的设置content-type资源文件加载时不会检查重复资源，前面加载的资源将会被后面同名的资源覆盖特别的，类似index.html文件可以使用/index.html或者/来访问4 一些函数和类4.1.request重定向你可以通过request.redirect(path)，这个函数可以实现页面的重定向
他有一个参数path就是重定向页面的名字如下是重定向使用的演示fromfast_serverimportcontroller,router,HttpRequest@controller()classTest3(object):@router("/img")defget_img(self,request:HttpRequest):returnrequest.redirect("/img1.jpg")4.2.cookie4.2.1 Cookiefromfast_serverimportcontroller,router,HttpRequest@controller(value="/user")classTest3(object):@router(value="/login")deftest(self,name,pwd,request:HttpRequest):data={'name':name,'pwd':pwd,'method':request.method}foriindata:request.cookie[i]=data[i]returndatacookie本质上是一个字典，你可以使用字典的方式获取值以及设置对应cookie的信息request.cookie.id可以获取cookie的id4.2.2 Session使用request.session获取sessionsession的用法和cookie的用法一样他其实是封装了Cookie你可以设置Session的生命期，它默认会在服务器保存30分钟4.3 替换内置的wsgi应用4.3.1.make_serverfast.start()的完整定义是：fast.start(constructor=make_server)在使用这个函数启动服务器时，你可以使用遵循wsgi协议的make_server作为
参数传递给他，让服务器使用自定义的wsgi应用4.3.2 call方法Fast类实现了__call__方法以官方的wsgi应用为例，make_server有一个参数app，
你可以将fast对象直接作为参数传递给这个app，
也可以实现替换服务器内置的wsgi应用。fromwsgiref.simple_serverimportmake_serverfromfast_serverimportFastfast=Fast()server=make_server("0.0.0.0",8080,fast)server.serve_forever()4.4 reject_list和allow_list4.4.1 reject_list这是一个拦截队列，在配置文件中的"container_reject"中定义，
当服务器遇到拦截队列中的IP地址时，会直接阻止这个请求，并返回一个403你可以这样配置：{"container_reject":["10.10.10.10"]}这样IP地址为10.10.10.10的客户端将无法访问服务器你也可以设置掩码：{"container_reject":["10.10.10.0/24"]}这样10.10.10.0-10.10.10.255这一段ip的客户端都不能访问服务器拦截队列在初始化时会尝试将能聚合的IP地址尽量聚合起来以减少检索时的压力。拦截队列默认为空4.4.2 allow_list用法和reject_list一样，在配置文件的"container_allow"中定义，
他的优先级比reject_list低。如果你在allow_list中配置了10.10.10.10，reject_list在也配置了10.10.10.10，
那么这个IP地址还是会被拒绝访问允许队列默认值为["0.0.0.0"]"0.0.0.0"为允许所有ip访问4.5 @post_router, @get_router这两个注解本质上都是@router@post_router(value)==>@router(value, fast_server.POST)@get_router(value)==>@router(value, fast_server.GET)4.6 HttpRequest, HttpResponse4.6.1 requestrequest对象中封装了本次请求的所有数据，
你可以在方法的参数中添加request，然后就可以在方法中使用这个对象fromfast_serverimportHttpRequestdeftest(name,pwd,request:HttpRequest):pass这个类的定义classHttpRequest:# wsgi的environenviron=None# 请求方法method=None# 客户端地址remote_addr=None# 请求题数据类型content_type=None# 请求地址path=None# 请求体长度content_length=None# 请求体body=None# get请求中url中的请求参数parameter={}# post请求中的表单form={}# 该请求是被禁止prohibit=False# cookiecookie=Nonesession=Noneremote_addr是一个IP对象，你可以使用remote_addr.int()获取ip的地址，remote_addr.version()获取ip地址的版本remote_addr.int()获取ip地址的16进制形式remote_addr.strBin()获取ip地址的二进制形式你可以通过设置prohibit为True，此时这个请求将会被返回403form和prohibit中的数据将会按照请求方式被加载到请求参数中
例如如果是get请求就是prohibit，如果是post请求就是formenviron保存了此次请求的所有数据4.6.1 responseresponse对象会有服务器创建，在函数中使用return返回的数据都会被服务器解析后，
打包为response对象。你可以在方法中自己创建一个response对象，然后设置好响应题的数据，
相应类型等，将response对象最为参数直接返回，服务器会直接使用这个response对象，
而不会自己在打包一个新的。fromfast_serverimportHttpResponsedeftest():data="hello world"response=HttpResponse(data=data,charset='utf-8',status=200)returnresponse4.7 Log日志from fast_server import LogLog().log(info, _type)普通日志，info为日志信息，_type为日志类型，
目前_type支持三种日志类型INFO_LOG = 'info'WARN_LOG = 'warn'ERROR_LOG = 'error'from fast_server import NFO_LOG, WARN_LOG, ERROR_LOGLog().ilog(info)它等于Log().log(info, INFO_LOG)Log().wlog(info)它等于Log().log(info, WARN_LOG)Log().elog(info)它等于Log().log(info, ERROR_LOG)5. 单线程模式，多线程模式，多进程模式5.1.单线程模式设置配置数据中的server_workers==1时，服务器启动在单线程模式下。5.2 多线程模式和多进程模式server_workers是指工作线程的最大数，当设置这个数大于1时，
服务器就会启动在多线程模式下。设置server_process==True可以让服务器进入多进程模式。server_waiters是进程中等待队列的大小，当他为0时，
等待队列理论上无限大。当队列塞满之后，新的请求将会被阻塞。windows下暂不支持使用多进程模式，该模式目前只能运行在linux环境下。
当在windows下尝试进入多进程模式时，服务器会提示异常
然后切换为多线程模式6.可视化界面（该功能还在测试）目前在我们的设计中，我们有三种方式的可视化平台，分别是：控制台格式化显示；python标准ui库tkinter实现的桌面应用；通过浏览器访问的web界面。这三种平台的使用应该有开发者来决定，选择其中的一种或几种，或者关闭不适用，亦或者使用我们定义的接口，由开发人员自己实现一个个性化的监控平台。
这个可视化界面将是我们这个框架的最重要功能之一，我们需要花费一定时间来进行优化升级。