marshal_with
which seems changed returned redirection:import flask
from flask import Flask
from flask_restx import Model, Resource, fields, Namespace, abort, Api
from werkzeug.middleware.proxy_fix import ProxyFix
app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)
api = Api(app, version='1.0', title='TodoMVC API',
description='A simple TodoMVC API',
)
ns = Namespace('todos', description='TODO operations')
ns2 = Namespace('todos2', description='TODO operations')
todo = Model('todo', {
'id': fields.Integer(required=True, description='The task unique identifier'),
'task': fields.String(required=True, description='The task details'),
'description': fields.String(required=True, description='Put some description here')
})
response = Model('response', {
'id': fields.Integer,
'task': fields.String
})
ns.models[todo.name] = todo
ns.models[response.name] = response
todo2 = Model('todo2', {
'task': fields.String(required=True, description='The task details'),
'todo_description': fields.String(required=True, description='Put some description here')
})
response2 = Model('response2', {
'id': fields.Integer,
'task': fields.String
})
ns2.models[todo2.name] = todo2
ns2.models[response2.name] = response
api.add_namespace(ns)
api.add_namespace(ns2)
@ns2.route('/<int:id>')
@ns2.response(404, 'Todo not found')
class Todo(Resource):
'''Show a single todo item and lets you delete them'''
@ns2.doc('get_todo')
def get(self, id):
'''Fetch a given resource'''
return "get todo 2"
@ns2.expect(todo2)
@ns2.marshal_with(response)
def post(self, id):
'''Update a task given its identifier'''
if id == 1:
redirection = flask.redirect(flask.url_for('todos_todo_list', _method='POST'), code=307)
return redirection
return {"id": "dummy id", "task": "some dummy task here"}
@ns.route('/')
class TodoList(Resource):
'''Shows a list of all todos, and lets you POST to add new tasks'''
@ns.doc('list_todos')
def get(self):
'''List all tasks'''
return "get todo list"
@ns.doc('create_todo')
@ns2.expect(todo)
@ns.marshal_with(response)
def post(self):
'''Create a new task'''
payload = ns.payload
return {"id": payload.get("id"), "task": payload.get("task")}
if __name__ == '__main__':
app.run(debug=True)
so the requirement is:
Given an endpoint with a variable (var == $CONDITION), have a redirect only for $CONDITION, otherwise, return properly
My gut would say, if you want a single endpoint, split by condition, to do 2 redirects. One for $CONDITION, one for everything else. and the resultant endpoints handling the marshalling. Because, in the end, if their responses are going to be different, they should probably be considered separate endpoints
Considering you're changing core functionality based upon a condition, i'd say keeping the original endpoint with 2 redirects, split by condition. then if you want to deprecate the v1 style endpoint later, you can
the other option is to split v1 and v2 endpoints, and just tell folks to use v2 for the new setup. Versioning and moving some endpoints is normal, and versioning is supported in flask-restx. you can provide version=
to the API generator.
Hi, I have a question about how can I create a field which is a fixed list of different models:
model_1 = api.model(...)
model_2 = api.model(...)
model_3 = api.model(...)
model = api.model('model', {'field': fields.List([model_1, model_2, model_3])})
I know passing the list of previous models is not expected as the first param of the fields.List
class but I don't know how to achieve it. Any ideas?
.config[]
list as static values in my api.models
but I'm getting errors about app_context()
Rather than try to push an context in my include that has all my models are there any tips you would recomend for including configuration values when marshaling results?
api.doc()
to document a POST request which should be able to take any JSON body (that is to say a valid JSON body is required, doesn't matter what is actually inside that body). At the moment, I am using a reqparse that is passed to the api.expect()
which I dont actually use in my code but is just there to force the Swagger docs to give me a JSON body when clicking "Try it out". I understand there isn't really a way to pass custom Swagger JSON (as you would be able to pass invalid JSON) so what would be the best way to do this?
mask=
does something I hacked around by having a nasty lambda
function in my model so that will clean that up significantly,
@api.route("/<string:subaccount>/user/<string:uniquename>")
How do I do stricter validation of uniquename much like parsing payloads? Do I do it all manually in my routine? Or is there something more strict than <string:varname>
?
I currently have problems with marshalling my Responses.
I am trying to do the following:
test_model = Model(
"Test",
{
"_id": fields.String,
"name": fields.String,
"location": fields.String,
"ip": fields.String,
},
)
success_model = Model(
"Success",
{"data": fields.List(
fields.Nested(test_model)
)
},
)
Without throwing any exception the data in the response is null
[{"status": "success", "data": null}']
Can somebody give me an advice?