Remove default `application/json` header from fastapi response
Question:
I have taken this (https://fastapi.tiangolo.com/advanced/response-directly/#returning-a-custom-response) example from fastapi documentation regarding how to return a custom response from a fastapi application. This is my example code that i came up with to test it :
from http.client import responses
from fastapi import FastAPI, Response
app = FastAPI()
response_examples = {
200: {
"description": "Success",
"content": {
"application/xml": {
"example": {
"""<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
"""
}
}
},
},
400: {"description": "An invalid value for header content-type."},
405: {"description": "Endpoint only supports POST."},
500: {"description": "Internal server error."},
}
@app.get("/legacy/", responses=response_examples)
def get_legacy_data():
data = """<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
"""
return Response(content=data, media_type="application/xml")
However my question is regarding the open api file when I am querying the /docs
endpoint of my application.
Below is the relevant section of the /docs
endpoint response(in yaml):
openapi: 3.0.2
info:
title: FastAPI
version: 0.1.0
paths:
/legacy/:
get:
summary: Get Legacy Data
operationId: get_legacy_data_legacy__get
responses:
'200':
description: Success
content:
application/json:
schema: {}
application/xml:
example:
- |-
<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
'400':
description: An invalid value for header content-type.
'405':
description: Endpoint only supports POST.
'500':
description: Internal server error.
There are 2 header types mentioned in the response application/json
and application/xml
which is the right response header. There should not be an application/json
response at all.
My question is that is this possible to do in fastapi and if so how can i remove the default application/json
header from response.
Answers:
You should put in a response_class=
parameter in your endpoint. Below is a fully working example:
from fastapi import FastAPI, Response
app = FastAPI()
response_examples = {
200: {
"description": "Success",
"content": {
"application/xml": {
"example": {
"""<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
"""
}
}
},
},
400: {"description": "An invalid value for header content-type."},
405: {"description": "Endpoint only supports POST."},
500: {"description": "Internal server error."},
}
class XMLResponse(Response):
media_type = "application/xml"
@app.get("/legacy/", responses=response_examples, response_class=XMLResponse)
def get_legacy_data():
data = """<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
"""
return XMLResponse(content=data)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000, )
I have taken this (https://fastapi.tiangolo.com/advanced/response-directly/#returning-a-custom-response) example from fastapi documentation regarding how to return a custom response from a fastapi application. This is my example code that i came up with to test it :
from http.client import responses
from fastapi import FastAPI, Response
app = FastAPI()
response_examples = {
200: {
"description": "Success",
"content": {
"application/xml": {
"example": {
"""<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
"""
}
}
},
},
400: {"description": "An invalid value for header content-type."},
405: {"description": "Endpoint only supports POST."},
500: {"description": "Internal server error."},
}
@app.get("/legacy/", responses=response_examples)
def get_legacy_data():
data = """<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
"""
return Response(content=data, media_type="application/xml")
However my question is regarding the open api file when I am querying the /docs
endpoint of my application.
Below is the relevant section of the /docs
endpoint response(in yaml):
openapi: 3.0.2
info:
title: FastAPI
version: 0.1.0
paths:
/legacy/:
get:
summary: Get Legacy Data
operationId: get_legacy_data_legacy__get
responses:
'200':
description: Success
content:
application/json:
schema: {}
application/xml:
example:
- |-
<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
'400':
description: An invalid value for header content-type.
'405':
description: Endpoint only supports POST.
'500':
description: Internal server error.
There are 2 header types mentioned in the response application/json
and application/xml
which is the right response header. There should not be an application/json
response at all.
My question is that is this possible to do in fastapi and if so how can i remove the default application/json
header from response.
You should put in a response_class=
parameter in your endpoint. Below is a fully working example:
from fastapi import FastAPI, Response
app = FastAPI()
response_examples = {
200: {
"description": "Success",
"content": {
"application/xml": {
"example": {
"""<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
"""
}
}
},
},
400: {"description": "An invalid value for header content-type."},
405: {"description": "Endpoint only supports POST."},
500: {"description": "Internal server error."},
}
class XMLResponse(Response):
media_type = "application/xml"
@app.get("/legacy/", responses=response_examples, response_class=XMLResponse)
def get_legacy_data():
data = """<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
"""
return XMLResponse(content=data)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000, )