Python Falcon – Post calls are being ignored

Question:

I’m trying to set up a simple reverse proxy with Falcon in Python.

I have:

import falcon
import requests

class ReverseProxyResource:
    def on_get(self, req, resp, text=None):
        print("GET")
        if(text):
            destination = "[destination_url]/" + text
        else:
            destination = "[destination_url]"
        result = requests.get(destination)
        resp.body = result.text
        resp.status = result.status_code 

    def on_post(self, req, resp, text=None):
        print("POST")
        if(text):
            destination = "[destination_url]/" + text
        else:
            destination = "[destination_url]"
        result = requests.post(destination, data=req.bounded_stream.read())
        resp.body = result.text
        resp.status = result.status_code 

proxy_api = application = falcon.API()
proxy_api.req_options.auto_parse_form_urlencoded = True
proxy_api.add_route('/{text}', ReverseProxyResource())
proxy_api.add_route('/', ReverseProxyResource())

Get requests to the proxy are returned correctly.

However, Post requests are only returned a 404 error from the api. The "POST" print statement is not shown, indicating on_post isn’t called at all. (The post requests only included Header Content-Type: application/json and a simple JSON body, which work correctly when called directly against the destination url)

EDIT: Interestingly enough, if I change GET call in postman to POST (ie: no body, headers, or anything else added) on_post() is called when I hit the endpoint. So it seems like an issue where post requests that contain a body are being automtically 404’ed without calling on_post()

Asked By: DevBot

||

Answers:

Try adding user agent and content type before making the post call

headers = {"Content-Type": "text/plain", "User-Agent": "PostmanRuntime/7.30.0"}
result = requests.post(url = destination, data=req.bounded_stream.read(), headers=headers)

below code works for me

import falcon
import requests

class ReverseProxyResource:
    def on_get(self, req, resp, text=None):
        print("GET")
        if(text):
            destination = "https://cat-fact.herokuapp.com/" + text
        else:
            destination = "https://cat-fact.herokuapp.com/facts/"
        result = requests.get(destination)
        resp.body = result.text
        resp.status = result.status_code

    def on_post(self, req, resp, text=None):
        print("POST")
        if(text):
            destination = "https://dummy.restapiexample.com/api/v1/"+ text
        else:
            destination = "https://dummy.restapiexample.com/api/v1/create"
        headers = {"Content-Type": "text/plain", "User-Agent": "PostmanRuntime/7.30.0"}
        result = requests.post(url = destination, data=req.bounded_stream.read(), headers=headers)
        resp.text = result.text
        resp.status = result.status_code

proxy_api = application = falcon.App()
proxy_api.req_options.auto_parse_form_urlencoded = True
proxy_api.add_route('/{text}', ReverseProxyResource())
proxy_api.add_route('/', ReverseProxyResource())
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.