How to return Different Response Formats (JSON, XML) in Flask REST API

Here I am going to show you how to return different response formats (content negotiation) from Flask REST API. The default response format you receive from the REST API is JSON (JavaScript Object Notation). Now for some requirements you may need to return XML format from your REST API. Then this example may help you how to do it. I will show you example on HTTP GET and POST method.

Content negotiation refers to mechanisms defined as a part of HTTP that make it possible to serve different versions of a document (or more generally, representations of a resource) at the same URI, so that user agents can specify which version fits their capabilities the best.

Flask-RESTful is an extension of Flask API and it provides an additional support and encourages best practices for building REST APIs. Out of the box, Flask-RESTful is only configured to support JSON. To add additional media types to your API, you will need to declare your supported representations on the Api object.

To customize the response media types in XML or JSON format you need to define in the following way.

You need to define a Flask instance and api instance:

app = Flask(__name__)
api = Api(app)

Then you need to define your supported representations. To declare XML response format define following:

@api.representation('application/xml')
def output_xml(data, code, headers=None):
	resp = make_response(dumps({'response' : data}), code)
	resp.headers.extend(headers or {})
	return resp

To declare JSON response format do the following:

@api.representation('application/json')
def output_json(data, code, headers=None):
	resp = make_response(json.dumps({'response' : data}), code)
	resp.headers.extend(headers or {})
	return resp

By default response format is JSON format but if you still want to set default response format for your REST API then you can change the api instance api = Api(app) to api = Api(app, default_mediatype='application/json').

I have used decorator @api.representation() to declare the response format. Instead of using this decorator you can also use the following way to declare your response format.

api.representations['application/json'] = output_json
api.representations['application/xml'] = output_xml

You can also declare your different response format by subclassing the Api class with your own output functions:

class Api(restful.Api):
    def __init__(self, *args, **kwargs):
        super(Api, self).__init__(*args, **kwargs)
        self.representations = {
            'application/xml': output_xml,
            'text/html': output_html,
            'text/csv': output_csv,
            'application/json': output_json,
        }

Let’s look at the implementation part of the example.

Prerequisites

Python 3.9.0, Flask 1.1.2 (pip install flask), Flask-Restful 0.3.8 (pip install flask-restful), Python-Simplexml 0.1.5 (pip install python-simplexml)

Application Directory

You can create the root directory for your app anywhere in your system. The root directory name for my example is python-flask-rest-api-multiple-response-formats. I am going to keep all my Python scripts inside this root folder.

REST Resource Class

The first thing I am going to create is REST resource class. The following code is written into rest.py script.

from flask import request
from flask_restful import Resource

class Greet(Resource):

	def get(self):
		return {'message' : 'Hello, how are you?'}
	
	def post(self):
		req = request.get_json()
		print('req', req)
		return req, 201

class GreetName(Resource):
	def get(self, name):
		return {'message' : 'Hello ' + name + ', how are you?'}

I have created two classes – Greet and GreetName. Greet class defines two functions – get() and post(). get() is used to get or fetch the data using the resource and post() is used to create a new resource in the server.

REST Configurations

Here I am going to declare JSON & XML response formats, REST API endpoints. The following code is written into app.py script.

import rest
import json
from simplexml import dumps
from flask import Flask, make_response
from flask_restful import Api

app = Flask(__name__)

api = Api(app)
#api = Api(app, default_mediatype='application/json')

@api.representation('application/json')
def output_json(data, code, headers=None):
	resp = make_response(json.dumps({'response' : data}), code)
	resp.headers.extend(headers or {})
	return resp

@api.representation('application/xml')
def output_xml(data, code, headers=None):
	resp = make_response(dumps({'response' : data}), code)
	resp.headers.extend(headers or {})
	return resp

#api.representations['application/json'] = output_json
#api.representations['application/xml'] = output_xml

api.add_resource(rest.Greet, '/')
api.add_resource(rest.GreetName, '/<string:name>')

if __name__ == "__main__":
	app.run()

After creating the app and api instances I have declared the response formats. Then I have defined the endpoints using api.add_resource() function. Finally I have declared the app.run() for running the app.

Deploying the Application

Now navigate to the project’s root directory using command line tool and execute the command app.py, your server will be started on default port 5000.

If you want to change the port then you can change the line app.run() to app.run(port=5001), where 5001 is the new port.

Testing the Application

URL: http://localhost:5000/

By default response is JSON as shown in the below image:

different response formats json xml in flask rest api

If you want the response in XML format then add Accept/(application/xml) key/value pair in the headers.

different response formats json xml in flask rest api

For POST request I am not doing with the input data, just returning in the response.

different response formats json xml in flask rest api

URL: http://localhost:5000/<name>

You will get response with the name passed as a path parameter. The default format is JSON. You can also check the XML response by setting Accept/(application/xml) key/value pair in the HTTP headers.

different response formats json xml in flask rest api

That’s all. Hope you got an idea how to return different response format from the same REST API in Flask Restful framework.

Source Code

Download

Leave a Comment