Blinker 1.6 Released

written by P G Jones on 2023-04-02 in Releases

Signalling allows for applications to be decoupled by allowing designated receivers to be informed when an action has taken place (the signal). Flask and Quart both utilise the excellent Blinker library to support signals and it is version 1.6 of this library that has been released.

This is the second major release of Blinker since maintenance transferred to the Pallets-eco organisation, and represents a desire to maintain it for the benefit of Flask, Quart, and indeed Blinker users.

The Changelog for 1.6 is headlined by a mondernisation of the project structure which should ensure easier maintenance into the years to come. In addition we've added:

  • an ability to temporarily mute signals,
  • support for int senders,
  • support for async (coroutine) receivers,
  • and we've type hinted the project.

Quart is now a Pallets project

written by P G Jones on 2022-07-06 in Meta

Quart, an ASGI re-implementation of the Flask API has joined the Pallets organization. This means that future development will be under the Pallets governance by the Pallets maintainers.

Our long term aim is to merge Quart and Flask to bring ASGI support directly to Flask. This aim has significant technical obstacles, as outlined in this post or this talk. However, this change clears governance obstacles and brings the Quart and Flask maintainers closer together.

Introduction to Quart

Quart was developed from a desire to use asyncio and the async/await keywords in Flask. Which at the time of Quart's inception was not possible in Flask nor was it possible to add support. Instead Quart was developed as a reimplementation of Flask's API using async/await (learn more from this talk). Later Quart adopted the ASGI standard and is now a compliant ASGI framework.

The Quart API is a superset's of Flask in that it matches Flask's whilst including ASGI specific features such as websockets, for example:

from quart import Quart, render_template, websocket

app = Quart(__name__)

@app.route("/")
async def hello():
    return await render_template("index.html")

@app.route("/api")
async def json():
    return {"hello": "world"}

@app.websocket("/ws")
async def ws():
    while True:
        await websocket.send("hello")
        await websocket.send_json({"hello": "world"})

You can read more about Quart at quart.palletsprojects.com including a guide to migrating from Flask to Quart.

When to use Quart

Quart is an ASGI framework utilising async IO throughout, whereas Flask is a WSGI framework utilising sync IO. It is therefore best to use Quart if you intend to use async IO (i.e. async/await libraries) and Flask if not. Don't worry if you choose the 'wrong' framework though, as Quart supports sync IO and Flask supports async IO, although less efficiently.

What's next

The large ecosystem of Flask extensions is a real strength but unfortunately these extensions only work with Flask, and vice versa for Quart extensions. Therefore we plan to enable extensions to support both Flask and Quart in the future.

We expect to keep developing features for both Flask and Quart, in fact a number of features now present in Flask were developed in Quart or from knowledge gained from Quart. This includes typing, async/await support (in Flask), faster routing, and more.

With the closer relationship now possible both Flask and Quart should benefit from new features, shared bug fixes, and more. Please join our discord if you'd like to get involved.

Introducing the Pallets Community Organization (Pallets-Eco)

written by Kara Babcock on 2022-04-03 in Meta

Flask and many of the other Pallets projects benefit from having a diverse ecosystem of user-maintained extensions. However, we recognize that not every extension creator can maintain an extension indefinitely. Last year, the Pallets team started the Pallets Community Organization, aka Pallets-Eco, on GitHub to provide a place where the community can work together to maintain the extensions that we all rely on.

The popular Flask-Caching and Flask-OpenID extensions have already been moved to Pallets-Eco.

In time, we hope that this organization will ensure the stability of the Pallets ecosystem and provide a great point of entry for new contributors.

What Belongs in Pallets-Eco?

Although we expect that most extensions we take in will be for Flask, the organization is open to extensions for any of the Pallets projects—Click, Jinja, Werkzeug, etc.

It's important to note, however, that this is not an official extension repository. Extensions in this organization are not guaranteed to be up to date or maintained by the Pallets team. Rather, this is a centralized place for members of the wider community to help maintain these extensions.

The Pallets Community Organization is not currently accepting non-extension projects, such as documentation translations. If you are interested in such projects, join the Pallets Discord and ask about the Flask Community Working Group.

How You Can Transfer Your Extension

First, reach out on Discord (in the #pallets-eco channel) to express your interest. Only the current owner of a repository can transfer it, so please don't inquire on behalf of extensions you don't own. If there is an abandoned extension that you want to start maintaining, fork it, work on it, and then ask about joining Pallets-Eco.

Second, review the GitHub docs on transferring a repo. We will work with you to transfer the repo into the Pallets-Eco organization.

Third, you will need to give some of our organization members access to make releases on PyPI.

Keep in mind that transferring your extension to the Pallets Community Organization means you're giving up the final say on how your extension evolves. You will remain as a collaborator on your extension and can continue to contribute, but other members will have input on pull requests and when releases are made. If you prefer to keep your extension completely under your control, then Pallets-Eco is not for you.

Help With Maintenance

Whether you're interested in maintaining one extension in particular or just contributing to the organization overall, we welcome new contributors! This is a great starting point if you've always wanted to contribute to a Pallets project but haven't seen an issue you are ready to tackle—most of the issues in an extension will be smaller in scope and easier to resolve.

All extensions in the Pallets Community Organization follow the same contributing guidelines as the core Pallets projects. Different extensions will come to the organization with different testing coverage and documentation completion. To that end, even if an extension doesn't have open issues, it's likely you could improve its tests and/or docs. After you have reviewed the contributing guidelines, fork the repo, make changes, and open a pull request when you are ready.

Release permissions will be limited to trusted members of the organization (you could become one in time). If you have questions that don't belong in a specific extension's issues, ask in #pallets-eco on the Pallets Discord.

New Major Versions Released! Flask 2.0, Werkzeug 2.0, Jinja 3.0, Click 8.0, ItsDangerous 2.0, and MarkupSafe 2.0

written by David Lord on 2021-05-11 in Releases

The Pallets team is pleased to announce that the next major versions for our six core projects have been released!

This represents two years of work by the Pallets team and community, there are a significant number of changes and exciting new features. Check out the logs for every project to see what's new. Flask depends on the five other libraries, be sure to read them all if you're upgrading Flask.

Installing and Upgrading

Install from PyPI with pip. For example, for Flask:

pip install -U Flask

The projects have all dropped support for Python 2 and 3.5, requiring Python 3.6 as the minimum supported version. We plan to follow CPython's supported versions as our supported versions.

Some less common parts of the projects, or parts that we've determined are better served by external implementations, have been deprecated. Previously deprecated code has also been removed. Testing tools such as pytest enable showing deprecation warnings automatically, and can turn them into errors so that you can see early what you may need to change in your project.

While we strive to avoid compatibility issues, there may turn out to be incompatibilities either directly or through other dependencies your project uses, such as Flask extensions. Over the next few weeks, the ecosystem around our projects will continue to update to improve compatibility as necessary. We encourage you to use tools such as pip-compile and Dependabot to pin and control upgrades to your dependencies to avoid unexpected changes.

Renaming the Default Branch

We are joining the PSF, CPython, and Django, among many other projects, in renaming the default branch of our repositories to "main". GitHub makes this transition easy, see their documentation about how it works for maintainers and users.

If you have a local copy of the repository you'll need to rename its branch to "main".

$ git branch -m master main
$ git fetch origin
$ git branch -u origin/main main
$ git remote set-head origin -a

If you were installing from a GitHub archive URL such as https://github.com/pallets/flask/archive/refs/heads/master.zip, you'll need to rename that link to use "main".

Release Highlights

These are a few of the great new features and changes to be aware of in the projects. Check out the linked changelogs for the full lists of changes.

  • All Projects
    • Support Python 3.6 and above only. Removing the compatibility code makes the code faster, as well as easier to maintain and contribute to.
    • Comprehensive type annotations have been added to the code. This makes type checking your own code more useful, and allows IDEs to provide better completion and help.
    • Use tools such as pre-commit, black, flake8, and pyupgrade to ensure the code and new PRs follow the same style consistently.
  • Flask 2.0
    • Support async views and other callbacks such as error handlers, defined with async def. Regular sync views continue to work unchanged. ASGI features such as web sockets are not supported. We will continue exploring how to add more support for async.
    • Blueprints can be nested under other blueprints, allowing a more layered approach to organizing the application.
    • Add route decorators for common HTTP API methods. For example, @app.post("/login") is a shortcut for @app.route("/login", methods=["POST"]).
    • Better CLI errors when an app could not be loaded. Running the development server shows errors immediately, they are only deferred on reloads.
    • A new Config.from_file function to load config from any file format.
    • The flask shell command enables tab completion like the regular python shell does.
    • When serving static files, browsers will cache based on content rather than a 12 hour timer. This means changes to static content such as CSS styles will be reflected immediately on reload without needing to clear the cache.
  • Werkzeug 2.0
    • Parsing multipart/form-data has been optimized and shows a 15x speedup, especially for large file uploads.
    • Locals use Python's ContextVar to allow working across async coroutines instead of only threads.
    • All request and response code has been merged into single classes instead of composing multiple mixin classes.
    • While this is not a public API yet, the Request and Response classes are becoming sans-io. This will allow us to better support sync and async use cases in the future.
    • The test client always returns a Response class that includes a reference to the original request, environ, and any redirects that were followed.
    • datetime objects returned by some headers and functions are timezone-aware.
    • URL routing understands ws:// and wss:// schemes and will route appropriately. While there is no direct support for websockets, this allows other projects to use Werkzeug's routing.
    • Move Flask's implementation of send_file and send_from_directory to Werkzeug.
    • The debugger no longer uses jQuery, which significantly reduces the size of the package.
    • The reloader is smarter about watching or ignoring directories.
    • The development server avoids showing 0.0.0.0 and warns about not running in production.
    • Colors are shown correctly in the server log on Windows.
  • Jinja 3.0
    • Async environments and rendering no longer requires patching. This feature will continue to be improved now that async is natively supported.
    • Blocks can be marked as required.
    • Variables set in blocks or loops can be accessed in context functions, as well as inner scoped blocks. Macros have access to the current template globals.
    • Filters and tests used within if blocks and ternary statements can be undefined at runtime. Tests have been added to check if a filter or test is available, to allow optionally using them.
    • I18N supports pgettext and npgettext.
    • NativeEnvironment supports enable_async mode.
  • Click 8.0
    • The shell tab completion system has been completely rewritten. It now allows every command, group, parameter, and type to provide custom completion, supports sending metadata such as the type to the shell for better native support, and provides a way to add support for new shells.
    • style supports 256 and RGB color codes supported by modern terminals, as well as the strikethrough, italic, and overline styles.
    • New class attributes make it easier to customize the core objects.
    • The context can manage resources that use context managers across commands. For example, this makes it easier to manage a database connection.
    • Options with multiple=True or nargs don't require setting a default, and properly validate the format of a default if it's given.
    • Options can be used as only a flag to use a default value, or prompt for a value only if the flag is given.
    • Prompts validate using the option's custom callback in addition to its type.
    • Help formatting and short help message generate has been improved.
    • Command line arguments on Windows support glob patterns like *.txt and ~/config.json, since the Windows terminal does not support this automatically.
    • Messages shown to users, such as validation and errors, are marked as I18N translatable with gettext.
  • ItsDangerous 2.0
    • Added support for key rotation by passing a list of valid keys instead of a single key.
    • datetime objects are timezone-aware.
  • MarkupSafe 2.0
    • Wheels are provided for 33 Python version / OS / architecture combinations, to make installing with speedups easy. Newly added are ManyLinux 2014 and OSX Universal 2 wheels.

Follow and Get Involved

Follow our blog RSS feed or our Twitter @PalletsTeam to get future updates. We also have an official Discord server https://discord.gg/pallets for chatting, asking questions, and contributing to the projects.

If you're interested in contributing, each project has a guide showing how to get started with a development environment and the tools we use. Check out the issue trackers for each project for what to work on. Use the Watch feature on GitHub see new issues, PRs, and the discussions we have around them.

The Pallets organization accepts donations as part of the non-profit Python Software Foundation (PSF). Donations through the PSF support our efforts to maintain the projects and grow the community.

Click here to donate. ❤

For Enterprise

The Pallets team and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use.

Learn more.

Thank You!

We've made amazing progress, both by working through the backlog of issues and PRs, as well as growing the team and community. We have so many more exciting things in store. Look for more updates soon on community projects such as documentation translations and FlaskCon Online 2021! Thank you so much for using, supporting, and contributing to the Pallets projects!

New Flask, Jinja2, Click, Werkzeug, ItsDangerous, and MarkupSafe major release candidates

written by Philip Jones on 2021-04-29 in Releases

The Pallets team is pleased to announce that release candidates are now available for the next major version of each project.

Check out the changelogs for every project to see what's new:

Please help us prepare for the final release by testing the prerelease versions and reporting any issues you have. To upgrade to pre-releases with pip, use the --pre flag, e.g.:

pip install -U --pre Flask

These new major versions all drop support for Python 2 and 3.5, requiring Python 3.6 as the minimum supported version.

Release highlights

These are a few highlights, see the changelogs linked above for the full release details. More detailed posts about each project's highlights will be made with the final releases.

  • All projects (Jinja coming soon) now provide type hints.
  • Flask gains limited async/await support.
  • Flask supports nested blueprints.
  • Flask tells the browser to cache static files more intelligently, so changes to CSS or images show up immediately.
  • Flask introduces short form route decorators, such as @app.post() as a shortcut for @app.route(methods=["POST"]).
  • Click's shell completion system has been rewritten.
  • Click will now prompt for values where they are omitted.
  • Werkzeug now provides send_file and send_from_directory helpers.
  • Werkzeug's test client always returns a Response object.
  • Werkzeug's multipart parsing performance increases by a factor of 15.

Release date

The Pallets team is aiming to release on or before PyCon 2021, i.e. a target release date of the 11th of May 2021.

Click 7.1 Released

written by David Lord on 2020-03-09 in Releases

The Pallets team is pleased to release Click 7.1.

Read the full changelog to understand what may affect your code when upgrading.

  • Drop support for Python 3.4. This will be the last version to support Python 2.7 and 3.5.
  • Multiple fixes in low-level Windows compatibility code.
  • Colored output in Jupyter notebooks on Linux and Mac.
  • Updated Bash and ZSH tab completion support. Add support for Fish.
  • Better formatting when option help text contains newlines.

This also fixes a packaging issue from 7.0 where the project name in the package metadata was changed to "Click" with an upper case "C". This has been reverted, the name is now correctly reported in all lower case, "click".

Version 8.0 Coming Soon

As outlined in Ending Python 2 Support, 7.1.x will be the last version to support Python 2.7 and 3.5. The next version will be 8.0 and will support Python 3.6 and newer.

Install or Upgrade

Install from PyPI with pip:

pip install -U click

The Pallets organization accepts donations as part of the non-profit Python Software Foundation (PSF). Donations through the PSF support our efforts to maintain the projects and grow the community.

Click here to donate. ❤

Werkzeug 1.0.0 Released

written by David Lord on 2020-02-06 in Releases

The Pallets team is pleased to release Werkzeug 1.0. Werkzeug is the low-level WSGI and HTTP toolkit that powers Flask. It's been almost 13 years since the first commit, and this milestone for the project brings many fixes and changes. Read the full changelog to understand what may affect your code when upgrading.

  • Drop support for Python 3.4. This will be the last version to support Python 2.7 and 3.5.
  • Remove most top-level attributes provided by the werkzeug module in favor of direct imports. If you haven't already, use version 0.16 first to see deprecation warnings while upgrading.
  • Cookies support the samesite='None' option. Cookies are parsed as a MultiDict instead of overwriting repeated keys.
  • The development server supports 2-way TLS, making it easier to develop applications that inspect client certificates.
  • When building URLs with host matching, the current host is accounted for when deciding what rule to build.
  • When defining and matching URL rules, consecutive slashes are merged by default to match the behavior of common HTTP servers.
  • The Accept header preserves order for tags with equal quality and considers options on each value. The Accept-Language header can match the primary tag if the specific value is not present.
  • Added CORS header attributes to Request and Response.
  • A URL rule can be marked as a websocket, in which case it will only match for wss:// requests. This allows async web frameworks to use Werkzeug for routing.

Version 2.0 Coming Soon

As outlined in Ending Python 2 Support, 1.0.x will be the last version to support Python 2.7 and 3.5. The next version will be 2.0 and will support Python 3.6 and newer.

Install or Upgrade

Install from PyPI with pip:

pip install -U Werkzeug

The Pallets organization accepts donations as part of the non-profit Python Software Foundation (PSF). Donations through the PSF support our efforts to maintain the projects and grow the community.

Click here to donate. ❤

For Enterprise

The Pallets team and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use.

Learn more.

Jinja 2.11.0 Released

written by David Lord on 2020-01-27 in Releases

The Pallets team is pleased to release Jinja 2.11.0. Read the changelog for the full list of changes. Some of the bigger changes include:

  • Drop support for Python 2.6, 3.3, and 3.4. This will be the last version to support Python 2.7 and 3.5.
  • A new jinja2.ext.debug extension adds a {% debug %} tag to quickly dump the current template context.
  • A new ChainableUndefined type allows silently ignoring attribute access on undefined variables.
  • Loop context variables like loop.length and loop.nextitem work better in both sync and async environments.
  • Improved compile and runtime performance.

Version 3.0 Coming Soon

As outlined in Ending Python 2 Support, 2.11.x will be the last version to support Python 2.7 and 3.5. The next version will be 3.0 and will support Python 3.6 and newer.

The package name will remain "Jinja2" and imports will remain jinja2. "Jinja2 3.0" looks a little weird, but given the years of community momentum behind the name, we concluded it was less disruptive to keep it as-is.

Install or Upgrade

Install from PyPI with pip:

pip install -U Jinja2

The Pallets organization accepts donations as part of the non-profit Python Software Foundation (PSF). Donations through the PSF support our efforts to maintain the projects and grow the community.

Click here to donate. ❤

For Enterprise

The Pallets team and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use.

Learn more.

Ending Python 2 Support

written by David Lord on 2019-12-17 in Meta

Upstream support for Python 2.7 is ending on January 1, 2020. Pallets is joining the community of open source projects ending support for Python 2 at that time. Our statement and support plan are based on PyTest's announcement.

We will be dropping support for Python 2.7 as well as Python 3.5 and below, as their support windows have ended or will end around the same time. Future releases of each Pallets project will only support Python versions still supported upstream, which can be found in the Python Developer's Guide.

The last version branch of each core project to support Python 2.7 and Python 3.5 are:

  • Flask 1.1.x
  • Werkzeug 1.0.x
  • Click 7.x
  • Jinja 2.11.x
  • ItsDangerous 1.1.x
  • MarkupSafe 1.1.x

Each project will receive a major version bump to indicate support for only 3.6+:

  • Flask 2.0
  • Werkzeug 2.0
  • Click 8.0
  • Jinja 3.0
  • ItsDangerous 2.0
  • MarkupSafe 2.0

Thanks to the python_requires package metadata, Python 2.7 and 3.5 users with a modern pip version will install the last supported version automatically even if later versions are available.

The team will no longer backport patches for unsupported versions, but the branches will continue to exist. The team will be happy to accept patches contributed by the community for any severe security and usability issues until mid-2020.

We made this decision based on multiple factors. Foremost is ease of community contribution and maintainer availability. As time goes on, fewer contributors have used or are familiar with the differences between Python 2 and 3. Contributors and maintainers must keep track of an ever growing list of obscure compatibility issues and workarounds, and cannot use many modern features.

Over the last two years, we've talked to many developers and teams at conferences and meetups and heard overwhelming support for the move to Python 3. This is backed up by data collected from our community in a survey we ran during January 2019, with 92% of respondents already using or actively upgrading to Python 3. The PSF developer survey and PyPI statistics report similar majorities and show adoption continuing to increase.

Thank you to everyone in the community for your support, and to everyone who has made this transition a reality. We look forward to continuing to develop the Pallets projects with you!

Werkzeug 0.16.0 Released

written by David Lord on 2019-09-19 in Releases

Werkzeug 0.16.0 has been released. The only change is that most of the top-level attributes in the werkzeug module are now deprecated, and will be removed in 1.0.0.

For example, instead of import werkzeug; werkzeug.url_quote, do from werkzeug.urls import url_quote. If you are using these imports in your project, a deprecation warning will show the correct import to use. werkzeug.exceptions and werkzeug.routing should also be imported instead of accessed, but for technical reasons can’t show a warning.

These imports were supported by patching the werkzeug module to support lazy imports, but the implementation added complexity, and there was no clear design reason why some things were available and some weren't. It also masked some circular dependency issues. IDEs like PyCharm didn't know those lazy imports existed and were already correctly using the full imports.