18

你能提供一个WSGI start_response函数的真实例子吗?(Web 服务器向 wsgi 应用程序提供该功能)

我无法理解引入start_response.

(我读过大约 10 篇关于 WSGI 标准的相同文本。他们都说“WSGI 标准是……”他们都没有说“WSGI 是这样设计……”:()

4

3 回答 3

14

start_response()你能提供一个 WSGI函数的真实例子吗?

好吧,start_response()函数的mod_wsgi定义在第 2678 行mod_wgsi.c

他们都没有说“WSGI 是这样设计的……”

WSGI 在PEP3333. 浏览web-sig 邮件列表档案,我发现了这条消息......

前段时间我反对从下一个版本的 WSGI 中删除 start_response 函数的决定,理由是没有 start_callable,异步扩展是不可能支持的。

现在我发现删除 start_response 也将无法支持协程(或者,至少,一些协程的使用)。

[...]

...这开始了一个关于这部分实现的基本原理的长线程,可能值得一读。

如果您真的想知道 WSGI 接口这一方面的起源,您将不得不阅读2003 年 12 月的初稿和2004年 8 月的后期草案之间的大量消息。


更新

那将如何与其他协议兼容?

我不太清楚你的意思。忽略所有的早期草案,WSGI 1.x 接口可以以两种不同的方式使用。

“不推荐使用”的方法是......

def application(environ, start_response):
    write = start_response(status, headers)
    write('content block 1')
    write('content block 2')
    write('content block 3')
    return None

...而“推荐”的方法是...

def application(environ, start_response):
    start_response(status, headers)
    return ['content block 1',
            'content block 2',
            'content block 3']

据推测,您可以同时使用两者,...

def application(environ, start_response):
    write = start_response(status, headers)
    write('content block 1')
    return ['content block 2',
            'content block 3']

...但由此产生的行为可能是未定义的。

这篇博文看来,正在考虑的新 WSGI 2.x 方法是……

def application(environ):
    return (status,
            headers,
            ['content block 1',
             'content block 2',
             'content block 3'])

...这消除了start_response()可调用的,显然,write()可调用的,但没有迹象表明何时(或什至)这可能会取代 WSGI 1.x。

于 2013-05-27T14:53:26.917 回答
3

我发现一个旧线程可以解释原因。

为什么有一个 start_response 然后一个单独的返回?

一个原因是它允许您将应用程序编写为生成器。但更重要的是,为了支持 'write()' 以向后兼容现有框架是必要的,而这几乎就是它的结构的“杀手锏”。不过,这项特殊的创新是 Tony Lownds 的创意,不是我的。在我最初的 WSGI 概念中,应用程序接收到一个输出流,然后只向它写入标头和所有内容。

于 2015-06-19T02:32:28.503 回答
1

TLDR:

它只是为了向后兼容某些现有框架。WSGI 建议使用新框架以避免使用它。

稍长版本:

官方Python WSGI 标准页面的这一部分提到:

write() 可调用对象由 start_response() 可调用对象返回。

...

一些现有的应用程序框架 API 以不同于 WSGI 的方式支持无缓冲输出。具体来说,它们提供“写入”函数或某种方法来写入无缓冲的数据块,或者它们提供缓冲的“写入”函数和“刷新”机制来刷新缓冲区。

不幸的是,除非使用线程或其他特殊机制,否则此类 API 无法根据 WSGI 的“可迭代”应用程序返回值来实现。

因此,为了允许这些框架继续使用命令式 API,WSGI 包含一个特殊的 write() 可调用函数,由 start_response 可调用函数返回。

如果可以避免这样做,新的 WSGI 应用程序和框架不应该使用 write() 可调用函数。write() 可调用严格来说是一种支持命令式流 API 的 hack

整篇文章完美地回答了编写服务器和框架的 WSGI 标准,对任何从 python 后端 Web 开发开始的初学者都有帮助。

于 2021-05-08T20:12:55.053 回答