0

I've found a number of simple web servers in python that will spin up a quick server and respond to requests simply. What I need is a server that won't just print the IP address, timestamp, method, and response code of each request (127.0.0.1 - - [28/Aug/2017 10:42:11] "POST / HTTP/1.1" 200 -), but also, if a POST request, I need it to print out the POST data.

So for example, if I send a POST request with {"foo":"bar"} in the body of the message, I want the server to print 127.0.0.1 - - [28/Aug/2017 10:42:11] "POST / HTTP/1.1" 200 - {"foo":"bar"} to the console before responding.

I'm not sure how to modify any of the linked options above to do this. If there's another simple option, that would work as well.

ewok
  • 20,148
  • 51
  • 149
  • 254

1 Answers1

2

To just print out whatever JSON gets sent to a server, build yourself a basic catch-all endpoint and just print the JSON from it. In flask, this looks like the following:

import logging
from flask import Flask, request
app = Flask(__name__)

@app.route('/', methods=['POST', 'GET'], defaults={'path': ''})
@app.route('/<path:path>', methods=['POST', 'GET'])
def index(path):
    print("HTTP {} to URL /{} received JSON {}".format(request.method, path, request.get_json()))
    return "True"

Here's my calls to the server:

In [15]: requests.post('http://localhost:5000/', json={'a': 1})
Out[15]: <Response [200]>

In [16]: requests.post('http://localhost:5000/some/endpoint', json={'a': 1})
Out[16]: <Response [200]>

In [17]: requests.get('http://localhost:5000/', json={'a': 1})
Out[17]: <Response [200]>

Here's the server output:

In [7]: app.run(host='0.0.0.0')
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
HTTP POST to URL / received JSON {'a': 1}
127.0.0.1 - - [28/Aug/2017 11:57:49] "POST / HTTP/1.1" 200 -
HTTP POST to URL /some/endpoint received JSON {'a': 1}
127.0.0.1 - - [28/Aug/2017 11:57:51] "POST /some/endpoint HTTP/1.1" 200 -
HTTP GET to URL / received JSON {'a': 1}
127.0.0.1 - - [28/Aug/2017 11:57:55] "GET / HTTP/1.1" 200 -

Original Answer

A simple decorator should do the trick:

from flask import Flask, request
app = Flask(__name__)

def print_if_post(*args, **kwargs):
    def inner_decorator(f):
        def inner(*args, **kwargs):
            if request.method == 'POST':
                json = request.get_json()
                print("JSON Data: {}".format(json))

            return f(*args, **kwargs)

        return app.route(*args, **kwargs)(inner)
    return inner_decorator

This decorator will function exactly like app.route, but will print any JSON data sent to its endpoint:

@print_if_post('/', methods=['POST', 'GET'])
def index():
    return "True"

Called with the following code:

In [4]: requests.get('http://localhost:5000/')
Out[4]: <Response [200]>

In [5]: requests.post('http://localhost:5000/', json={'a': 1})
Out[5]: <Response [200]>

Server outputs:

In [2]: app.run(host='0.0.0.0')
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [28/Aug/2017 11:03:11] "GET / HTTP/1.1" 200 -
JSON Data: {'a': 1}
127.0.0.1 - - [28/Aug/2017 11:03:23] "POST / HTTP/1.1" 200 -
scnerd
  • 5,836
  • 2
  • 21
  • 36
  • is there no way to do this without Flask? – ewok Aug 28 '17 at 15:12
  • 1
    Like the examples that you link, with [some help from here](https://stackoverflow.com/questions/4233218/python-basehttprequesthandler-post-variables), you may be able to write a minimal server that parses and prints the JSON data in POST requests. Without more details about the server you're trying to write, I'm not sure I can give you a good answer. Are you mainly trying to serve files? If so, why do you care about JSON POST data? Are you writing a basic web application? If so, why aren't you using a more complete server like flask, django, or web.py (as per @atwalsh04)? – scnerd Aug 28 '17 at 15:35
  • I'm literally trying to write a server that accepts requests, prints the POST data to the console, if there is any, responds with a 20X, and does absolutely nothing else. The point is to monitor what kinds of requests are being sent by another application I wrote. – ewok Aug 28 '17 at 15:41
  • 1
    Just use Flask or Web.py like suggested then. It hides a lot of the "server" crap, and lets you just write the logic you want. If dependencies are really not an option, you're probably going to have a bit of a tough time. I'll edit the answer with a more general suggestion for that use case. – scnerd Aug 28 '17 at 15:52