【问题标题】:I cannot reach a URL with flask calling pandoc (ResponseTimeOut error)我无法使用烧瓶调用 pandoc 访问 URL(ResponseTimeOut 错误)
【发布时间】:2017-01-09 19:35:52
【问题描述】:

只需在烧瓶中返回一些(降价)字符串:

@app.route("/raw/", methods=['GET'])
def sometext():
    return "This is an **example**"

## Main procedure
if __name__ == "__main__":
    app.run(debug=True, port=8000) 

如果您直接调用 pandoc (pandoc http://localhost:8000/raw) 或使用subprocess,则没有问题:

import subprocess, os

url = "http://localhost:8000/raw"
pbody = subprocess.run(["pandoc", url], check=True, stdout=subprocess.PIPE)
print(pbody.stdout.decode())

但是如果你在flask方法中调用pandoc:

@app.route("/get", methods=['GET'])
def index():
    url = "{}".format(url_for('sometext', _external=True))
    pbody = subprocess.run(["pandoc", url], check=True, stdout=subprocess.PIPE, universal_newlines=True)
    print("***Error: ", pbody.stderr)
    return pbody.stdout

然后,当您访问 http://localhost:8000/get 时,您会收到 pandoc 的 Responsetimeout 错误:

pandoc: HttpExceptionRequest Request {
  host                 = "localhost"
  port                 = 8000
  secure               = False
  requestHeaders       = []
  path                 = "/raw/"
  queryString          = ""
  method               = "GET"
  proxy                = Nothing
  rawBody              = False
  redirectCount        = 10
  responseTimeout      = ResponseTimeoutDefault
  requestVersion       = HTTP/1.1
}
 ResponseTimeout

参考:url_for in flask API

【问题讨论】:

    标签: python flask subprocess pandoc


    【解决方案1】:

    我记得 Flask http 服务器是单线程的,因此它在处理“/get”请求时无法处理“/raw”请求。

    Answer to another SO question 建议使用app.run(threaded=True),这可能足以供个人使用。对于生产用途,您应该考虑使用真正的 Web 服务器,例如 nginx 或 apache。

    即便如此,假设 pandoc 支持它(我不知道),您可能需要考虑将 markdown 输入发送到 pandoc 标准输入并完全避免额外的 HTTP 请求,例如(未经测试)

    markdown = StringIO("This is an **example**")
    pbody = subprocess.run(["pandoc"], check=True, stdin=markdown, stdout=subprocess.PIPE, universal_newlines=True)
    

    【讨论】:

    • 或者创建一个真正的 WSGI 应用程序。喜欢here
    • stringIO 不起作用 (python3)。使用io 库我得到io.UnsupportedOperation: filenomarkdown = io.StringIO("This is an **example**")。有人知道如何在python3的子进程中使用stdin吗?
    • 它必须与 stringIO 一起使用,因为在 bash 中你可以调用 echo 'some text' | pandoc - 工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    相关资源
    最近更新 更多