【发布时间】:2014-10-17 11:33:38
【问题描述】:
我正在调试我构建的微控制器,它逐行编写原始 HTTP 请求。我正在使用 Flask 作为我的后端,我希望看到以这种格式显示的整个请求:
GET / HTTP/1.1
Content-length: 123
User-agent: blah
...
我知道 Flask 是基于 WSGI 的。有没有办法让它与 Flask 一起工作?
【问题讨论】:
我正在调试我构建的微控制器,它逐行编写原始 HTTP 请求。我正在使用 Flask 作为我的后端,我希望看到以这种格式显示的整个请求:
GET / HTTP/1.1
Content-length: 123
User-agent: blah
...
我知道 Flask 是基于 WSGI 的。有没有办法让它与 Flask 一起工作?
【问题讨论】:
是的,Flask 是一个 WSGI 应用程序,因此将您的应用程序包装在一个记录请求的额外层中是微不足道的:
import pprint
class LoggingMiddleware(object):
def __init__(self, app):
self._app = app
def __call__(self, env, resp):
errorlog = env['wsgi.errors']
pprint.pprint(('REQUEST', env), stream=errorlog)
def log_response(status, headers, *args):
pprint.pprint(('RESPONSE', status, headers), stream=errorlog)
return resp(status, headers, *args)
return self._app(env, log_response)
这定义了一个中间件来包装您的 Flask 应用程序。优点是它完全独立于 Flask 运行,让您可以未经过滤地了解输入内容和输出内容。
如何应用中间件取决于您使用的确切 WSGI 服务器;请参阅您的 WSGI 服务器文档。
使用内置服务器 (app.run()) 运行 Flask 时,请执行以下操作:
if __name__ == '__main__':
app.wsgi_app = LoggingMiddleware(app.wsgi_app)
app.run()
小app.wsgi_app wrapping dance 将LoggingMiddleware 放置在 Flask WSGI 应用程序周围。
输出到wsgi.error 流;最终的结果取决于您的 WSGI 服务器; mod_wsgi 将其放入您站点的 Apache 错误日志中,捆绑的 Flask 服务器将其打印到 stderr。
【讨论】:
env['wsgi.input'] 是流,您也许可以将数据复制到tempfile.SpooledTemporaryFile() object,对那个文件做一些事情,然后回到开始并设置env['input.stream'] 指向它。
使用flask,您可以访问包含所有HTTP详细信息的请求对象:
from flask import request
@app.route('/')
def index():
print(request.headers)
【讨论】:
all the HTTP details。使用请求的其他属性也无济于事(例如数据、表单、值等)。要完整打印 HTTP 请求,围绕@martinpieters 的答案中建议的 WSGI 进行包装是可行的方法。
假设你想要完整的细节,
@app.route('/')
def index():
print request.__dict__
#this prints all variables in `dict` format including `headers`
【讨论】:
headers 甚至不是钥匙; environ 键包含不同的东西,包括标题,但肯定不是完整的原始请求。
pprint 后执行pprint.pformat(request.__dict__, depth=5)) 时,我看到environ 是为我打印的第一个键。
为什么不呢?
from flask import Flask, request
app = Flask(__name__)
@app.before_request
def log_request():
app.logger.debug("Request Headers %s", request.headers)
return None
# The remaining application code.
我已经使用了标头,但是您可以使用相同的方法来打印任何请求属性。文档在这里:http://flask.pocoo.org/docs/0.12/api/#flask.Request。
您还需要将 FLASK_DEBUG=1 设置为 Flask.logger.debug 才能工作,这很好,因为您可以在生产中禁用它。
问候,
【讨论】:
你可能想要类似的东西
print(request.headers)
print(request.data)
print(request.args)
print(request.form)
print(request.endpoint)
print(request.method)
print(request.remote_addr)
【讨论】:
这不使用烧瓶,但设置socket echo server 相当简单。
import socket
host = ''
port = 8888
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
while 1:
client, address = s.accept()
data = client.recv(size)
if data:
client.send(data)
client.close()
【讨论】:
如果您使用的是记录器,我发现这很有用
https://docs.python.org/3/library/pprint.html#pprint.pformat
from pprint import pformat
import requests
log.debug(pformat(request.headers))
【讨论】: