Coder Social home page Coder Social logo

Comments (7)

apogiatzis avatar apogiatzis commented on June 2, 2024 3

Firstly thanks for this handy package!

That would be a really nice feature! If I find some spare time I will try to open a PR for this

For the time being here is my workaround in case you want to achieve this with Marshmallow schemas:

@ns.route("/testroute")
class TestResource(Resource):
    """Testing Endpoint"""

    @ns.response(200, "Success", for_swagger(model_schema, ns))
    @ns.response(404, "NotFound",for_swagger(error_schema, ns))
    def get(self):
        """Return something"""
        .....
        return obj

where ns is the Namespace or Api, and the schemas are Marshmallow schemas

from flask_accepts.

odesenfans avatar odesenfans commented on June 2, 2024

I concur, the handling of the various status codes surprises me. I see at least 2 different use cases:

  1. Different schemas for different situations (ex: success, failure)
  2. Different status codes for the same schema (ex: in a PUT request, return 201 on creation but 200 or 204 on update).

For 1, the type could be inferred in the responds decorator for simple cases. However, it's not easy for non-trivial schemas, ex: returning an object from the DB with an auto-generated marshmallow schema.
For 2, using the same schema, I don't see a proper solution. flask-accepts can't really make the difference between return response_content, status_code and a tuple schema.

Best solution could actually be to remove the status_code parameter from the responds decorator entirely...

from flask_accepts.

odesenfans avatar odesenfans commented on June 2, 2024

After giving it a bit more thought, I've come up with the following solution:

  1. Force the return value of endpoints decorated with responds to be a tuple of (data, status_code). It's non-trivial for flask-accepts to take only the object and determine the status code from it in anything but simplistic situations. A complete endpoint will have a lot of possible of different HTTP status codes. I usually have endpoints that return 200, 201, 204, 400, 401, 404, 422 and 500 status codes, so this seems like a strong requirement in a complete app.
  2. Specify schemas for each status code of interest. Store the schemas in a dict of status_code -> schema. Cases where the schema is not specified can easily be detected using the corresponding KeyError.
  3. Allow responds to be specified multiple times, once for each HTTP status code.

This feels like quite a large refactoring though, and is definitely a breaking change. I guess this should be discussed with @apryor6 :)

from flask_accepts.

volfpeter avatar volfpeter commented on June 2, 2024

My two cents:
I just don't think forcing return values to be tuples is a good idea. As you said it's a huge breaking change and adds (in most cases unnecessary) complexity to routing for developers. To quote another somewhat related principle from the zen of Python, special cases are not special enough to break the rules.

If support for multiple status codes is added, it must be added in a way that i) doesn't break existing code, ii) is straightforward to use (no tuples, they lack semantics and could actually be data). For example there could be a Response class with mandatory data and code properties, plus maybe an optional headers property, as described in the issue. If the route returns a Response, use the schema corresponding to code if such a schema was registered on the route with responds, otherwise raise an exception. If the route returns anything else and only one responds decorator was applied on the route, use that schema, otherwise raise an exception.

from flask_accepts.

odesenfans avatar odesenfans commented on June 2, 2024

To quote another somewhat related principle from the zen of Python, special cases are not special enough to break the rules.

I would say that this is not a special case, but rather an oversimplification from flask-accepts. Even a PUT must send different codes depending on whether the object was created or updated. HTTP codes need to be understood and controlled by developers.

I was proposing a tuple since it's the standard way of returning responses in Flask. I see this as more of a fix of a problem with flask-accepts rather than a new feature. Since we're not at a stable version number I would say the breaking change is acceptable and would make the library more usable in the long run.

from flask_accepts.

volfpeter avatar volfpeter commented on June 2, 2024

There is no standard for building REST APIs, it's an API implementation style that uses HTTP methods to communicate semantics. Everything you put on top of this (like PUT must respond with different status codes whether an object was created or updated) is up to you. I actually prefer a simple API style like this (notice the author), but this is also just a preference.

I would argue that in Flask make_response is the standard, but returning simply the result (or maybe an extra status code) is enough in most cases so the devs were kind/smart and added it as a convenience feature for users. You're also making the assumption that flask-accepts is (or will be) following semantic versioning, which may not be true.

Anyway, we've moved to subjective topics, so I'm closing this on my part. Actually the only reason I commented was because not long ago another breaking, not perfectly implemented PR ( #80 ) was accepted here that had to be later reverted, and I would like a solution that doesn't cause trouble for the existing users of this excellent project.

from flask_accepts.

apryor6 avatar apryor6 commented on June 2, 2024

from flask_accepts.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.