Skip to content

Commit 804f015

Browse files
authored
Merge pull request #2827 from litestar-org/develop
chore(release): v2.5.0
2 parents 2b89145 + 39b0f87 commit 804f015

38 files changed

+1163
-78
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
.scannerwork/
99
.unasyncd_cache/
1010
.venv/
11+
.venv*
1112
.vscode/
1213
__pycache__/
1314
build/

docs/conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"opentelemetry": ("https://opentelemetry-python.readthedocs.io/en/latest/", None),
5858
"advanced-alchemy": ("https://docs.advanced-alchemy.jolt.rs/latest/", None),
5959
"jinja2": ("https://jinja.palletsprojects.com/en/latest/", None),
60+
"trio": ("https://trio.readthedocs.io/en/stable/", None),
6061
}
6162

6263
napoleon_google_docstring = True
@@ -226,6 +227,9 @@
226227
),
227228
re.compile(r"litestar\.dto.*"): re.compile(".*T|.*FieldDefinition|Empty"),
228229
re.compile(r"litestar\.template\.(config|TemplateConfig).*"): re.compile(".*EngineType"),
230+
"litestar.concurrency.set_asyncio_executor": {"ThreadPoolExecutor"},
231+
"litestar.concurrency.get_asyncio_executor": {"ThreadPoolExecutor"},
232+
re.compile(r"litestar\.channels\.backends\.asyncpg.*"): {"asyncpg.connection.Connection"},
229233
}
230234

231235
# Do not warn about broken links to the following:
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
asyncpg
2+
=======
3+
4+
.. automodule:: litestar.channels.backends.asyncpg
5+
:members:

docs/reference/channels/backends/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ backends
66
base
77
memory
88
redis
9+
psycopg
10+
asyncpg
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
psycopg
2+
=======
3+
4+
.. automodule:: litestar.channels.backends.psycopg
5+
:members:

docs/reference/concurrency.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
cli
2+
===
3+
4+
.. automodule:: litestar.concurrency
5+
:members:

docs/reference/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ API reference
1414
connection
1515
contrib/index
1616
controller
17+
concurrency
1718
data_extractors
1819
datastructures
1920
di

docs/release-notes/changelog.rst

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,160 @@
33
2.x Changelog
44
=============
55

6+
.. changelog:: 2.5.0
7+
:date: 2024/01/06
8+
9+
.. change:: Fix serialization of custom types in exception responses
10+
:type: bugfix
11+
:issue: 2867
12+
:pr: 2941
13+
14+
Fix a bug that would lead to a :exc:`SerializationException` when custom types
15+
were present in an exception response handled by the built-in exception
16+
handlers.
17+
18+
.. code-block:: python
19+
20+
class Foo:
21+
pass
22+
23+
24+
@get()
25+
def handler() -> None:
26+
raise ValidationException(extra={"foo": Foo("bar")})
27+
28+
29+
app = Litestar(route_handlers=[handler], type_encoders={Foo: lambda foo: "foo"})
30+
31+
The cause was that, in examples like the one shown above, ``type_encoders``
32+
were not resolved properly from all layers by the exception handling middleware,
33+
causing the serializer to throw an exception for an unknown type.
34+
35+
.. change:: Fix SSE reverting to default ``event_type`` after 1st message
36+
:type: bugfix
37+
:pr: 2888
38+
:issue: 2877
39+
40+
The ``event_type`` set within an SSE returned from a handler would revert back
41+
to a default after the first message sent:
42+
43+
.. code-block:: python
44+
45+
@get("/stream")
46+
async def stream(self) -> ServerSentEvent:
47+
async def gen() -> AsyncGenerator[str, None]:
48+
c = 0
49+
while True:
50+
yield f"<div>{c}</div>\n"
51+
c += 1
52+
53+
return ServerSentEvent(gen(), event_type="my_event")
54+
55+
In this example, the event type would only be ``my_event`` for the first
56+
message, and fall back to a default afterwards. The implementation has been
57+
fixed and will now continue sending the set event type for all messages.
58+
59+
.. change:: Correctly handle single file upload validation when multiple files are specified
60+
:type: bugfix
61+
:pr: 2950
62+
:issue: 2939
63+
64+
Uploading a single file when the validation target allowed multiple would cause
65+
a :exc:`ValidationException`:
66+
67+
.. code-block:: python
68+
69+
class FileUpload(Struct):
70+
files: list[UploadFile]
71+
72+
73+
@post(path="/")
74+
async def upload_files_object(
75+
data: Annotated[FileUpload, Body(media_type=RequestEncodingType.MULTI_PART)]
76+
) -> list[str]:
77+
pass
78+
79+
80+
This could would only allow for 2 or more files to be sent, and otherwise throw
81+
an exception.
82+
83+
.. change:: Fix trailing messages after unsubscribe in channels
84+
:type: bugfix
85+
:pr: 2894
86+
87+
Fix a bug that would allow some channels backend to receive messages from a
88+
channel it just unsubscribed from, for a short period of time, due to how the
89+
different brokers handle unsubscribes.
90+
91+
.. code-block:: python
92+
93+
await backend.subscribe(["foo", "bar"]) # subscribe to two channels
94+
await backend.publish(
95+
b"something", ["foo"]
96+
) # publish a message to a channel we're subscribed to
97+
98+
# start the stream after publishing. Depending on the backend
99+
# the previously published message might be in the stream
100+
event_generator = backend.stream_events()
101+
102+
# unsubscribe from the channel we previously published to
103+
await backend.unsubscribe(["foo"])
104+
105+
# this should block, as we expect messages from channels
106+
# we unsubscribed from to not appear in the stream anymore
107+
print(anext(event_generator))
108+
109+
Backends affected by this were in-memory, Redis PubSub and asyncpg. The Redis
110+
stream and psycopg backends were not affected.
111+
112+
.. change:: Postgres channels backends
113+
:type: feature
114+
:pr: 2803
115+
116+
Two new channel backends were added to bring Postgres support:
117+
118+
:class:`~litestar.channels.backends.asyncpg.AsyncPgChannelsBackend`, using the
119+
`asyncpg <https://magicstack.github.io/asyncpg/current/>`_ driver and
120+
:class:`~litestar.channels.backends.psycopg.PsycoPgChannelsBackend` using the
121+
`psycopg3 <https://www.psycopg.org/psycopg3/docs/>`_ async driver.
122+
123+
.. seealso::
124+
:doc:`/usage/channels`
125+
126+
127+
.. change:: Add ``--schema`` and ``--exclude`` option to ``litestar route`` CLI command
128+
:type: feature
129+
:pr: 2886
130+
131+
Two new options were added to the ``litestar route`` CLI command:
132+
133+
- ``--schema``, to include the routes serving OpenAPI schema and docs
134+
- ``--exclude`` to exclude routes matching a specified pattern
135+
136+
.. seealso::
137+
:ref:`usage/cli:routes`
138+
139+
.. change:: Improve performance of threaded synchronous execution
140+
:type: misc
141+
:pr: 2937
142+
143+
Performance of threaded synchronous code was improved by using the async
144+
library's native threading helpers instead of anyio. On asyncio,
145+
:meth:`asyncio.loop.run_in_executor` is now used and on trio
146+
:func:`trio.to_thread.run_sync`.
147+
148+
Beneficiaries of these performance improvements are:
149+
150+
- Synchronous route handlers making use of ``sync_to_thread=True``
151+
- Synchronous dependency providers making use of ``sync_to_thread=True``
152+
- Synchronous SSE generators
153+
- :class:`~litestar.stores.file.FileStore`
154+
- Large file uploads where the ``max_spool_size`` is exceeded and the spooled
155+
temporary file has been rolled to disk
156+
- :class:`~litestar.response.file.File` and
157+
:class:`~litestar.response.file.ASGIFileResponse`
158+
159+
6160
.. changelog:: 2.4.5
7161
:date: 2023/12/23
8162

docs/usage/channels.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,17 @@ implemented are:
413413
when history is needed
414414

415415

416+
:class:`AsyncPgChannelsBackend <.asyncpg.AsyncPgChannelsBackend>`
417+
A postgres backend using the
418+
`asyncpg <https://magicstack.github.io/asyncpg/current/>`_ driver
419+
420+
421+
:class:`PsycoPgChannelsBackend <.psycopg.PsycoPgChannelsBackend>`
422+
A postgres backend using the `psycopg3 <https://www.psycopg.org/psycopg3/docs/>`_
423+
async driver
424+
425+
426+
416427

417428
Integrating with websocket handlers
418429
-----------------------------------

docs/usage/cli.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,19 @@ The ``routes`` command displays a tree view of the routing table.
185185
186186
litestar routes
187187
188+
Options
189+
~~~~~~~
190+
191+
+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
192+
| Flag | Description |
193+
+=================+===========================================================================================================================================================+
194+
| ``--schema`` | Include default auto generated openAPI schema routes |
195+
+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
196+
| ``--exclude`` | Exclude endpoints from query with given regex patterns. Multiple excludes allowed. e.g., ``litestar routes --schema --exclude=routes/.* --exclude=[]`` |
197+
+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
198+
199+
200+
188201

189202
.. image:: /images/cli/litestar_routes.png
190203
:alt: litestar info

0 commit comments

Comments
 (0)