A while ago I was tasked with adding readiness checks for a Django App. This wasn’t as straight forward as I had hoped, so here’s a tutorial for the next person who has to do this.
The very first thing you need to do is add a new Middleware, say,
HealthCheckMiddleware to your Django app. Adding an API via a middleware and not a view might seem strange at first, but it’s important that you do this, because your readiness check must be executed before anything else, including Django’s inbuilt middleware chain. The skeleton for the middleware will look like:
settings.py, make sure this middleware is executed before everything else by adding it to the top of the list of the middlewares:
The next step is to write code to handle the request itself in the middleware. Readiness usually means that your app is up and can connect to the database. Since this API is going to be called pretty frequently by App Engine, we need to make sure the operation is as light as possible:
The final step is to tell Google App Engine how and when to call this API. Add the following to your
You should consider tweaking these values. For an explanation of what they mean, check out the docs here.
Nothing is complete without adding unit tests. To do this, we’ll add 2 unit tests, one that tests if the API returns 200 OK on a successful connection to the database, and a test for checking if there’s no connection to the database (and if the 503 is indeed being returned). Simulating the broken database postgresql connection in Django was a little tricky, since I couldn’t find documentation online, and using tools like
destroy_test_db freaks out the tests as Django thinks something has gone wrong. I was stuck for quite a while on this when my mentor suggested this great idea of passing a database connection
object to the middleware, so it can use that instead of using the default connection
object. Since we now control what connection the middleware uses, we can pass a <a href="https://docs.python.org/3/library/unittest.mock.html">mock database object</a> to it (and break it using a
side_effect). Using mocks revealed a host of new Google search results, compared to what I was searching (and struggling with) before.
Add the following code to your
And that’s it! You can see if it worked fine by running
python manage.py test tests.HealthCheckMiddlewareTestCase. You can now be rest assured that App Engine will only route traffic to your instance only when it can successfully connect to your database!