我最近试图了解什么是WSGI应用程序:
WSGI应用程序只是一个可调用的对象,它被传递给环境-一个包含请求数据的dict,以及一个被调用以开始发送响应的start_response函数。
为了将数据发送到服务器,您所要做的就是调用start_response并返回一个可迭代的。
因此,这里有一个简单的应用程序:
def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return ['Hello World!']
Djangos wsgi.py是
"""
WSGI config for basic_django project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'basic_django.settings')
application = get_wsgi_application()
但是当我看到wsgi.py时,application = get_wsgi_application()
可调用的函数不会通过environ
或start_response
函数
那么如何理解这个
您看不到传递给application
的内容——这是WSGI容器的工作,而不是您的工作。您的方法是将application
定义为可以传递这两个参数的东西。
有多种方法可以使可调用。最简单的是一个函数:
def add5(x):
return x + 5
另一个是匿名函数,或者lambda:
add5 = lambda x: x + 5
还有一个是具有__call__
方法的类的对象:
class AdderOf5:
def __call__(self, x):
return x + 5
add5 = AdderOf5()
您可以将其中任何一个封装到一个函数中,该函数返回一个可调用的:
def make_add_y(y):
def add_y(x):
return x + y
return add_y
add5 = make_add_y(5)
或
def make_add_y(y):
return lambda x: x + y
add5 = make_add_y(5)
第三个选项并不需要包装器,因为类已经是一个工厂:
class AdderOfY:
def __init__(self, y):
self.y = y
def __call__(self, x):
return x + self.y
add5 = AdderOfY(5)
我想我们甚至可以制作一个函数,构造一个可调用的对象并将其返回给我们:
class AdderOfY:
def __init__(self, y):
self.y = y
def __call__(self, x):
return x + self.y
def make_adder(y):
return AdderOfY(5)
add5 = make_adder(5)
所有这些都展示了如何定义可调用。如何调用是一段不同的代码,无论以何种方式定义可调用,它看起来都是一样的:
eight = add5(3)
无论我们以何种方式构建add5
,您都可以尝试验证这条线是否有效。
返回WSGI:您提供的示例创建了一个接受两个参数的简单函数。
Django的get_wsgi_application
函数是一个包装器,它返回一个相同形式的可调用函数:一个可以给定环境并启动响应的函数。
如果你想看看它是如何定义的,下面是它的样子:
get_wsgi_application
:
def get_wsgi_application():
# ...
return WSGIHandler()
WSGIHandler
:
class WSGIHandler(base.BaseHandler):
# ...
def __call__(self, environ, start_response):
# ...
您可以注意到,它看起来几乎与我的上一个示例完全相同:一个构造可调用对象的函数。可调用对象可以使用两个参数调用:environ
和start_response
。
在调用端,在代码中不是,而是在WSGI容器中(如Apache的mod_wsgi
或gUnicorn…(,无论您使用简单的函数(如第一个示例中(还是可调用对象(如Django中(,它都是这样的:
response = application(environ, start_response)