toc_depth |
---|
2 |
- Drop Python 3.8 support #2823.
- Remove
ExceptionMiddleware
import proxy fromstarlette.exceptions
module #2826. - Remove deprecated
WS_1004_NO_STATUS_RCVD
andWS_1005_ABNORMAL_CLOSURE
#2827.
- Remove deprecated
allow_redirects
argument fromTestClient
#2808.
- Make UUID path parameter conversion more flexible #2806.
- Raise
ClientDisconnect
onStreamingResponse
#2732.
- Use ETag from headers when parsing If-Range in FileResponse #2761.
- Follow directory symlinks in
StaticFiles
whenfollow_symlinks=True
#2711. - Bump minimum
python-multipart
version to0.0.18
0ba8395. - Bump minimum
httpx
version to0.27.0
#2773.
- Exclude the query parameters from the
scope[raw_path]
on theTestClient
#2716. - Replace
dict
byMapping
onHTTPException.headers
#2749. - Correct middleware argument passing and improve factory pattern #2752.
- Revert bump on
python-multipart
onstarlette[full]
extras #2737.
- Bump minimum
python-multipart
version to0.0.13
#2734. - Change
python-multipart
import topython_multipart
#2733.
- Allow to raise
HTTPException
beforewebsocket.accept()
#2725.
This release fixes a Denial of service (DoS) via multipart/form-data
requests.
You can view the full security advisory: GHSA-f96h-pmfr-66vw
- Add
max_part_size
toMultiPartParser
to limit the size of parts inmultipart/form-data
requests fd038f3.
- Allow use of
request.url_for
when only "app" scope is available #2672. - Fix internal type hints to support
python-multipart==0.0.12
#2708.
- Avoid regex re-compilation in
responses.py
andschemas.py
#2700. - Improve performance of
get_route_path
by removing regular expression usage #2701. - Consider
FileResponse.chunk_size
when handling multiple ranges #2703. - Use
token_hex
for generating multipart boundary strings #2702.
- Add support for HTTP Range to
FileResponse
#2697.
- Close unclosed
MemoryObjectReceiveStream
inTestClient
#2693.
- Schedule
BackgroundTasks
from withinBaseHTTPMiddleware
#2688. This behavior was removed in 0.38.3, and is now restored.
- Ensure accurate
root_path
removal inget_route_path
function #2600.
- Support for Python 3.13 #2662.
- Don't poll for disconnects in
BaseHTTPMiddleware
viaStreamingResponse
#2620.
- Not assume all routines have
__name__
onrouting.get_name()
#2648.
- Revert "Add support for ASGI pathsend extension" #2649.
- Allow use of
memoryview
inStreamingResponse
andResponse
#2576 and #2577. - Send 404 instead of 500 when filename requested is too long on
StaticFiles
#2583.
- Fail fast on invalid
Jinja2Template
instantiation parameters #2568. - Check endpoint handler is async only once #2536.
- Add proper synchronization to
WebSocketTestSession
#2597.
- Add
bytes
to_RequestData
type #2510.
- Revert "Turn
scope["client"]
toNone
onTestClient
(#2377)" #2525. - Remove deprecated
app
argument passed tohttpx.Client
on theTestClient
#2526.
- Warn instead of raise for missing env file on
Config
#2485.
- Support the WebSocket Denial Response ASGI extension #2041.
- Create
anyio.Event
on async context #2459.
- Check if "extensions" in scope before checking the extension #2438.
- Add support for ASGI
pathsend
extension #2435. - Cancel
WebSocketTestSession
on close #2427. - Raise
WebSocketDisconnect
whenWebSocket.send()
exceptsIOError
#2425. - Raise
FileNotFoundError
when theenv_file
parameter onConfig
is not valid #2422.
- Stop using the deprecated "method" parameter in
FileResponse
inside ofStaticFiles
#2406. - Make
typing-extensions
optional again #2409.
- Add
*args
toMiddleware
and improve its type hints #2381.
- Use
Iterable
insteadIterator
oniterate_in_threadpool
#2362.
- Handle
root_path
to keep compatibility with mounted ASGI applications and WSGI #2400. - Turn
scope["client"]
toNone
onTestClient
#2377.
- Deprecate
FileResponse(method=...)
parameter #2366.
- Do not overwrite
"path"
and"root_path"
scope keys #2352. - Set
ensure_ascii=False
onjson.dumps()
forWebSocket.send_json()
#2341.
- Revert mkdocs-material from 9.1.17 to 9.4.7 #2326.
- Inherit from
HTMLResponse
instead ofResponse
on_TemplateResponse
#2274. - Restore the
Response.render
type annotation to its pre-0.31.0 state #2264.
- Fix import error when
exceptiongroup
isn't available #2231. - Set
url_for
global for custom Jinja environments #2230.
- Officially support Python 3.12 #2214.
- Support AnyIO 4.0 #2211.
- Strictly type annotate Starlette (strict mode on mypy) #2180.
- Don't group duplicated headers on a single string when using the
TestClient
#2219.
- Drop Python 3.7 support #2178.
- Add
follow_redirects
parameter toTestClient
#2207. - Add
__str__
toHTTPException
andWebSocketException
#2181. - Warn users when using
lifespan
together withon_startup
/on_shutdown
#2193. - Collect routes from
Host
to generate the OpenAPI schema #2183. - Add
request
argument toTemplateResponse
#2191.
- Stop
body_stream
in casemore_body=False
onBaseHTTPMiddleware
#2194.
- Reuse
Request
's body buffer for call_next inBaseHTTPMiddleware
#1692. - Move exception handling logic to
Route
#2026.
- Add
env
parameter toJinja2Templates
, and deprecate**env_options
#2159. - Add clear error message when
httpx
is not installed #2177.
- Allow "name" argument on
templates url_for()
#2127.
This release fixes a path traversal vulnerability in StaticFiles
. You can view the full security advisory:
https://github.com/encode/starlette/security/advisories/GHSA-v5gw-mw7f-84px
- Minify JSON websocket data via
send_json
#2128
- Replace
commonprefix
bycommonpath
onStaticFiles
1797de4. - Convert ImportErrors into ModuleNotFoundError #2135.
- Correct the RuntimeError message content in websockets #2141.
- Fix typing of Lifespan to allow subclasses of Starlette #2077.
- Replace reference from Events to Lifespan on the mkdocs.yml #2072.
- Support lifespan state #2060, #2065 and #2064.
- Change
url_for
signature to return aURL
instance #1385.
- Allow "name" argument on
url_for()
andurl_path_for()
#2050.
- Deprecate
on_startup
andon_shutdown
events #2070.
- Limit the number of fields and files when parsing
multipart/form-data
on theMultipartParser
8c74c2c and #2036.
- Allow
StaticFiles
to follow symlinks #1683. - Allow
Request.form()
as a context manager #1903. - Add
size
attribute toUploadFile
#1405. - Add
env_prefix
argument toConfig
#1990. - Add template context processors #1904.
- Support
str
anddatetime
onexpires
parameter on theResponse.set_cookie
method #1908.
- Lazily build the middleware stack #2017.
- Make the
file
argument required onUploadFile
#1413. - Use debug extension instead of custom response template extension #1991.
- Fix url parsing of ipv6 urls on
URL.replace
#1965.
- Only stop receiving stream on
body_stream
if body is empty on theBaseHTTPMiddleware
#1940.
- Add
headers
parameter to theTestClient
#1966.
- Deprecate
Starlette
andRouter
decorators #1897.
- Fix bug on
FloatConvertor
regex #1973.
- Bypass
GZipMiddleware
when response includesContent-Encoding
#1901.
- Remove unneeded
unquote()
from query parameters on theTestClient
#1953. - Make sure
MutableHeaders._list
is actually alist
#1917. - Import compatibility with the next version of
AnyIO
#1936.
This release replaces the underlying HTTP client used on the TestClient
(requests
β‘οΈ httpx
), and as those clients differ a bit on their API, your test suite will likely break. To make the migration smoother, you can use the bump-testclient
tool.
- Replace
requests
withhttpx
inTestClient
#1376.
- Add
WebSocketException
and support for WebSocket exception handlers #1263. - Add
middleware
parameter toMount
class #1649. - Officially support Python 3.11 #1863.
- Implement
__repr__
for route classes #1864.
- Fix bug on which
BackgroundTasks
were cancelled when usingBaseHTTPMiddleware
and client disconnected #1715.
- Remove converter from path when generating OpenAPI schema #1648.
- Revert "Allow
StaticFiles
to follow symlinks" #1681.
- Improve detection of async callables #1444.
- Send 400 (Bad Request) when
boundary
is missing #1617. - Send 400 (Bad Request) when missing "name" field on
Content-Disposition
header #1643. - Do not send empty data to
StreamingResponse
onBaseHTTPMiddleware
#1609. - Add
__bool__
dunder forSecret
#1625.
- Fix inference of
Route.name
when created from methods #1553. - Avoid
TypeError
onwebsocket.disconnect
when code isNone
#1574.
- Deprecate
WS_1004_NO_STATUS_RCVD
andWS_1005_ABNORMAL_CLOSURE
in favor ofWS_1005_NO_STATUS_RCVD
andWS_1006_ABNORMAL_CLOSURE
, as the previous constants didn't match the WebSockets specs #1580.
- Error handler will always run, even if the error happens on a background task #761.
- Add
headers
parameter toHTTPException
#1435. - Internal responses with
405
status code insert anAllow
header, as described by RFC 7231 #1436. - The
content
argument inJSONResponse
is now required #1431. - Add custom URL convertor register #1437.
- Add content disposition type parameter to
FileResponse
#1266. - Add next query param with original request URL in requires decorator #920.
- Add
raw_path
toTestClient
scope #1445. - Add union operators to
MutableHeaders
#1240. - Display missing route details on debug page #1363.
- Change
anyio
required version range to>=3.4.0,<5.0
#1421 and #1460. - Add
typing-extensions>=3.10
requirement - used only on lower versions than Python 3.10 #1475.
- Prevent
BaseHTTPMiddleware
from hiding errors ofStreamingResponse
and mounted applications #1459. SessionMiddleware
uses an explicitpath=...
, instead of defaulting to the ASGI 'root_path' #1512.Request.client
is now compliant with the ASGI specifications #1462.- Raise
KeyError
at early stage for missing boundary #1349.
- Change default chunk size from 4Kb to 64Kb on
FileResponse
#1345. - Add support for
functools.partial
inWebSocketRoute
#1356. - Add
StaticFiles
packages with directory #1350. - Allow environment options in
Jinja2Templates
#1401. - Allow HEAD method on
HttpEndpoint
#1346. - Accept additional headers on
websocket.accept
message #1361 and #1422. - Add
reason
toWebSocket
close ASGI event #1417. - Add headers attribute to
UploadFile
#1382. - Don't omit
Content-Length
header forContent-Length: 0
cases #1395. - Don't set headers for responses with 1xx, 204 and 304 status code #1397.
SessionMiddleware.max_age
now acceptsNone
, so cookie can last as long as the browser session #1387.
- Tweak
hashlib.md5()
function onFileResponse
s ETag generation. The parameterusedforsecurity
flag is set toFalse
, if the flag is available on the system. This fixes an error raised on systems with FIPS enabled #1366 and #1410. - Fix
path_params
type onurl_path_for()
method i.e. turnstr
intoAny
#1341. Host
now ignoresport
on routing #1322.
- Fix
IndexError
in authenticationrequires
when wrapped function arguments are distributed between*args
and**kwargs
#1335.
Response.delete_cookie
now accepts the same parameters asResponse.set_cookie
#1228.- Update the
Jinja2Templates
constructor to allowPathLike
#1292.
- Fix BadSignature exception handling in SessionMiddleware #1264.
- Change
HTTPConnection.__getitem__
return type fromstr
totyping.Any
#1118. - Change
ImmutableMultiDict.getlist
return type fromtyping.List[str]
totyping.List[typing.Any]
#1235. - Handle
OSError
exceptions onStaticFiles
#1220. - Fix
StaticFiles
404.html in HTML mode #1314. - Prevent anyio.ExceptionGroup in error views under a BaseHTTPMiddleware #1262.
- Remove GraphQL support #1198.
starlette.websockets.WebSocket
instances are now hashable and compare by identity #1039- A number of fixes related to running task groups in lifespan #1213, #1227
- The method
starlette.templates.Jinja2Templates.get_env
was removed #1218 - The ClassVar
starlette.testclient.TestClient.async_backend
was removed, the backend is now configured using constructor kwargs #1211 - Passing an Async Generator Function or a Generator Function to
starlette.routing.Router(lifespan=)
is deprecated. You should wrap your lifespan in@contextlib.asynccontextmanager
. #1227 #1110
This release includes major changes to the low-level asynchronous parts of Starlette. As a result, Starlette now depends on AnyIO and some minor API changes have occurred. Another significant change with this release is the deprecation of built-in GraphQL support.
- Starlette now supports Trio as an async runtime via AnyIO - #1157.
TestClient.websocket_connect()
now must be used as a context manager.- Initial support for Python 3.10 - #1201.
- The compression level used in
GZipMiddleware
is now adjustable - #1128.
- Several fixes to
CORSMiddleware
. See #1111, #1112, #1113, #1199. - Improved exception messages in the case of duplicated path parameter names - #1177.
RedirectResponse
now usesquote
instead ofquote_plus
encoding for theLocation
header to better match the behaviour in other frameworks such as Django - #1164.- Exception causes are now preserved in more cases - #1158.
- Session cookies now use the ASGI root path in the case of mounted applications - #1147.
- Fixed a cache invalidation bug when static files were deleted in certain circumstances - #1023.
- Improved memory usage of
BaseHTTPMiddleware
when handling large responses - #1012 fixed via #1157
- Built-in GraphQL support via the
GraphQLApp
class has been deprecated and will be removed in a future release. Please see #619. GraphQL is not supported on Python 3.10. - The
executor
parameter toGraphQLApp
was removed. Useexecutor_class
instead. - The
workers
parameter toWSGIMiddleware
was removed. This hasn't had any effect since Starlette v0.6.3.
- Fixed
ServerErrorMiddleware
compatibility with Python 3.9.1/3.8.7 when debug mode is enabled - #1132. - Fixed unclosed socket
ResourceWarning
s when using theTestClient
with WebSocket endpoints - #1132. - Improved detection of
async
endpoints wrapped infunctools.partial
on Python 3.8+ - #1106.
UJSONResponse
was removed (this change was intended to be included in 0.14.0). Please see the documentation for how to implement responses using custom JSON serialization - #1074.
- Starlette now officially supports Python3.9.
- In
StreamingResponse
, allow custom async iterator such as objects from classes implementing__aiter__
. - Allow usage of
functools.partial
async handlers in Python versions 3.6 and 3.7. - Add 418 I'm A Teapot status code.
- Create tasks from handler coroutines before sending them to
asyncio.wait
. - Use
format_exception
instead offormat_tb
inServerErrorMiddleware
'sdebug
responses. - Be more lenient with handler arguments when using the
requires
decorator.
-
Revert
Queue(maxsize=1)
fix forBaseHTTPMiddleware
middleware classes and streaming responses. -
The
StaticFiles
constructor now allowspathlib.Path
in addition to strings for itsdirectory
argument.
- Fix high memory usage when using
BaseHTTPMiddleware
middleware classes and streaming responses.
- Fix 404 errors with
StaticFiles
.
- Add support for
Starlette(lifespan=...)
functions. - More robust path-traversal check in StaticFiles app.
- Fix WSGI PATH_INFO encoding.
- RedirectResponse now accepts optional background parameter
- Allow path routes to contain regex meta characters
- Treat ASGI HTTP 'body' as an optional key.
- Don't use thread pooling for writing to in-memory upload files.
- Switch to promoting application configuration on init style everywhere. This means dropping the decorator style in favour of declarative routing tables and middleware definitions.
- Fix
request.url_for()
for the Mount-within-a-Mount case.
- Fix
request.url_for()
when an ASGIroot_path
is being used.
- Add
URL.include_query_params(**kwargs)
- Add
URL.replace_query_params(**kwargs)
- Add
URL.remove_query_params(param_names)
request.state
properly persisting across middleware.- Added
request.scope
interface.
- Switch to ASGI 3.0.
- Fixes to CORS middleware.
- Add
StaticFiles(html=True)
support. - Fix path quoting in redirect responses.
- Add
request.state
interface, for storing arbitrary additional information. - Support disabling GraphiQL with
GraphQLApp(..., graphiql=False)
.
DatabaseMiddleware
is now dropped in favour ofdatabases
- Templates are no longer configured on the application instance. Use
templates = Jinja2Templates(directory=...)
andreturn templates.TemplateResponse('index.html', {"request": request})
- Schema generation is no longer attached to the application instance. Use
schemas = SchemaGenerator(...)
andreturn schemas.OpenAPIResponse(request=request)
LifespanMiddleware
is dropped in favor of router-based lifespan handling.- Application instances now accept a
routes
argument,Starlette(routes=[...])
- Schema generation now includes mounted routes.
- Add
Lifespan
routing component.
- Ensure
templating
does not strictly requirejinja2
to be installed.
- Templates are now configured independently from the application instance.
templates = Jinja2Templates(directory=...)
. Existing API remains in place, but is no longer documented, and will be deprecated in due course. See the template documentation for more details.
- Move to independent
databases
package instead ofDatabaseMiddleware
. Existing API remains in place, but is no longer documented, and will be deprecated in due course.
- Don't drop explicit port numbers on redirects from
HTTPSRedirectMiddleware
.
- Add MySQL database support.
- Add host-based routing.
- WebSockets now default to sending/receiving JSON over text data frames. Use
.send_json(data, mode="binary")
and.receive_json(mode="binary")
for binary framing. GraphQLApp
now takes anexecutor_class
argument, which should be used in preference to the existingexecutor
argument. Resolves an issue with async executors being instantiated before the event loop was setup. Theexecutor
argument is expected to be deprecated in the next median or major release.- Authentication and the
@requires
decorator now support WebSocket endpoints. MultiDict
andImmutableMultiDict
classes are available inuvicorn.datastructures
.QueryParams
is now instantiated with standard dict-style*args, **kwargs
arguments.
- Session cookies now include browser 'expires', in addition to the existing signed expiry.
request.form()
now returns a multi-dict interface.- The query parameter multi-dict implementation now mirrors
dict
more correctly for the behavior of.keys()
,.values()
, and.items()
when multiple same-key items occur. - Use
urlsplit
throughout in favor ofurlparse
.
- Support
@requires(...)
on class methods. - Apply URL escaping to form data.
- Support
HEAD
requests automatically. - Add
await request.is_disconnected()
. - Pass operationName to GraphQL executor.
- Add
TemplateResponse
. - Add
CommaSeparatedStrings
datatype. - Add
BackgroundTasks
for multiple tasks. - Common subclass for
Request
andWebSocket
, to eg. sharesession
functionality. - Expose remote address with
request.client
.
- Add
request.database.executemany
.
- Ensure that
AuthenticationMiddleware
handles lifespan messages correctly.
- Add
AuthenticationMiddleware
, and@requires()
decorator.
- Support either
str
orSecret
forSessionMiddleware(secret_key=...)
.
- Add
config.environ
. - Add
datastructures.Secret
. - Add
datastructures.DatabaseURL
.
- Add
config.Config(".env")
- Add optional database support.
- Add
request
to GraphQL context. - Hide any password component in
URL.__repr__
.
- Handle startup/shutdown errors properly.
TestClient
can now be used as a context manager, instead ofLifespanContext
.- Lifespan is now handled as middleware. Startup and Shutdown events are visible throughout the middleware stack.
- Better support for third-party API schema generators.
- Support chunked requests with TestClient.
- Cleanup asyncio tasks properly with WSGIMiddleware.
- Support using TestClient within endpoints, for service mocking.
- Session cookies are now set on the root path.
- Support URL convertors.
- Support HTTP 304 cache responses from
StaticFiles
. - Resolve character escaping issue with form data.
- Default to empty body on responses.
- Add 'name' argument to
@app.route()
. - Use 'Host' header for URL reconstruction.
- StaticFiles no longer reads the file for responses to
HEAD
requests.
- Add a default templating configuration with Jinja2.
Allows the following:
app = Starlette(template_directory="templates")
@app.route('/')
async def homepage(request):
# `url_for` is available inside the template.
template = app.get_template('index.html')
content = template.render(request=request)
return HTMLResponse(content)
- Add support for
@app.exception_handler(404)
. - Ensure handled exceptions are not seen as errors by the middleware stack.
- Add
max_age
, and use timestamp-signed cookies. Defaults to two weeks.
- Ensure cookies are strictly HTTP correct.
- Check directory exists on instantiation.
- Add
starlette.concurrency.run_in_threadpool
. Now handlescontextvar
support.
- Add
name=
support toapp.mount()
. This allows eg:app.mount('/static', StaticFiles(directory='static'), name='static')
.
- Add support for
@app.middleware("http")
decorator.
- Add "endpoint" to ASGI scope.
- Improve debug traceback information & styling.
- Support mounted URL lookups with "path=", eg.
url_for('static', path=...)
. - Support nested URL lookups, eg.
url_for('admin:user', username=...)
. - Add redirect slashes support.
- Add www redirect support.
- Add background task support to
FileResponse
andStreamingResponse
.
- Add
app.schema_generator = SchemaGenerator(...)
. - Add
app.schema
property. - Add
OpenAPIResponse(...)
.
- Drop
app.add_graphql_route("/", ...)
in favor of more consistentapp.add_route("/", GraphQLApp(...))
.
- Support routing to methods.
- Ensure
url_path_for
works with Mount('/{some_path_params}'). - Fix Router(default=) argument.
- Support repeated paths, like:
@app.route("/", methods=["GET"])
,@app.route("/", methods=["POST"])
- Use the default ThreadPoolExecutor for all sync endpoints.
Added support for request.session
, with SessionMiddleware
.
Added support for BaseHTTPMiddleware
, which provides a standard
request/response interface over a regular ASGI middleware.
This means you can write ASGI middleware while still working at a request/response level, rather than handling ASGI messages directly.
from starlette.applications import Starlette
from starlette.middleware.base import BaseHTTPMiddleware
class CustomMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
response = await call_next(request)
response.headers['Custom-Header'] = 'Example'
return response
app = Starlette()
app.add_middleware(CustomMiddleware)
The biggest change in 0.6 is that endpoint signatures are no longer:
async def func(request: Request, **kwargs) -> Response
Instead we just use:
async def func(request: Request) -> Response
The path parameters are available on the request as request.path_params
.
This is different to most Python webframeworks, but I think it actually ends up being much more nicely consistent all the way through.
Request and WebSocketSession now support URL reversing with request.url_for(name, **path_params)
.
This method returns a fully qualified URL
instance.
The URL instance is a string-like object.
Applications now support URL path reversing with app.url_path_for(name, **path_params)
.
This method returns a URL
instance with the path and scheme set.
The URL instance is a string-like object, and will return only the path if coerced to a string.
Applications now support a .routes
parameter, which returns a list of [Route|WebSocketRoute|Mount]
.
The low level components to Router
now match the @app.route()
, @app.websocket_route()
, and app.mount()
signatures.