更改流式响应的状态代码

时间:2015-04-14 14:34:59

标签: python http flask

我有这个小的Flask视图,它从正在运行的pg_dump命令中流出数据。只要我没有在启动过程中发生任何错误,就可以完美运行。有没有什么方法可以延迟设置HTTP状态代码,直到生成器函数pg_dump_yielder的第一次收益发生?至少可以处理初始错误。

import errno
import os
import fcntl
import subprocess as subp
from flask import Flask, Response, abort

app = Flask(__name__)
cmd = ['pg_dump', '--format=c', '--no-owner', '--no-privileges', '--no-acl',
       '--username=postgres', 'mywebsite_db']


def make_fd_async(fd):
    """Helper function to add the O_NONBLOCK flag to a fd"""
    fcntl.fcntl(fd, fcntl.F_SETFL,
                fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)


def read_async(fd):
    """Helper function to read some data from a fd, ignoring EAGAIN errors"""
    try:
        return fd.read()
    except IOError as exc:
        if exc.errno == errno.EAGAIN:
            return b''
        else:
            raise exc


@app.route('/')
def pg_dump_view():
    proc = subp.Popen(cmd, stdout=subp.PIPE, stderr=subp.PIPE)
    make_fd_async(proc.stdout)
    make_fd_async(proc.stderr)

    def pg_dump_yielder():
        stderr_data = b''
        while True:
            stdout_data = read_async(proc.stdout)
            new_stderr_data = read_async(proc.stderr)
            if new_stderr_data:
                stderr_data += new_stderr_data
                continue
            if stderr_data:
                abort(500, stderr_data.decode())
            if stdout_data:
                yield stdout_data

            return_code = proc.poll()
            if return_code is not None:
                return abort(500, "Exited with: {}".format(return_code))

    return Response(pg_dump_yielder(), mimetype='application/octet-stream')

app.run(debug=True)

0 个答案:

没有答案