【问题标题】:WSGI: what's the purpose of start_response functionWSGI:start_response 函数的目的是什么
【发布时间】:2013-05-22 09:57:43
【问题描述】:

你能提供一个WSGIstart_response函数的真实例子吗? (Web-server 为 wsgi 应用程序提供该功能)

我不明白介绍start_response目的

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

【问题讨论】:

    标签: python web-services web-applications wsgi middleware


    【解决方案1】:

    您能否提供一个真实的 WSGI start_response() 函数示例?

    好吧,mod_wsgistart_response() 函数是在 line 2678 of mod_wgsi.c 上定义的

    没有人说“WSGI 是这样设计的……”

    PEP3333 中似乎没有太多理由说明 WSGI 设计的这一方面。翻看web-sig mailing list archives,我遇到了this message...

    前段时间我反对删除 start_response 的决定 来自下一个版本 WSGI 的函数,使用以下事实作为基本原理 没有 start_callable,异步扩展是不可能的 支持。

    现在我发现删除 start_response 也会使 不可能支持协程(或者,至少,一些协程 用法)。

    [...]

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

    如果您真的想知道 WSGI 接口这方面的起源,您将不得不阅读 2003 年 12 月的 this initial draft 和 2004 年 8 月的 this later draft 之间的大量消息。


    更新

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

    我不太清楚你的意思。忽略所有的早期草案,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']
    

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

    this blog post 看来,正在考虑的新 WSGI 2.x 方法是...

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

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

    【讨论】:

    • 请不要让异步支持者混淆 start_response() 的含义。主要原因之一是允许服务器返回可调用的 write() 以支持现有的 Python Web 应用程序,这些应用程序过去能够调用 write() 函数来生成内容。这使它们免于被重写以返回可迭代对象。
    • @GrahamDumpleton 好吧,鉴于我没有参与设计过程,也不会费心阅读 web-sig 存档中的每条消息,我真的只能推测。但是,似乎我链接到的最初草案(它建议使用函数def runCGI(input,output,errors,environ))也会通过output.write() 提供这样的可调用对象。看起来更像是有人反对 Web 应用程序必须手动编写 HTTP/1.1 200 OK 行和响应标头本身。
    • 我也不在那里,你挖出了我以前从未读过的东西。 runCGI 版本在它被更改为返回一个可迭代对象之前就已经存在,因此输出完全是通过 write() 的方式。那时他们本可以放弃 write(),这正是 WSGI 2+ 解决方案最终提出的。在不需要 write() 的 WSGI 2+ 中, start_response() 也消失了。不再需要挂在 write() 上,因为依赖于能够执行 write() 的非常古老的应用程序不再存在或已被重写为现在返回一个可迭代的响应。
    • @GrahamDumpleton, @Aya 首先,感谢你们提供有用的链接和可读的解释。奇怪的是,链接页面中没有示例说明应用程序如何使用返回的write 函数。一个应用程序是否应该与 WSGI 和其他网关协议兼容,是否应该按如下方式使用它:write = start_response(status,headers); write(data)?
    • @GrahamDumpleton, @Aya 那如何与其他协议兼容?我想,隐含的其他协议只会将应用程序称为application(environ, start_response=gateway_write),将其自定义gateway_write 函数提供给应用程序的输入?那么应用程序应该直接调用start_response(data)而不是write = start_response(status,headers); write(data)并且WSGI与其他协议不兼容?
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      TLDR:

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

      略长的版本:

      官方Python WSGI Standards Page这一段提到:

      write() callable 由 start_response() callable 返回。

      ...

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

      不幸的是,这样的 API 不能用 WSGI 的方式实现 “可迭代”应用程序返回值,除非线程或其他特殊 使用机制。

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

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

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

      【讨论】:

        猜你喜欢
        • 2017-02-10
        • 2012-01-14
        • 2012-06-08
        • 1970-01-01
        • 2021-06-09
        • 2014-01-19
        • 2018-04-24
        • 2020-01-24
        相关资源
        最近更新 更多