I love that this happens to larger libraries now. It doesn't need to be 100% complete, but it will still improve many devs' lives. I hope it will become the default for new projects and major updates.
He and his kind are in a different reality
I couldn't find a way to close the top banner. So I clicked around and found out this page had a bug. In the bottom right corner there is button to select the version of flask.
1. click v2.0.x, works fine
2. click v1.1.x, 404 page not found
3. click v2.0.x again, 404 page not found
Flask is still my go-to Python web framework. Ten years on, and I haven't stopped loving how small, elegant, and flexible it is. It set the bar for many other similar projects.
Flask was just a PITA to deploy properly in a way that it could handle lots of concurrent connections without a massive memory footprint, and async in Python is a mess.
The JS ecosystem has on the other hand moved to async and Promises as the standand/default way to implement things, which makes things much easier.
Express middleware is also just easier to write than Flask middleware.
I’ve heard this a lot of late, but it’s not clear to me why. Would you be willing to expand on your assertion?
Personally, I’ve written a fair chunk of typescript and asyncio based Python over the year for a project and in general I think Python has done an excellent job of their implementation.
Some things are annoying; for example I’ve a consistent case, which I haven’t pared down to better understand, where by exceptions in a coro are never visible. Not to be confused with the classic case of being notified of the exception when your process shuts down.
OTOH some things are really amazing, for example PYTHONASYNCIODEBUG=1. More so the ability to wrap non async, typically blocking, code in an Executor and it “magically” (via thread pools) work in the event loop has also been a boon for the type of work I’m engaged in.
Waaaaay back, I was really hurt by twisted and to a lesser extent tornado. But the async stuff shipped in 3.9x seems completely comparable to JavaScript imho.
The memory footprint shouldn't be bad, just one page per user.
Weird, none of the issues in my career as a full stack dev ever have been due to a lack of async primitives.
There are much more elegant ways of doing concurrency than Promises and coloured (async vs regular) functions, if that's the issue.
That makes me concerned. Does anyone here know if FastAPI is better? How many concurrent connections could your Express app handle at once?
Python 3 released on '08. Flask debuted a couple of years later in 2010, on Python 2. 11.5 years later Python 2 is nearly in the rearview. The history of the Python 3 release is surely an impressive one.
On a more related note, props to devs/contributors for this release. My experience with Flask was pop-up projects and never mission critical, but i always found it a joy to use and quite intuitive.
Flask is a great library which gets out of your way - I find it a joy to use compared to Django.
Although there are some dark sides, particularly with how Flask interacts with Werkzeug during exceptions when you need CORS (for example, we can't overwrite exception page's Access-Control-Allow-Origin headers with @app.after_request since these headers are set by Werkzeug and can't be overwritten in Flask).
This prevents us from levering Flask's default except handler in certain environments which require custom headers for exception handling page.
Agreed. I found Flask after being really annoyed with learning Django. Flask + Heroku is an awesome combo for the hobbyist like myself.
But this works for me:
@app.errorhandler(ApplicationError)
def handle(e):
resp = e.args[0]
resp.headers["Access-Control-Allow-Origin"] = "..."
resp.status_code = 500
return resp
@app.route("/err")
def err():
raise ApplicationError(jsonify({"reason": "test"}))I find built-in MethodViews very limited and unable to capture context.
Furthermore, MethodViews force you to artificially split endpoints between multiple classes when functionality better belongs in a single class.
Add route decorators for common HTTP methods. For example,
@app.post("/login") is a shortcut for
@app.route("/login", methods=["POST"]).I consider this to be a minor syntactic sugar.
Why? By default, it’s GET if you don’t specify a method. But now with this change, for special routes such as “/login” it’s POST. IMO these kinds of things make for “gotcha” moments. Just keep defaults simple without special exceptions.