]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
♻️ Add support for `pip install "fastapi[standard]"` with standard dependencies and...
authorSebastián Ramírez <tiangolo@gmail.com>
Fri, 2 Aug 2024 06:03:05 +0000 (01:03 -0500)
committerGitHub <noreply@github.com>
Fri, 2 Aug 2024 06:03:05 +0000 (01:03 -0500)
* ♻️ 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

15 files changed:
README.md
docs/em/docs/index.md
docs/em/docs/tutorial/index.md
docs/en/docs/deployment/docker.md
docs/en/docs/deployment/manually.md
docs/en/docs/deployment/versions.md
docs/en/docs/fastapi-cli.md
docs/en/docs/index.md
docs/en/docs/tutorial/index.md
docs/en/docs/tutorial/security/first-steps.md
fastapi/__main__.py [new file with mode: 0644]
fastapi/cli.py [new file with mode: 0644]
pdm_build.py
pyproject.toml
tests/test_fastapi_cli.py [new file with mode: 0644]

index 739e776274e15a180b2a631e9c2bb14e40fa955b..aa70ff2da562c422efabf44e78538c8b7fb88a8b 100644 (file)
--- a/README.md
+++ b/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
 
index a7d1d06f94a9fc17cd4f8db5b4f728f1538a7f4a..dc8c4f0236f35d23cfed1044c4bec11408adfd50 100644 (file)
@@ -133,7 +133,7 @@ FastAPI 🧍 🔛 ⌚ 🐘:
 <div class="termy">
 
 ```console
-$ pip install fastapi
+$ pip install "fastapi[standard]"
 
 ---> 100%
 ```
index 26b4c1913a5e3efaeeff7263b2258557aa07e25b..fd6900db0e1da6494ff67e5c2dcc6ac2e67fb1cf 100644 (file)
@@ -58,7 +58,7 @@ $ pip install "fastapi[all]"
     👉 ⚫️❔ 👆 🔜 🎲 🕐 👆 💚 🛠️ 👆 🈸 🏭:
 
     ```
-    pip install fastapi
+    pip install "fastapi[standard]"
     ```
 
     ❎ `uvicorn` 👷 💽:
index 5cd24eb46293d980dc231a2f1e5a52e018f810c0..157a3c003f7a551798f80e0b20558bea5be72197 100644 (file)
@@ -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
 ```
 
index 51989d819dbbb930958be68f3f91566f9e8431c6..ad9f62f913f715179d4d92d74aa25637b4141ecd 100644 (file)
@@ -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"
 
index 4be9385ddf530094a0cbc97031f230118cd91c84..24430b0cfb2d07aa6c0aa19d9e41f6c6bb901431 100644 (file)
@@ -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
 ```
index a6facde3a29455a32a83867620e537c3d207b370..0fc072ed24cb25d9d3f867797f8f35d276cbe026 100644 (file)
@@ -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:
 
index 73357542f8072711d45d009a8eb5c54d45cfdf96..4fe0cd6cc71ebe68d268877407c72f498ae98bd6 100644 (file)
@@ -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
 
index 74fe06acd495e0cdce987586c51a3256dcca91b9..f22dc01ddbbcdf0baeffb49c5362444b097b2276 100644 (file)
@@ -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
 
index a769cc0e6deb15b4f561f8baebdaa7dd3739d4a8..d8682a0548b63af6e0cbca7b493dec3101c76318 100644 (file)
@@ -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`
 
diff --git a/fastapi/__main__.py b/fastapi/__main__.py
new file mode 100644 (file)
index 0000000..fc36465
--- /dev/null
@@ -0,0 +1,3 @@
+from fastapi.cli import main
+
+main()
diff --git a/fastapi/cli.py b/fastapi/cli.py
new file mode 100644 (file)
index 0000000..8d3301e
--- /dev/null
@@ -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()
index 45922d471a3b0e30394628d37a7a4a309ded0137..c83222b33685819dcb0d8ec08df5ed94bcc1cdaf 100644 (file)
@@ -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)
index 9ab6e6d69ea8ad6d942cff70620fe37ed52ab647..3601e6322179d0d9ead424f500ba1ab1858e0fb9 100644 (file)
@@ -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
 
diff --git a/tests/test_fastapi_cli.py b/tests/test_fastapi_cli.py
new file mode 100644 (file)
index 0000000..20c9281
--- /dev/null
@@ -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)