# Werkzeug 讲解

Werkzeug 为WSGi应用程序开发提供了一些实用工具,要了解Werkzeug提供了什么,我们可以从开发一个WSGI程序入手

import werkzeug
def wsgi_app(environ,start_response):
    headers = [('Content-Type','text/plain'),('charset','utf-8')]
    start_response('200 OK',headers)
    yield "Hello world"

client = werkzeug.Client(wsgi_app,response_wrapper=werkzeug.Response)
resp = client.get("?answer")
print(resp,type(resp))  # <Response streamed [200 OK]> <class 'werkzeug.wrappers.response.Response'>
print(resp.content_type)   # text/plain
print(resp.data.decode('utf-8'))  #Hello world

=======================================================
#上面我们通过定义函数,再将函数注册到Client类中,该类用来做一次性测试,效果和下面的是一样的,只不过下面的已经我们设置到了
response_app = werkzeug.Response("hello world")
print(response_app)   #<Response 11 bytes [200 OK]>
client = werkzeug.Client(response_app,response_wrapper=werkzeug.Response)
resp = client.get("?answer") 
print(resp.data.decode('utf-8'))  #Hello world

除了上面的方式可以传入所有参数,还可以通过装饰器,传递request参数

import werkzeug

@werkzeug.Request.application
def wsgi_app_using_request(request):
    msg = "A WSGI app with: \n method:{}\n path:{}\n"
    return werkzeug.Response(
        msg.format(request.method,request.path)
    )

client = werkzeug.Client(wsgi_app_using_request,response_wrapper=werkzeug.Response)

resp = client.get('answer')
print(resp.data.decode())

#结果:
A WSGI app with: 
 method:GET
 path:/answer

重点部分:路由

import werkzeug
from werkzeug.routing import Map, Rule

url_map = Map(
    [
        Rule('/',endpoint="index"),
        Rule('/<any("Robin","Galahad","Arthur"):person>',endpoint="ask"),
        Rule('/<other>',endpoint='other')
    ]
)

# 无法匹配
env = werkzeug.create_environ(path='/shouldnt/match')
# 匹配到other
env = werkzeug.create_environ(path='/shouldnt')  #('other', {'other': 'shouldnt'})
# 匹配到名字
env = werkzeug.create_environ(path='/Robin?favorite=red')  #('ask', {'person': 'Robin'})
urls = url_map.bind_to_environ(env)
print(urls.match())

通过上面的代码我们呢可以知道,werkzeug可以通过url,提取参数,所以我们可以添加逻辑


import werkzeug
from werkzeug.routing import Map, Rule

url_map = Map(
    [
        Rule('/',endpoint="index"),
        Rule('/<any("Robin","Galahad","Arthur"):person>',endpoint="ask"),
        Rule('/<other>',endpoint='other')
    ]
)

@werkzeug.Request.application
def send_to_endpoint(request):
    urls = url_map.bind_to_environ(request)
    try:
        endpoint, kwargs = urls.match()
        if endpoint == 'index':
            response = werkzeug.Response('You got the index')

        elif endpoint == 'ask':
            questions = dict(
                Galahad = 'what is your favorite color?',
                Robin = "what is the capital of China?",
                Arthur = "what is your name?"
            )

            response = werkzeug.Response(questions[kwargs['person']])
        else:
            response = werkzeug.Response('Other:{other}'.format(**kwargs))
    except (KeyboardInterrupt,SystemExit):
        raise
    except:
        response = werkzeug.Response(
            "FUCK"
        )
    return response

client = werkzeug.Client(send_to_endpoint,response_wrapper=werkzeug.Response)
print(client.get("/").data.decode())  #You got the index

print(client.get("Arthur").data.decode()) #what is your name?