NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #46 most downloaded on PyPI
The little ASGI library that shines.
Last release 8 days ago
23 Sep 2026
Ships fairly regularly
a new release about every 6 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
2 versions withdrawn
withdrawn after publishing
8 years old
203 releases · first in 2018
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
One column per quarter.
Add request.state interface, for storing arbitrary additional information.
Add request.state interface, for storing arbitrary additional information.
Support disabling GraphiQL with GraphQLApp(..., graphiql=False) .
DatabaseMiddleware is now dropped in favour of databases
DatabaseMiddleware is now dropped in favour of databases
Templates are no longer configured on the application instance. Use templates = Jinja2Templates(directory=...) and return templates.TemplateResponse('index.html', {"request": request})
Schema generation is no longer attached to the application instance. Use schemas = SchemaGenerator(...) and return 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.
Nothing published for this version
Add Lifespan routing component.
Ensure templating does not strictly require jinja2 to be installed.
templates = Jinja2Templates(directory=...) . Existing API remains in place, but is no longer documented, and will be deprecated in due course. See the…
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.
Add MySQL database support.
Add host-based routing.
The executor argument is expected to be deprecated in the next median or major release.
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 an executor_class argument, which should be used in preference to the existing executor argument. Resolves an issue with async executors being instantiated before the event loop was setup. The executor argument is expected to be deprecated in the next median or major release.
Authentication and the @requires decorator now support WebSocket endpoints.
MultiDict and ImmutableMultiDict classes are available in uvicorn.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.
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 of urlparse .
Support @requires(...) on class methods.
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 CommaSeparatedStrings datatype.
Add TemplateResponse .
Add CommaSeparatedStrings datatype.
Add BackgroundTasks for multiple tasks.
Common subclass for Request and WebSocket , to eg. share session 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 or Secret for SessionMiddleware(secret_key=...) .
Add datastructures.DatabaseURL .
Add config.environ .
Add datastructures.Secret .
Add datastructures.DatabaseURL .
- Add config.Config(".env")
Add request to GraphQL context.
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 of LifespanContext .
TestClient can now be used as a context manager, instead of LifespanContext .
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.
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 HTTP 304 cache responses from StaticFiles .
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() .
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) .
Add support for @app.exception_handler(404) .
Ensure handled exceptions are not seen as errors by the middleware stack.
Add starlette.concurrency.run_in_threadpool . Now handles contextvar support.
Add name= support to app.mount() . This allows eg: app.mount('/static', StaticFiles(directory='static'), name='static') .
Add support for @app.middleware("http") decorator.
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 app.schema_generator = SchemaGenerator(...) .
Add app.schema_generator = SchemaGenerator(...) .
Add app.schema property.
Add OpenAPIResponse(...) .
Ensure url_path_for works with Mount('/{some_path_params}').
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 request.session , with SessionMiddleware .
Added support for BaseHTTPMiddleware , which provides a standard request/response interface over a regular ASGI middleware.
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:
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.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →