Browse Source

♻️ Add support for `pip install "fastapi[standard]"` with standard dependencies and `python -m fastapi` (#11935)

* ♻️ Add support for `pip install "fastapi[standard]"` and make `fastapi` not include the optional standard dependencies

* 📝 Update docs to include new fastapi[standard]

*  Add new stub fastapi command that tells people to install fastapi[standard]

*  Add tests for new stub CLI

* 🔧 Add new command fastapi in main fastapi project, for when fastapi-cli is not installed

* ✏️ Fix types

* 📝 Add note about quotes when installing fastapi[standard]

* 📝 Update docs about standard extra dependencies

* ⬆️ Upgrade fastapi-cli
pull/11940/head
Sebastián Ramírez 8 months ago
committed by GitHub
parent
commit
a25c92ceb9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 41
      README.md
  2. 2
      docs/em/docs/index.md
  3. 2
      docs/em/docs/tutorial/index.md
  4. 2
      docs/en/docs/deployment/docker.md
  5. 2
      docs/en/docs/deployment/manually.md
  6. 14
      docs/en/docs/deployment/versions.md
  7. 2
      docs/en/docs/fastapi-cli.md
  8. 41
      docs/en/docs/index.md
  9. 6
      docs/en/docs/tutorial/index.md
  10. 4
      docs/en/docs/tutorial/security/first-steps.md
  11. 3
      fastapi/__main__.py
  12. 13
      fastapi/cli.py
  13. 27
      pdm_build.py
  14. 36
      pyproject.toml
  15. 32
      tests/test_fastapi_cli.py

41
README.md

@ -135,13 +135,15 @@ FastAPI stands on the shoulders of giants:
<div class="termy">
```console
$ pip install fastapi
$ pip install "fastapi[standard]"
---> 100%
```
</div>
**Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals.
## Example
### Create it
@ -452,11 +454,15 @@ To understand more about it, see the section <a href="https://fastapi.tiangolo.c
## Dependencies
FastAPI depends on Pydantic and Starlette.
### `standard` Dependencies
When you install FastAPI with `pip install "fastapi[standard]"` it comes the `standard` group of optional dependencies:
Used by Pydantic:
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - for settings management.
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - for extra types to be used with Pydantic.
Used by Starlette:
@ -466,33 +472,26 @@ Used by Starlette:
Used by FastAPI / Starlette:
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application. This includes `uvicorn[standard]`, which includes some dependencies (e.g. `uvloop`) needed for high performance serving.
* `fastapi-cli` - to provide the `fastapi` command.
When you install `fastapi` it comes these standard dependencies.
Additional optional dependencies:
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
### Without `standard` Dependencies
## `fastapi-slim`
If you don't want to include the `standard` optional dependencies, you can install with `pip install fastapi` instead of `pip install "fastapi[standard]"`.
If you don't want the extra standard optional dependencies, install `fastapi-slim` instead.
### Additional Optional Dependencies
When you install with:
There are some additional dependencies you might want to install.
```bash
pip install fastapi
```
Additional optional Pydantic dependencies:
...it includes the same code and dependencies as:
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - for settings management.
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - for extra types to be used with Pydantic.
```bash
pip install "fastapi-slim[standard]"
```
Additional optional FastAPI dependencies:
The standard extra dependencies are the ones mentioned above.
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
## License

2
docs/em/docs/index.md

@ -133,7 +133,7 @@ FastAPI 🧍 🔛 ⌚ 🐘:
<div class="termy">
```console
$ pip install fastapi
$ pip install "fastapi[standard]"
---> 100%
```

2
docs/em/docs/tutorial/index.md

@ -58,7 +58,7 @@ $ pip install "fastapi[all]"
👉 ⚫️❔ 👆 🔜 🎲 🕐 👆 💚 🛠️ 👆 🈸 🏭:
```
pip install fastapi
pip install "fastapi[standard]"
```
`uvicorn` 👷 💽:

2
docs/en/docs/deployment/docker.md

@ -113,7 +113,7 @@ You would of course use the same ideas you read in [About FastAPI versions](vers
For example, your `requirements.txt` could look like:
```
fastapi>=0.112.0,<0.113.0
fastapi[standard]>=0.113.0,<0.114.0
pydantic>=2.7.0,<3.0.0
```

2
docs/en/docs/deployment/manually.md

@ -103,7 +103,7 @@ But you can also install an ASGI server manually:
That including `uvloop`, the high-performance drop-in replacement for `asyncio`, that provides the big concurrency performance boost.
When you install FastAPI with something like `pip install fastapi` you already get `uvicorn[standard]` as well.
When you install FastAPI with something like `pip install "fastapi[standard]"` you already get `uvicorn[standard]` as well.
=== "Hypercorn"

14
docs/en/docs/deployment/versions.md

@ -12,23 +12,23 @@ You can create production applications with **FastAPI** right now (and you have
The first thing you should do is to "pin" the version of **FastAPI** you are using to the specific latest version that you know works correctly for your application.
For example, let's say you are using version `0.45.0` in your app.
For example, let's say you are using version `0.112.0` in your app.
If you use a `requirements.txt` file you could specify the version with:
```txt
fastapi==0.45.0
fastapi[standard]==0.112.0
```
that would mean that you would use exactly the version `0.45.0`.
that would mean that you would use exactly the version `0.112.0`.
Or you could also pin it with:
```txt
fastapi>=0.45.0,<0.46.0
fastapi[standard]>=0.112.0,<0.113.0
```
that would mean that you would use the versions `0.45.0` or above, but less than `0.46.0`, for example, a version `0.45.2` would still be accepted.
that would mean that you would use the versions `0.112.0` or above, but less than `0.113.0`, for example, a version `0.112.2` would still be accepted.
If you use any other tool to manage your installations, like Poetry, Pipenv, or others, they all have a way that you can use to define specific versions for your packages.
@ -78,10 +78,10 @@ So, you can just let **FastAPI** use the correct Starlette version.
Pydantic includes the tests for **FastAPI** with its own tests, so new versions of Pydantic (above `1.0.0`) are always compatible with FastAPI.
You can pin Pydantic to any version above `1.0.0` that works for you and below `2.0.0`.
You can pin Pydantic to any version above `1.0.0` that works for you.
For example:
```txt
pydantic>=1.2.0,<2.0.0
pydantic>=2.7.0,<3.0.0
```

2
docs/en/docs/fastapi-cli.md

@ -2,7 +2,7 @@
**FastAPI CLI** is a command line program that you can use to serve your FastAPI app, manage your FastAPI project, and more.
When you install FastAPI (e.g. with `pip install fastapi`), it includes a package called `fastapi-cli`, this package provides the `fastapi` command in the terminal.
When you install FastAPI (e.g. with `pip install "fastapi[standard]"`), it includes a package called `fastapi-cli`, this package provides the `fastapi` command in the terminal.
To run your FastAPI app for development, you can use the `fastapi dev` command:

41
docs/en/docs/index.md

@ -131,13 +131,15 @@ FastAPI stands on the shoulders of giants:
<div class="termy">
```console
$ pip install fastapi
$ pip install "fastapi[standard]"
---> 100%
```
</div>
**Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals.
## Example
### Create it
@ -448,11 +450,15 @@ To understand more about it, see the section <a href="https://fastapi.tiangolo.c
## Dependencies
FastAPI depends on Pydantic and Starlette.
### `standard` Dependencies
When you install FastAPI with `pip install "fastapi[standard]"` it comes the `standard` group of optional dependencies:
Used by Pydantic:
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - for settings management.
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - for extra types to be used with Pydantic.
Used by Starlette:
@ -462,33 +468,26 @@ Used by Starlette:
Used by FastAPI / Starlette:
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application. This includes `uvicorn[standard]`, which includes some dependencies (e.g. `uvloop`) needed for high performance serving.
* `fastapi-cli` - to provide the `fastapi` command.
When you install `fastapi` it comes these standard dependencies.
Additional optional dependencies:
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
### Without `standard` Dependencies
## `fastapi-slim`
If you don't want to include the `standard` optional dependencies, you can install with `pip install fastapi` instead of `pip install "fastapi[standard]"`.
If you don't want the extra standard optional dependencies, install `fastapi-slim` instead.
### Additional Optional Dependencies
When you install with:
There are some additional dependencies you might want to install.
```bash
pip install fastapi
```
Additional optional Pydantic dependencies:
...it includes the same code and dependencies as:
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - for settings management.
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - for extra types to be used with Pydantic.
```bash
pip install "fastapi-slim[standard]"
```
Additional optional FastAPI dependencies:
The standard extra dependencies are the ones mentioned above.
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
## License

6
docs/en/docs/tutorial/index.md

@ -76,7 +76,7 @@ The first step is to install FastAPI:
<div class="termy">
```console
$ pip install fastapi
$ pip install "fastapi[standard]"
---> 100%
```
@ -84,9 +84,9 @@ $ pip install fastapi
</div>
!!! note
When you install with `pip install fastapi` it comes with some default optional standard dependencies.
When you install with `pip install "fastapi[standard]"` it comes with some default optional standard dependencies.
If you don't want to have those optional dependencies, you can instead install `pip install fastapi-slim`.
If you don't want to have those optional dependencies, you can instead install `pip install fastapi`.
## Advanced User Guide

4
docs/en/docs/tutorial/security/first-steps.md

@ -45,9 +45,9 @@ Copy the example in a file `main.py`:
## Run it
!!! info
The <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a> package is automatically installed with **FastAPI** when you run the `pip install fastapi` command.
The <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a> package is automatically installed with **FastAPI** when you run the `pip install "fastapi[standard]"` command.
However, if you use the `pip install fastapi-slim` command, the `python-multipart` package is not included by default. To install it manually, use the following command:
However, if you use the `pip install fastapi` command, the `python-multipart` package is not included by default. To install it manually, use the following command:
`pip install python-multipart`

3
fastapi/__main__.py

@ -0,0 +1,3 @@
from fastapi.cli import main
main()

13
fastapi/cli.py

@ -0,0 +1,13 @@
try:
from fastapi_cli.cli import main as cli_main
except ImportError: # pragma: no cover
cli_main = None # type: ignore
def main() -> None:
if not cli_main: # type: ignore[truthy-function]
message = 'To use the fastapi command, please install "fastapi[standard]":\n\n\tpip install "fastapi[standard]"\n'
print(message)
raise RuntimeError(message) # noqa: B904
cli_main()

27
pdm_build.py

@ -1,5 +1,5 @@
import os
from typing import Any, Dict, List
from typing import Any, Dict
from pdm.backend.hooks import Context
@ -11,29 +11,10 @@ def pdm_build_initialize(context: Context) -> None:
# Get custom config for the current package, from the env var
config: Dict[str, Any] = context.config.data["tool"]["tiangolo"][
"_internal-slim-build"
]["packages"][TIANGOLO_BUILD_PACKAGE]
]["packages"].get(TIANGOLO_BUILD_PACKAGE)
if not config:
return
project_config: Dict[str, Any] = config["project"]
# Get main optional dependencies, extras
optional_dependencies: Dict[str, List[str]] = metadata.get(
"optional-dependencies", {}
)
# Get custom optional dependencies name to always include in this (non-slim) package
include_optional_dependencies: List[str] = config.get(
"include-optional-dependencies", []
)
# Override main [project] configs with custom configs for this package
for key, value in project_config.items():
metadata[key] = value
# Get custom build config for the current package
build_config: Dict[str, Any] = (
config.get("tool", {}).get("pdm", {}).get("build", {})
)
# Override PDM build config with custom build config for this package
for key, value in build_config.items():
context.config.build_config[key] = value
# Get main dependencies
dependencies: List[str] = metadata.get("dependencies", [])
# Add optional dependencies to the default dependencies for this (non-slim) package
for include_optional in include_optional_dependencies:
optional_dependencies_group = optional_dependencies.get(include_optional, [])
dependencies.extend(optional_dependencies_group)

36
pyproject.toml

@ -54,7 +54,7 @@ Repository = "https://github.com/fastapi/fastapi"
[project.optional-dependencies]
standard = [
"fastapi-cli >=0.0.2",
"fastapi-cli[standard] >=0.0.5",
# For the test client
"httpx >=0.23.0",
# For templates
@ -73,7 +73,7 @@ standard = [
]
all = [
"fastapi-cli >=0.0.2",
"fastapi-cli[standard] >=0.0.5",
# # For the test client
"httpx >=0.23.0",
# For templates
@ -98,6 +98,9 @@ all = [
"pydantic-extra-types >=2.0.0",
]
[project.scripts]
fastapi = "fastapi.cli:main"
[tool.pdm]
version = { source = "file", path = "fastapi/__init__.py" }
distribution = true
@ -115,35 +118,6 @@ source-includes = [
[tool.tiangolo._internal-slim-build.packages.fastapi-slim.project]
name = "fastapi-slim"
[tool.tiangolo._internal-slim-build.packages.fastapi]
include-optional-dependencies = ["standard"]
[tool.tiangolo._internal-slim-build.packages.fastapi.project.optional-dependencies]
all = [
# # For the test client
"httpx >=0.23.0",
# For templates
"jinja2 >=2.11.2",
# For forms and file uploads
"python-multipart >=0.0.7",
# For Starlette's SessionMiddleware, not commonly used with FastAPI
"itsdangerous >=1.1.0",
# For Starlette's schema generation, would not be used with FastAPI
"pyyaml >=5.3.1",
# For UJSONResponse
"ujson >=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0",
# For ORJSONResponse
"orjson >=3.2.1",
# To validate email fields
"email_validator >=2.0.0",
# Uvicorn with uvloop
"uvicorn[standard] >=0.12.0",
# Settings management
"pydantic-settings >=2.0.0",
# Extra Pydantic data types
"pydantic-extra-types >=2.0.0",
]
[tool.mypy]
strict = true

32
tests/test_fastapi_cli.py

@ -0,0 +1,32 @@
import subprocess
import sys
from unittest.mock import patch
import fastapi.cli
import pytest
def test_fastapi_cli():
result = subprocess.run(
[
sys.executable,
"-m",
"coverage",
"run",
"-m",
"fastapi",
"dev",
"non_existent_file.py",
],
capture_output=True,
encoding="utf-8",
)
assert result.returncode == 1, result.stdout
assert "Using path non_existent_file.py" in result.stdout
def test_fastapi_cli_not_installed():
with patch.object(fastapi.cli, "cli_main", None):
with pytest.raises(RuntimeError) as exc_info:
fastapi.cli.main()
assert "To use the fastapi command, please install" in str(exc_info.value)
Loading…
Cancel
Save