flask-smorest
flask-smorest copied to clipboard
How to configure body content-type text/plain
I would like to configure a method that would use text as body imput (a message) for example:
{
"...": "...",
"paths": {
"/results/report": {
"post": {
"responses": {
"...": "...",
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Report"
}
}
}
},
},
"requestBody": {
"required": true,
"content": {
"text/plain": {
"type": "string",
"description": "Report message as text",
"example": "This is a text example"
}
}
},
"...": "...",
},
"parameters": [
"..."
]
}
},
"openapi": "3.0.2"
}
However, as @blueprint.arguments() only accepts schemas (or I think so), I could not find a way to accept "text" calls (neither in the swagger UI).
Is there a way I have not think about to produce this? I was thinking in something similar to:
import marshmallow as ma
import schemas
from flask.views import MethodView
from flask_smorest import Blueprint
blp = Blueprint(
'results', __name__, description='Operations on results'
)
@blp.route('/report')
class Report(MethodView):
@blp.doc(operationId='AddResultReport')
@blp.arguments(ms.fields.String, content_type="text/plain")
@blp.response(201, schemas.Report)
def post(self, message):
"""Creates a result report."""
...
return report
I haven't had the time to test this yet but I think you could archieve this by using marshmallows pre_dump-decorator.
Code-Example:
from marshmallow import Schema
from marshmallow.fields import String
class TextBodySchema(Schema):
content = String()
@pre_load
def wrap_body_content(self, in_data, **kwargs):
data = {"content": in_data}
return data
@blp.route('/report')
class Report(MethodView):
@blp.doc(operationId='AddResultReport')
@blp.arguments(TextBodySchema)
@blp.response(201, schemas.Report)
def post(self, body_schema):
"""Creates a result report."""
message = body_schema.content
...
return report
For more examples of extending schemas take a look at the marshmallow-docs.
Thanks for the help, I tried but it fails:
$ curl -X 'POST' \
> 'http://localhost:5000/results/265ddee1-555d-47d6-90cb-6279c730218c/report' \
> -H 'accept: application/json' \
> -H 'Content-Type: text/plain' \
> -d 'Result does not match benchmark template'
{
"code": 422,
"errors": {
"json": {
"content": [
"Not a valid string."
]
}
},
"status": "Unprocessable Entity"
}
Also i swagger the "example/schema" does not look as it shoud:
Example Value
{
"content": "This is an example string content"
}
when it should be simply:
This is an example string content
When debugging the content of in_data, its value is just {}.
I also tired to use content_type="text/plain" but in_data is still {}...
Is there a place to check where the content is removed and why?