Skip to content

Commit

Permalink
chore(release): prepare for v2.7.1 (#3243)
Browse files Browse the repository at this point in the history
* chore(release): prepare for v2.7.1

* Update docs/release-notes/changelog.rst

* Update docs/release-notes/changelog.rst

* Update docs/release-notes/changelog.rst

* docs(release): latest release notes
  • Loading branch information
JacobCoffee authored Mar 27, 2024
1 parent 85ecf40 commit 636e917
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 13 deletions.
125 changes: 121 additions & 4 deletions docs/release-notes/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,121 @@
2.x Changelog
=============

.. changelog:: 2.7.1
:date: 2024-03-22

.. change:: add default encoders for `Enums` and `EnumMeta`
:type: bugfix
:pr: 3193

This addresses an issue when serializing ``Enums`` that was reported in discord.

.. change:: replace TestClient.__enter__ return type with Self
:type: bugfix
:pr: 3194

``TestClient.__enter__`` and ``AsyncTestClient.__enter__`` return ``Self``.
If you inherit ``TestClient``, its ``__enter__`` method should return derived class's instance
unless override the method. ``Self`` is a more flexible return type.

.. change:: use the full path for fetching openapi.json
:type: bugfix
:pr: 3196
:issue: 3047

This specifies the ``spec-url`` and ``apiDescriptionUrl`` of Rapidoc, and Stoplight Elements as absolute
paths relative to the root of the site.

This ensures that both of the send the request for the JSON of the OpenAPI schema to the right endpoint.

.. change:: JSON schema ``examples`` were OpenAPI formatted
:type: bugfix
:pr: 3224
:issue: 2849

The generated ``examples`` in *JSON schema* objects were formatted as:

.. code-block:: json
"examples": {
"some-id": {
"description": "Lorem ipsum",
"value": "the real beef"
}
}
However, above is OpenAPI example format, and must not be used in JSON schema
objects. Schema objects follow different formatting:

.. code-block:: json
"examples": [
"the real beef"
]
* Explained in `APIs You Won't Hate blog post <https://medium.com/apis-you-wont-hate/openapi-v3-1-and-json-schema-2019-09-6862cf3db959>`_.
* `Schema objects spec <https://spec.openapis.org/oas/v3.1.0#schema-object>`_
* `OpenAPI example format spec <https://spec.openapis.org/oas/v3.1.0#example-object>`_.

This is referenced at least from parameters, media types and components.

The technical change here is to define ``Schema.examples`` as ``list[Any]`` instead
of ``list[Example]``. Examples can and must still be defined as ``list[Example]``
for OpenAPI objects (e.g. ``Parameter``, ``Body``) but for JSON schema ``examples``
the code now internally generates/converts ``list[Any]`` format instead.

Extra confusion here comes from the OpenAPI 3.0 vs OpenAPI 3.1 difference.
OpenAPI 3.0 only allowed ``example`` (singular) field in schema objects.
OpenAPI 3.1 supports the full JSON schema 2020-12 spec and so ``examples`` array
in schema objects.

Both ``example`` and ``examples`` seem to be supported, though the former is marked
as deprecated in the latest specs.

This can be tested over at https://editor-next.swagger.io by loading up the
OpenAPI 3.1 Pet store example. Then add ``examples`` in ``components.schemas.Pet``
using the both ways and see the Swagger UI only render the example once it's
properly formatted (it ignores is otherwise).

.. change:: queue_listener handler for Python >= 3.12
:type: bugfix
:pr: 3185
:issue: 2954

- Fix the ``queue_listener`` handler for Python 3.12

Python 3.12 introduced a new way to configure ``QueueHandler`` and ``QueueListener`` via
``logging.config.dictConfig()``. As described in the
`logging documentation <https://docs.python.org/3/library/logging.config.html#configuring-queuehandler-and-queuelistener>`_.

The listener still needs to be started & stopped, as previously.
To do so, we've introduced ``LoggingQueueListener``.

And as stated in the doc:
* Any custom queue handler and listener classes will need to be defined with the same initialization signatures
as `QueueHandler <https://docs.python.org/3/library/logging.handlers.html#logging.handlers.QueueHandler>`_ and
`QueueListener <https://docs.python.org/3/library/logging.handlers.html#logging.handlers.QueueListener>`_.

.. change:: extend openapi meta collected from domain models
:type: bugfix
:pr: 3237
:issue: 3232

:class:`~litestar.typing.FieldDefinition` s pack any OpenAPI metadata onto a ``KwargDefinition`` instance when
types are parsed from domain models.

When we produce a DTO type, we transfer this meta from the `KwargDefinition` to a `msgspec.Meta` instance,
however so far this has only included constraints, not attributes such as descriptions, examples and title.

This change ensures that we transfer the openapi meta for the complete intersection of fields that exist on b
oth `KwargDefinition` and `Meta`.

.. change:: kwarg ambiguity exc msg for path params
:type: bugfix
:pr: 3261

Fixes the way we construct the exception message when there is a kwarg ambiguity detected for path parameters.

.. changelog:: 2.7.0
:date: 2024-03-10

Expand All @@ -19,8 +134,10 @@
:pr: 3176

Fix an issue with SSE where JavaScript clients fail to receive an event without data.
The `spec <https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream>`_ is not clear in whether or not an event without data is ok.
Considering the EventSource "client" is not ok with it, and that it's so easy DX-wise to make the mistake not explicitly sending it, this change fixes it by defaulting to the empty-string
The `spec <https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream>`_ is
not clear in whether or not an event without data is ok.
Considering the EventSource "client" is not ok with it, and that it's so easy DX-wise to make the mistake not
explicitly sending it, this change fixes it by defaulting to the empty-string

.. change:: Support ``ResponseSpec(..., examples=[...])``
:type: feature
Expand Down Expand Up @@ -54,7 +171,7 @@
:pr: 3096
:issue: 3088

Automatically encode responses with media type of the form "application/<something>+json" as json.
Automatically encode responses with media type of the form ``application/<something>+json`` as json.

.. change:: Allow reusable ``Router`` instances
:type: feature
Expand All @@ -64,7 +181,7 @@
It was not possible to re-attach a router instance once it was attached. This
makes that possible.

The router instance now gets deecopied when it's registered to another router.
The router instance now gets deepcopied when it's registered to another router.

The application startup performance gets a hit here, but the same approach is
already used for controllers and handlers, so this only harmonizes the
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ maintainers = [
name = "litestar"
readme = "README.md"
requires-python = ">=3.8,<4.0"
version = "2.7.0"
version = "2.7.1"

[project.urls]
Blog = "https://blog.litestar.dev"
Expand Down
26 changes: 18 additions & 8 deletions tools/prepare_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
import httpx
import msgspec

_polar = "[Polar.sh](https://polar.sh/litestar-org)"
_open_collective = "[OpenCollective](https://opencollective.com/litestar)"
_github_sponsors = "[GitHub Sponsors](https://github.com/sponsors/litestar-org/)"


class PullRequest(msgspec.Struct):
title: str
Expand Down Expand Up @@ -250,7 +254,7 @@ def add_change(self, pr: PRInfo) -> None:

@contextlib.contextmanager
def directive(self, name: str, arg: str | None = None, **options: str) -> Generator[None, None, None]:
self.add_line(f".. {name}:: {arg if arg else ''}")
self.add_line(f".. {name}:: {arg or ''}")
self._level += 1
for key, value in options.items():
if value:
Expand All @@ -268,12 +272,23 @@ def build_gh_release_notes(release_info: ReleaseInfo) -> str:
# 3. It works with our release branch process. GitHub doesn't pick up (all) commits
# made there depending on how things were merged
doc = GHReleaseWriter()

doc.add_line("## Sponsors 🌟")
doc.add_line(
"⚠️ Maintainers: Please adjust business/individual sponsors section here as defined by our tier rewards"
)
doc.add_line(f"- A huge 'Thank you!' to all sponsors across {_polar}, {_open_collective} and {_github_sponsors}!")

doc.add_line("## What's changed")
if release_info.first_time_prs:
doc.add_line("\n## New contributors 🎉")
for pr in release_info.first_time_prs:
doc.add_line(f"* @{pr.user.login} made their first contribution in {pr.url}")
if fixes := release_info.pull_requests.get("fix"):
doc.add_line("\n### Bugfixes")
doc.add_line("\n### Bugfixes 🐛")
doc.add_pr_descriptions(fixes)
if features := release_info.pull_requests.get("feat"):
doc.add_line("\nNew features")
doc.add_line("\nNew features 🚀")
doc.add_pr_descriptions(features)

ignore_sections = {"fix", "feat", "ci", "chore"}
Expand All @@ -283,11 +298,6 @@ def build_gh_release_notes(release_info: ReleaseInfo) -> str:
doc.add_line("### Other changes")
doc.add_pr_descriptions(other)

if release_info.first_time_prs:
doc.add_line("\n## New contributors")
for pr in release_info.first_time_prs:
doc.add_line(f"* @{pr.user.login} made their first contribution in {pr.url}")

doc.add_line("\n**Full Changelog**")
doc.add_line(release_info.compare_url)

Expand Down

0 comments on commit 636e917

Please sign in to comment.