8

I am trying to use Falcon web framework with async workers like gevents and asyncio. I have been looking around for tutorials, but I haven't been able to find any which combine implementation of gevent with falcon. Since I have never used gevents before, I am not sure how to go around testing this combination. Can someone guide me to an example or a tutorial?

Thank you! :)

AnisH_GuptA
  • 137
  • 1
  • 10

1 Answers1

13

I was just looking to build a new website with Falcon and gevent, something I had done in the past. I knew that there was something odd about it, so I searched online and found your question. I'm somewhat surprised no one has responded yet. So, I went back to have a look at my earlier code and the following is the basic skeleton to get up and running with Falcon and gevent (which makes for a very fast framework):

from gevent import monkey, pywsgi  # import the monkey for some patching as well as the WSGI server
monkey.patch_all()  # make sure to do the monkey-patching before loading the falcon package!
import falcon  # once the patching is done, we can load the Falcon package


class Handler:  # create a basic handler class with methods to deal with HTTP GET, PUT, and DELETE methods
    def on_get(self, request, response):
        response.status = falcon.HTTP_200
        response.content_type = "application/json"
        response.body = '{"message": "HTTP GET method used"}'

    def on_post(self, request, response):
        response.status = falcon.HTTP_404
        response.content_type = "application/json"
        response.body = '{"message": "POST method is not supported"}'

    def on_put(self, request, response):
        response.status = falcon.HTTP_200
        response.content_type = "application/json"
        response.body = '{"message": "HTTP PUT method used"}'

    def on_delete(self, request, response):
        response.status = falcon.HTTP_200
        response.content_type = "application/json"
        response.body = '{"message": "HTTP DELETE method used"}'

api = falcon.API()
api.add_route("/", Handler())  # set the handler for dealing with HTTP methods; you may want add_sink for a catch-all
port = 8080
server = pywsgi.WSGIServer(("localhost", port), api)  # address and port to bind, and the Falcon handler API
server.serve_forever()  # once the server is created, let it serve forever

As you can see, the big trick is in the monkey-patching. Other than that, it really is quite straightforward. Hope this helps someone!

kartoon
  • 1,040
  • 1
  • 11
  • 24
kvaruni
  • 832
  • 1
  • 10
  • 20
  • 2
    This setup worked great for me. It's worth noting that not only can Falcon itself work with gevents, but you can also take advantage of gevents constructs like `spawn`, `sleep` and `Semaphore` within your app. I used them to create background workers that ran independently from request-driven code. – killthrush Mar 06 '17 at 13:58
  • 1
    I also tried running Falcon using the Bjoern server as opposed to gevent-enabled pywsgi. The former is faster and can support higher sustained requests/sec based on some of my hello-world testing, but the event loop is opaque and you can't use gevent in your app code. @kvaruni's setup lets you tap into the gevent event loop. That's certainly something to consider when selecting a WSGI server to host Falcon. – killthrush Mar 06 '17 at 14:09
  • you should not pass the `Handler()` class to the `add_route`, but rather an instance of the class ([ref](https://falcon.readthedocs.io/en/stable/user/tutorial.html)). Other than that I upvoted since it was useful, thanks! – charlie80 May 10 '18 at 09:16