.. _changelog-1.2: ============================== Change history for Faust 1.2 ============================== This document contain change notes for bugfix releases in the Faust 1.2.x series. If you're looking for changes in the latest series, please visit the latest :ref:`changelog`. For even older releases you can visit the :ref:`history` section. .. _version-1.2.2: 1.2.2 ===== - **Requirements** + Now depends on :mod:`aiocontextvars` 0.1.x. The new 0.2 version is backwards incompatible and breaks Faust. - **Settings**: Increases default :setting:`broker_session_timeout` to 60.0 seconds. - **Tables**: Fixes use of windowed tables when using :mod:`simplejson`. This change makes sure :mod:`simplejson` serializes :class:`typing.NamedTuple` as lists, and not dictionaries. Fix contributed by Omar Rayward (:github_user:`omarrayward`). - **Tables**: ``windowed_table[key].now()`` works outside of stream iteration. Fix contributed by Omar Rayward (:github_user:`omarrayward`). - **Examples**: New Kubernetes example. Contributed by Omar Rayward (:github_user:`omarrayward`). - **Misc**: Fixes :exc:`DeprecationWarning` for ``asyncio.current_task``. - **Typing**: Type checks now compatible with :pypi:`mypy` 0.641. - Documentation and examples fixes contributed by - Fabian Neumann (:github_user:`hellp`) - Omar Rayward (:github_user:`omarrayward`) .. _version-1.2.1: 1.2.1 ===== :release-date: 2018-10-08 5:00 P.M PDT :release-by: Ask Solem (:github_user:`ask`) - **Worker**: Fixed crash introduced in 1.2.0 if no ``--loglevel`` argument present. - **Web**: The :pypi:`aiohttp` driver now exposes ``app.web.web_app`` attribute. This will be the :class:`aiohttp.web_app.Application` instance used. - **Documentation**: Fixed markup typo in the settings section of the :ref:`guide` (Issue #177). Contributed by Denis Kataev (:github_user:`kataev`). .. _version-1.2.0: 1.2.0 ===== :release-date: 2018-10-05 5:23 P.M PDT :release-by: Ask Solem (:github_user:`ask`). .. _v120-fixes: Fixes ----- - **CLI**: All commands, including user-defined, now wait for producer to be fully stopped before shutting down to make sure buffers are flushed (Issue #172). - **Table**: Delete event in changelog would crash app on table restore (Issue #175) - **App**: Channels and topics now take default ``key_serializer``/``value_serializer`` from ``key_type``/``value_type`` when they are specified as models (Issue #173). This ensures support for custom codecs specified using the model ``serializer`` class keyword:: class X(faust.Record, serializer='msgpack'): x: int y: int .. _v120-news: News ---- - **Requirements** + Now depends on :ref:`Mode 1.18.1 `. - **CLI**: Command-line improvements. - All subcommands are now executed by :class:`mode.Worker`. This means all commands will have the same environment set up, including logging, signal handling, blocking detection support, and remote :pypi:`aiomonitor` console support. - ``faust worker`` options moved to top level (built-in) options: + ``--logfile`` + ``--loglevel`` + ``--console-port`` + ``--blocking-timeout`` To be backwards compatible these options can now appear before and after the ``faust worker`` command on the command-line (but for all other commands they need to be specified before the command name): .. sourcecode:: console $ ./examples/withdrawals.py -l info worker # OK $ ./examples/withdrawals.py worker -l info # OK $ ./examples/withdrawals.py -l info agents # OK $ ./examples/withdrawals.py agents -l info # ERROR! - If you want a long running background command that will run even after returning, use: ``daemon=True``. If enabled the program will not shut down until either the user hits :kbd:`Control-c`, or the process is terminated by a signal: .. code-block:: python @app.command(daemon=True) async def foo(): print('starting') # set up stuff return # command will continue to run after return. - **CLI**: New :func:`~faust.cli.faust.call_command` utility for testing. This can be used to safely call a command by name, given an argument list. - **Producer**: New :setting:`producer_partitioner` setting (Issue #164) - **Models**: Attempting to instantiate abstract model now raises an error (Issue #168). - **App**: App will no longer raise if configuration accessed before being finalized. Instead there's a new :class:`~faust.exceptions.AlreadyConfiguredWarning` emitted when a configuration key that has been read is modified. - **Distribution**: Setuptools metadata now moved to ``setup.py`` to keep in one location. This also helps the README banner icons show the correct information. Contributed by Bryant Biggs (:github_user:`bryantbiggs`) - Documentation and examples improvements by + Denis Kataev (:github_user:`kataev`). Web Improvements ---------------- .. note:: :mod:`faust.web` is a small web abstraction used by Faust projects. It is kept separate and is decoupled from stream processing so in the future we can move it to a separate package if necessary. You can safely disable the web server component of any Faust worker by passing the ``--without-web`` option. - **Web**: Users can now disable the web server from the faust worker (Issue #167). Either by passing :option:`faust worker --without-web` on the command-line, or by using the new :setting:`web_enable` setting. - **Web**: Blueprints can now be added to apps by using strings Example: .. sourcecode:: python app = faust.App('name') app.web.blueprints.add('/users/', 'proj.users.views:blueprint') - **Web**: Web server can now serve using Unix domain sockets. The ``--web-transport`` argument to :program:`faust worker`, and the :setting:`web_transport` setting was added for this purpose. Serve HTTP over Unix domain socket: .. sourcecode:: console faust -A app -l info worker --web-transport=unix:///tmp/faustweb.sock - **Web**: Web server is now started by the :class:`~faust.App` :class:`faust.Worker`. This makes it easier to access web-related functionality from the app. For example to get the URL for a view by name, you can now use ``app.web`` to do so after registering a blueprint: .. sourcecode:: python app.web.url_for('user:detail', user_id=3) - New :setting:`web` allows you to specify web framework by URL. Default, and only supported web driver is currently ``aiohttp://``. - **View**: A view can now define ``__post_init__``, just like dataclasses/Faust models can. This is useful for when you don't want to deal with all the work involved in overriding ``__init__``: .. sourcecode:: python @blueprint.route('/', name='list') class UserListView(web.View): def __post_init__(self): self.something = True async def get(self, request, response): if self.something: ... - **aiohttp Driver**: ``json()`` response method now uses the Faust json serializer for automatic support of ``__json__`` callbacks. - **Web**: New cache decorator and cache backends The cache decorator can be used to cache views, supporting both in-memory and Redis for storing the cache. .. sourcecode:: python from faust import web blueprint = web.Blueprint('users') cache = blueprint.cache(timeout=300.0) @blueprint.route('/', name='list') class UserListView(web.View): @cache.view() async def get(self, request: web.Request) -> web.Response: return web.json(...) @blueprint.route('/{user_id}/', name='detail') class UserDetailView(web.View): @cache.view(timeout=10.0) async def get(self, request: web.Request, user_id: str) -> web.Response: return web.json(...) At this point the views are realized and can be used from Python code, but the cached ``get`` method handlers cannot be called yet. To actually use the view from a web server, we need to register the blueprint to an app: .. sourcecode:: python app = faust.App( 'name', broker='kafka://', cache='redis://', ) app.web.blueprints.add('/user/', 'where.is:user_blueprint') After this the web server will have fully-realized views with actually cached method handlers. The blueprint is registered with a prefix, so the URL for the ``UserListView`` is now ``/user/``, and the URL for the ``UserDetailView`` is ``/user/{user_id}/``.