Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Porting to Quart #107

Open
hadware opened this issue Oct 20, 2019 · 9 comments
Open

Porting to Quart #107

hadware opened this issue Oct 20, 2019 · 9 comments

Comments

@hadware
Copy link

hadware commented Oct 20, 2019

Hello,

I really liked using Flask-smorest (reminded me a lot of the great pleasure of using google-endpoints), and i'm currently giving a shot at Quart (a Flask "clone" working with asyncio and ASGI middleware). I tried using Flask-smorest "as-is" with Quart, since its API is suposed to match exactly that of Flask, but since Flask-smorest imports some underlying Flask and werkzeug primitives to do its magic, there was no clean way to make it work.

Without too much trouble (an evening's hacking sprint) I got it to work fine (at least with the Quickstart example from the doc) on Quart, and i'm currently fixing all the unit tests to make sure everything is ok (great job on those btw, it helped be catch a lot of small bugs that got lost in the translation). Here is the repo : https://github.com/hadware/quart-smorest

I'm currently polishing the port, but I don't want to barbaricaly steal all your credit for that wonderful work. Maybe you'd be interested in moving that repo to the marshmallow-code organisation (and i'd be happy to mantain it).

@lafrech
Copy link
Member

lafrech commented Nov 5, 2019

Great. I'm glad to hear that.

You're not stealing anything. You're sharing what you did with the code, which is more than expected by the licence. Thank you for that.

I'm afraid we can't support both Flask and an async webserver with the same codebase, can we?

Maintaining quart-smorest as a flask-smorest fork means you may want/need to merge flask-smorest into quart-smorest from times to times. I don't see how we can make this easier.

If you manage to get a usable version, with pypi releases and all, and if you volunteer as a maintainer, then I guess hosting the repo in marshmallow organization could be a good idea. I'll defer that to @sloria.

Thanks again.

@hadware
Copy link
Author

hadware commented Nov 6, 2019

Alright, great!

The changes to the code aren't that big, but I think having to support both framework will make the code uglier and will probably set us up for some import hell. I think a workflow where features are added to flask-smorest and then "backported" to quart-smorest is the way to go. If any modification to flask-smorest is accompagnied by some unit testing (as it is currently), things should be smooth.

The port is currently already usable, but some features aren't (namely: pagination, and some stuff having to do with ETAGs).

I'd be happy to maintain it in the organisation (since i'm already planning on maintaining it anyway).

@ramnes
Copy link

ramnes commented Nov 13, 2019

Oof, well, from my experience of open-source software, you'd rather want to merge the two implementations here and have two maintainers on the same repository rather than maintaining a fork and having two separated maintainers, even with the cost of the code complication. It's basically "1.5x work" vs "2x work and backport delays", if that means something. That being said, I'm super glad to see this done, whatever the way.

@lafrech Quart support bundled in flask-smorest would be a good argument to get my company using it and supporting it. In fact, Quart support is something we wanted to add to Stupeflask more than a year ago, see that issue: numberly/flask-stupe#22

@hadware
Copy link
Author

hadware commented Nov 14, 2019

@ramnes l'important c'est de prendre des p'tits bouts de trucs et les assembler ensemble

Although in general I agree maintaining a fork is a risky move, in this case there is a pretty large gap between Quart and Flask in terms of what is supported and such. There are still a lot of quirks that are Quart-only, and I'm extensively using the async/await syntax in the port.
Moreover, I think smorest is stable enough now, so there won't be many backports to do.

The first step, in any case, is to have Quart-smorest working (which is something I have to finish ASAP), and then maybe @lafrech can have an expert look at a diff of the two to figure out what's the best course of actions.

@lafrech
Copy link
Member

lafrech commented Nov 16, 2019

I've been thinking of a huge refactor.

1/ Extract what's not flask-related into a separate lib (smorest, marshmallow-smorest,...). flask-smorest would depend on this, and this would open the door to other (synchronous) frameworks (bottle-smorest,)....

2/ Rework smorest to publish each decorator in two versions, sync and async, while keeping the duplication to a minimum by factorizing the part that is around the call to the decorated function.

Just dropping the idea. I didn't check the code to evaluate feasibility.

The greatest challenge could be the refactoring of the tests.

This would be an important piece of work and it would result in added complexity, so let's not do that until we're sure there's at least another framework using it.

@lafrech
Copy link
Member

lafrech commented Feb 21, 2020

For the record, about werkzeug and ASGI: pallets/werkzeug#1322.

@hadware
Copy link
Author

hadware commented Feb 21, 2020

Yes!!! The main dev of Quart has started (and maybe finished) porting Quart to "async" werkzeug, so it might be much easier to port. I'll look into it.

@lafrech
Copy link
Member

lafrech commented Feb 21, 2020

AFAIU, async werkzeug does not exist yet, does it? All I see is pallets/werkzeug#1330.

And once async werkzeug is out, wouldn't it be easier to make async flask?

@lafrech
Copy link
Member

lafrech commented Jun 21, 2021

More info about Flask async vs. Quart: https://flask.palletsprojects.com/en/2.0.x/async-await/.

When to use Quart instead

Flask’s async support is less performant than async-first frameworks due to the way it is implemented. If you have a mainly async codebase it would make sense to consider Quart. Quart is a reimplementation of Flask based on the ASGI standard instead of WSGI. This allows it to handle many concurrent requests, long running requests, and websockets without requiring multiple worker processes or threads.

It has also already been possible to run Flask with Gevent or Eventlet to get many of the benefits of async request handling. These libraries patch low-level Python functions to accomplish this, whereas async/ await and ASGI use standard, modern Python capabilities. Deciding whether you should use Flask, Quart, or something else is ultimately up to understanding the specific needs of your project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants