diff --git a/README.md b/README.md
index 6f13f9eae..a8a0e37b5 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ The key features are:
* estimation based on tests on an internal development team, building production applications.
-## Sponsors { #sponsors }
+## Sponsors
@@ -67,7 +67,7 @@ The key features are:
Other sponsors
-## Opinions { #opinions }
+## Opinions
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
@@ -113,7 +113,7 @@ The key features are:
---
-## **Typer**, the FastAPI of CLIs { #typer-the-fastapi-of-clis }
+## **Typer**, the FastAPI of CLIs
@@ -121,14 +121,14 @@ If you are building a CLI app to be
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
-## Requirements { #requirements }
+## Requirements
FastAPI stands on the shoulders of giants:
* Starlette for the web parts.
* Pydantic for the data parts.
-## Installation { #installation }
+## Installation
Create and activate a virtual environment and then install FastAPI:
@@ -144,9 +144,9 @@ $ pip install "fastapi[standard]"
**Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals.
-## Example { #example }
+## Example
-### Create it { #create-it }
+### Create it
Create a file `main.py` with:
@@ -197,7 +197,7 @@ If you don't know, check the _"In a hurry?"_ section about
-### Check it { #check-it }
+### Check it
Open your browser at http://127.0.0.1:8000/items/5?q=somequery.
@@ -256,7 +256,7 @@ You already created an API that:
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
-### Interactive API docs { #interactive-api-docs }
+### Interactive API docs
Now go to http://127.0.0.1:8000/docs.
@@ -264,7 +264,7 @@ You will see the automatic interactive API documentation (provided by http://127.0.0.1:8000/redoc.
@@ -272,7 +272,7 @@ You will see the alternative automatic documentation (provided by http://127.0.0.1:8000/docs.
@@ -326,7 +326,7 @@ Now go to http://127.0.0.1:8000/redoc.
@@ -334,7 +334,7 @@ And now, go to one of the fastest Python frameworks available, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
To understand more about it, see the section Benchmarks.
-## Dependencies { #dependencies }
+## Dependencies
FastAPI depends on Pydantic and Starlette.
-### `standard` Dependencies { #standard-dependencies }
+### `standard` Dependencies
When you install FastAPI with `pip install "fastapi[standard]"` it comes with the `standard` group of optional dependencies:
@@ -476,15 +476,15 @@ Used by FastAPI:
* `fastapi-cli[standard]` - to provide the `fastapi` command.
* This includes `fastapi-cloud-cli`, which allows you to deploy your FastAPI application to FastAPI Cloud.
-### Without `standard` Dependencies { #without-standard-dependencies }
+### Without `standard` Dependencies
If you don't want to include the `standard` optional dependencies, you can install with `pip install fastapi` instead of `pip install "fastapi[standard]"`.
-### Without `fastapi-cloud-cli` { #without-fastapi-cloud-cli }
+### Without `fastapi-cloud-cli`
If you want to install FastAPI with the standard dependencies but without the `fastapi-cloud-cli`, you can install with `pip install "fastapi[standard-no-fastapi-cloud-cli]"`.
-### Additional Optional Dependencies { #additional-optional-dependencies }
+### Additional Optional Dependencies
There are some additional dependencies you might want to install.
@@ -498,6 +498,6 @@ Additional optional FastAPI dependencies:
* orjson
- Required if you want to use `ORJSONResponse`.
* ujson
- Required if you want to use `UJSONResponse`.
-## License { #license }
+## License
This project is licensed under the terms of the MIT license.
diff --git a/scripts/docs.py b/scripts/docs.py
index 8462e2bc1..56ffb9d36 100644
--- a/scripts/docs.py
+++ b/scripts/docs.py
@@ -44,6 +44,8 @@ en_config_path: Path = en_docs_path / mkdocs_name
site_path = Path("site").absolute()
build_site_path = Path("site_build").absolute()
+header_with_permalink_pattern = re.compile(r"^(#{1,6}) (.+?)(\s*\{\s*#.*\s*\})\s*$")
+
@lru_cache
def is_mkdocs_insiders() -> bool:
@@ -154,9 +156,21 @@ index_sponsors_template = """
"""
+def remove_header_permalinks(content: str):
+ lines: list[str] = []
+ for line in content.split("\n"):
+ match = header_with_permalink_pattern.match(line)
+ if match:
+ hashes, title, *_ = match.groups()
+ line = f"{hashes} {title}"
+ lines.append(line)
+ return "\n".join(lines)
+
+
def generate_readme_content() -> str:
en_index = en_docs_path / "docs" / "index.md"
content = en_index.read_text("utf-8")
+ content = remove_header_permalinks(content) # remove permalinks from headers
match_pre = re.search(r"\n\n", content)
match_start = re.search(r"", content)
match_end = re.search(r"", content)