NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #74 most downloaded on PyPI
FastAPI framework, high performance, easy to learn, fast to code, ready for production
Last release 4 days ago
30 Sep 2026
Release timing varies
gaps range from 8 days to 2 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
8 years old
320 releases · first in 2018
🐛 Allow startup when automatic OpenTelemetry configuration fails. PR #16418 by @tiangolo .
🐛 Fix repeated endpoint wrapping in included routers. PR #16414 by @tiangolo .
One column per quarter.
✨ Add native OpenTelemetry support. PR #16403 by @tiangolo .
setup-uv action to 10.0.1. PR #16249 by @YuriiMotov.commit_in_place input in translate.yml. PR #16216 by @YuriiMotov.zizmor.yml workflow (main -> master). PR #16178 by @YuriiMotov..cache in build-docs.yml. PR #16156 by @YuriiMotov.🐛 Fix support for background tasks and headers from dependencies in app.frontend() . PR #16105 by @tiangolo .
✨ Add app.frontend(check_dir="auto") , to make local development more convenient with fastapi dev . PR #16102 by @tiangolo .
🐛 Fix status_code being ignored for SSE and JSONL streaming endpoints. PR #15937 by @SAURABHSALVE .
status_code being ignored for SSE and JSONL streaming endpoints. PR #15937 by @SAURABHSALVE.format_sse_event docstring rendering of \n\n terminator. PR #15613 by @AshNicolus.🐛 Fix line splitting in format_sse_event to comply with SSE spec. PR #15515 by @Zawwarsami16 .
format_sse_event to comply with SSE spec. PR #15515 by @Zawwarsami16.🐛 Fix response_model_* params ignored for non-generator endpoints with Iterable[..] return type. PR #15093 by @YuriiMotov .
response_model_* params ignored for non-generator endpoints with Iterable[..] return type. PR #15093 by @YuriiMotov.🐛 Fix handling sequences with nested Annotated types. PR #14874 by @YuriiMotov .
🐛 Fix exclude_defaults not propagated to dict keys and values in jsonable_encoder . PR #16043 by @MBGrao .
exclude_defaults not propagated to dict keys and values in jsonable_encoder. PR #16043 by @MBGrao.🐛 Fix stream item type lost when using include_router() . PR #15077 by @alex-raw .
⚡️ Avoid flattening dependencies for OpenAPI. PR #16076 by @tiangolo .
⚡️ Avoid flattening dependencies for request parameters, mainly for OpenAPI. PR #16073 by @tiangolo .
⚡️ Avoid flattening dependencies for body fields. PR #16071 by @tiangolo.
⚡️ Skip unused dependency repeat bookkeeping. PR #16069 by @tiangolo.
⚡️ Avoid repeated dependency flattening in OpenAPI. PR #16067 by @tiangolo.
⚡️ Stop retaining flat dependency trees. PR #16065 by @tiangolo.
♻️ Update the lru_cache limit for dependencies to account for large apps. PR #16062 by @tiangolo.
⚡️ Reduce memory usage in dependencies. PR #16049 by @tiangolo.
🐛 Refactor router route building to make it thread-safe, mainly relevant for tests running in parallel threads (uncommon). PR #16013 by @tiangolo.
🐛 Fix frontend fallback support for doted paths like /users/john.doe. PR #16011 by @tiangolo.
skip_users not being applied. PR #15995 by @YuriiMotov.llm-prompt.md for Hindi. PR #15810 by @YuriiMotov.FASTAPI_LATEST_CHANGES token in bump-pre-commit-hooks workflow. PR #15984 by @YuriiMotov.✨ Support dependencies in app.frontend(), e.g. for automatic cookie authentication for the frontend. PR #15908 by @tiangolo.
app.frontend(), e.g. for automatic cookie authentication for the frontend. PR #15908 by @tiangolo.allow-unsafe-pr-checkout: true. PR #15876 by @YuriiMotov.♻️ Make app.frontend() return 404 for methods other than GET or HEAD with no static file matches. PR #15863 by @tiangolo.
♻️ Refactor Library Skills, make info easier to find for agents. PR #15841 by @tiangolo.
✨ Add support for app.frontend("/", directory="dist") and router.frontend("/", directory="dist"). PR #15800 by @tiangolo.
app.frontend("/", directory="dist") and router.frontend("/", directory="dist"). PR #15800 by @tiangolo.
app.frontend() instructions to Agent Library Skill. PR #15805 by @tiangolo.release-notes.md for typos. PR #15796 by @YuriiMotov.gpt-5.5 model in translate.py, specify -chat to avoid warnings. PR #15792 by @YuriiMotov.✨ Add iter_route_contexts() for advanced use cases that used to use router.routes (e.g. Jupyverse). PR #15785 by @tiangolo.
iter_route_contexts() for advanced use cases that used to use router.routes (e.g. Jupyverse). PR #15785 by @tiangolo.coverage.sh. PR #15772 by @tiangolo.🚨 Fix typing checks for APIRoute. PR #15765 by @tiangolo.
🔥 Remove slim package stub, deprecated for a while. PR #15649 by @tiangolo.
Unblocks ✨ SO MANY THINGS ✨
Before this, router.include_router(other_router) would take each path operation from other_router and "clone" it, or recreate it from scratch.
This would mean that in the end there was only one top level router, part of the app.
The way it is structured here is that there are a few additional classes to handle intermediate metadata for router and route inclusion. That way the information of "router X includes Y and Y includes Z" is stored somewhere, without affecting (recreating / clonning) the final route.
Dependencies for 404: previously I intended to support dependencies that would be executed even for 404, but that would conflict with the fact that a router could not find a match, but the next router did find a match. Executing dependencies in the router that did not find a match would not make sense, they could consume the request, body, etc. This original idea was discarded.
Now router.routes is no longer a plain list of APIRoute objects, it can contain these intermediate objects that can contain additional routers, forming a tree.
Any logic that depended on iterating on the router.routes directly would be affected, that logic cannot expect to be able to extract data from a plain list of routes, as it's no longer a plain list but a tree.
Additionally, any logic that iterated on router.routes to modify them would now also see these new objects, and would not see all the routes in the app.
router.routes should be considered an internal implementation detail, only passed around to the FastAPI functions that need it.
subrouter in mainrouter can be done before adding routes (path operations) to subrouter, because now the the entire object is stored instead of copying the routes.This is not documented yet, so it's not officially supported yet and could change in the future.
But, as APIRoute and APIRouter instances are now preserved, they could be customized.
APIRouter has two new methods, .matches() and .handle(), counterpart to the existing ones in APIRoute. With this a router could customize how it matches and handles requests. For example, it could match only requests that include some specific header, for example for handling versions in headers.
Still, for now, consider this very experimental and potentially changing and breaking in the future.
APIRoute subclasses (undocumented, but alraedy works as desccribed above)APIRouter subclasses (undocumented, but already works as described above)Annotated in inline example in docs/en/docs/tutorial/body-multiple-params.md. PR #15591 by @TheArchons.docs/en/docs/tutorial/security/oauth2-jwt.md. PR #14781 by @zadevhub.changing_dir instead of CLIRunner.isolated_filesystem to set working dir. PR #15616 by @YuriiMotov.httpx2 test dependency to avoid deprecation warning. PR #15603 by @YuriiMotov.♻️ Do not accept underscore headers when using convert_underscores=True (the default). PR #15589 by @tiangolo.
⬆️ Update Pydantic v2 code to address deprecations. PR #15101 by @svlandeg.
⬆️ Support free-threaded Python 3.14t. PR #15149 by @svlandeg.
🔥 Remove April Fool's @app.vibe() 🤪. PR #15363 by @tiangolo.
✨ Add support for @app.vibe(). PR #15280 by @tiangolo.
@app.vibe(). PR #15280 by @tiangolo.
lint.sh. PR #15136 by @svlandeg.⬆️ Increase lower bound to pydantic >=2.9.0. and fix the test suite. PR #15139 by @svlandeg.
pyproject.toml with entrypoint. PR #15075 by @tiangolo.target=_blank for links in docs. PR #15063 by @tiangolo.max_digits and decimal_places. PR #14944 by @YuriiMotov.scripts/people.py. PR #15088 by @YuriiMotov.commit_in_place passed via env variable in translate.yml workflow. PR #15151 by @YuriiMotov.ty to precommit. PR #15091 by @svlandeg.🐛 Fix, avoid yield from a TaskGroup, only as an async context manager, closed in the request async exit stack. PR #15038 by @tiangolo.
docs/en/docs/_llm-test.md. PR #15007 by @adityagiri3600.✨ Add support for Server Sent Events. PR #15030 by @tiangolo.
✨ Add support for streaming JSON Lines and binary data with yield. PR #15022 by @tiangolo.
yield. PR #15022 by @tiangolo.
>=0.40.0 to >=0.46.0, as it's needed to properly unrwap and re-raise exceptions from exception groups.yield. PR #15023 by @tiangolo.await in StreamingResponse code example to allow cancellation. PR #14681 by @casperdcl.docs_src/websockets to docs_src/websockets_ to avoid import errors. PR #14979 by @YuriiMotov.pytest-xdist and pytest-cov. PR #14992 by @YuriiMotov.🔧 Add FastAPI Agent Skill. PR #14982 by @tiangolo.
⬆️ Add support for Starlette 1.0.0+. PR #14987 by @tiangolo.
♻️ Refactor logic to handle OpenAPI and Swagger UI escaping data. PR #14986 by @tiangolo.
🔒️ Add strict_content_type checking for JSON requests. PR #14978 by @tiangolo.
strict_content_type checking for JSON requests. PR #14978 by @tiangolo.
Content-Type header with a valid JSON value, like application/json, and rejects requests that don't.Content-Type header you can disable this with strict_content_type=False.griffelib instead of griffe. PR #14973 by @svlandeg.FastAPI People workflow. PR #14951 by @YuriiMotov.🗑️ Deprecate ORJSONResponse and UJSONResponse. PR #14964 by @tiangolo.
✨ Serialize JSON response with Pydantic (in Rust), when there's a Pydantic return type or response model. PR #14962 by @tiangolo.
⬆️ Upgrade pytest. PR #14959 by @tiangolo.
fastapi-slim. PR #14958 by @tiangolo.fastapi-slim, no more versions will be released, use only "fastapi[standard]" or fastapi. PR #14957 by @tiangolo.♻️ Fix JSON Schema for bytes, use "contentMediaType": "application/octet-stream" instead of "format": "binary". PR #14953 by @tiangolo.
"contentMediaType": "application/octet-stream" instead of "format": "binary". PR #14953 by @tiangolo.master branch and when run by scheduler. PR #14940 by @YuriiMotov.➖ Drop support for Python 3.9. PR #14897 by @tiangolo.
♻️ Update build setup for fastapi-slim, deprecate it, and make it only depend on fastapi. PR #14894 by @tiangolo.
✨ Show a clear error on attempt to include router into itself. PR #14258 by @JavierSanchezCastro.
dict by Mapping on HTTPException.headers. PR #12997 by @rijenkii.dfn tag for definitions instead of abbr in docs. PR #14744 by @YuriiMotov.abbr and dfn tags. PR #14747 by @YuriiMotov.test workflow to run tests with inline-snapshot=review. PR #14876 by @YuriiMotov.🐛 Fix on_startup and on_shutdown parameters of APIRouter. PR #14873 by @YuriiMotov.
on_startup and on_shutdown parameters of APIRouter. PR #14873 by @YuriiMotov.♻️ Refactor and simplify Pydantic v2 (and v1) compatibility internal utils. PR #14862 by @tiangolo.
♻️ Refactor internals, simplify Pydantic v2/v1 utils, create_model_field, better types for lenient_issubclass. PR #14860 by @tiangolo.
create_model_field, better types for lenient_issubclass. PR #14860 by @tiangolo.♻️ Re-implement on_event in FastAPI for compatibility with the next Starlette, while keeping backwards compatibility. PR #14851 by @tiangolo.
✨ Add support for PEP695 TypeAliasType. PR #13920 by @cstruct.
TypeAliasType. PR #13920 by @cstruct.Response type hint as dependency annotation. PR #14794 by @jonathan-fulton.Json[list[str]] type (issue #10997). PR #14616 by @mkanetsuna.advanced-dependencies.md. PR #14815 by @Rayyan-Oumlil.📝 Use WSGIMiddleware from a2wsgi instead of deprecated fastapi.middleware.wsgi.WSGIMiddleware. PR #14756 by @YuriiMotov.
viewport meta tag to improve Swagger UI on mobile devices. PR #14777 by @Joab0.ValidationError schema to include input and ctx. PR #14791 by @jonathan-fulton.Authorization header credentials. PR #14786 by @WaveTheory1.anyOf refs for app-level responses with specified content and model as Union. PR #14463 by @DJMcoder.IncEx type from Pydantic instead of duplicating it. PR #14641 by @mvanderlee.docs_src/app_testing/app_b code example. PR #14573 by @timakaa.docs/en/docs/contributing.md. PR #14757 by @YuriiMotov.response_model when possible. PR #14753 by @YuriiMotov.WSGIMiddleware from a2wsgi instead of deprecated fastapi.middleware.wsgi.WSGIMiddleware. PR #14756 by @YuriiMotov.uk documentation. PR #14795 by @roli2py.llm-prompt.md for Korean language. PR #14763 by @seuthootDev.uv.lock gets the internal label. PR #14759 by @svlandeg.➖ Drop support for pydantic.v1. PR #14609 by @tiangolo.
🔊 Add a custom FastAPIDeprecationWarning. PR #14605 by @tiangolo.
lint job from test CI workflow. PR #14593 by @YuriiMotov.🔊 Add deprecation warnings when using pydantic.v1. PR #14583 by @tiangolo.
➖ Drop support for Pydantic v1, keeping short temporary support for Pydantic v2's pydantic.v1. PR #14575 by @tiangolo.
pydantic.v1. PR #14575 by @tiangolo.
pydantic >=2.7.0.standard dependencies now include pydantic-settings >=2.0.0 and pydantic-extra-types >=2.0.0.docs_src/python_types/tutorial005_py39.py. PR #14565 by @paras-verma7454.…only install 0.124.4. Only marking it as a "breaking change" to make it visible.
markdown-include-variants from 0.0.7 to 0.0.8. PR #14556 by @YuriiMotov.🐛 Fix parameter aliases. PR #14371 by @YuriiMotov.
Your coding agent can read these notes before it upgrades. Set up the MCP server →