Print raw HTTP request in Flask or WSGI

PythonFlaskWsgi

Python Problem Overview


I am debugging a microcontroller I've built which is writing raw HTTP requests line by line. I am using Flask for my backend and I would like to see the entire request as it appears in this format:

GET / HTTP/1.1
Content-length: 123
User-agent: blah
...

I know Flask is based on WSGI. Is there anyway to get this to work with Flask?

Python Solutions


Solution 1 - Python

Yes, Flask is a WSGI application, so it is trivial to wrap your app in an extra layer that logs the request:

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)

This defines a piece of middleware to wrap your Flask application in. The advantage is that it operates entirely independent of Flask, giving you unfiltered insight into what goes in and what comes out.

How you apply the middleware depends on the exact WSGI server you are using; see your WSGI server documentation.

When running Flask with the built-in server (app.run()), do:

if __name__ == '__main__':
    app.wsgi_app = LoggingMiddleware(app.wsgi_app)
    app.run()

The little app.wsgi_app wrapping dance places the LoggingMiddleware around the Flask WSGI application.

The output goes to the wsgi.error stream; where that ends up again depends on your WSGI server; mod_wsgi puts this in the Apache error log for your site, the bundled Flask server prints this to stderr.

Solution 2 - Python

With flask you have access to the request object which contains all the HTTP details:

from flask import request

@app.route('/')
def index():
    print(request.headers)

Solution 3 - Python

suppose if you want complete details,

There is an another way

@app.route('/')
def index():
    print request.__dict__
    #this prints all variables in `dict` format including `headers`

Solution 4 - Python

Why not?

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.

I've used the headers but you can use the same aproach to print any request attribute. The docs are here: http://flask.pocoo.org/docs/0.12/api/#flask.Request.

Also you need to setup FLASK_DEBUG=1 to Flask.logger.debug to work, what is nice since you can disable it in production.

Regards,

Solution 5 - Python

you probably want something like

print(request.headers)
print(request.data)
print(request.args)
print(request.form)
print(request.endpoint)
print(request.method)
print(request.remote_addr)

Solution 6 - Python

This doesn't use flask but it is fairly simple to setup a 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()

Solution 7 - Python

if you're using a logger i found this useful

https://docs.python.org/3/library/pprint.html#pprint.pformat

from pprint import pformat
import requests
log.debug(pformat(request.headers))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTinkerView Question on Stackoverflow
Solution 1 - PythonMartijn PietersView Answer on Stackoverflow
Solution 2 - PythonjkysamView Answer on Stackoverflow
Solution 3 - PythonNavaView Answer on Stackoverflow
Solution 4 - PythongeckosView Answer on Stackoverflow
Solution 5 - PythonJens TimmermanView Answer on Stackoverflow
Solution 6 - PythonAndrew JohnsonView Answer on Stackoverflow
Solution 7 - PythonSonic SoulView Answer on Stackoverflow