]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
๐Ÿ“ Update docs to use uv projects by default (#16032)
authorSebastiรกn Ramรญrez <tiangolo@gmail.com>
Tue, 21 Jul 2026 21:27:36 +0000 (23:27 +0200)
committerGitHub <noreply@github.com>
Tue, 21 Jul 2026 21:27:36 +0000 (21:27 +0000)
30 files changed:
README.md
docs/en/docs/advanced/async-tests.md
docs/en/docs/advanced/behind-a-proxy.md
docs/en/docs/advanced/settings.md
docs/en/docs/advanced/sub-applications.md
docs/en/docs/advanced/templates.md
docs/en/docs/advanced/websockets.md
docs/en/docs/advanced/wsgi.md
docs/en/docs/deployment/docker.md
docs/en/docs/deployment/fastapicloud.md
docs/en/docs/deployment/manually.md
docs/en/docs/deployment/server-workers.md
docs/en/docs/environment-variables.md
docs/en/docs/fastapi-cli.md
docs/en/docs/index.md
docs/en/docs/tutorial/bigger-applications.md
docs/en/docs/tutorial/debugging.md
docs/en/docs/tutorial/first-steps.md
docs/en/docs/tutorial/index.md
docs/en/docs/tutorial/request-files.md
docs/en/docs/tutorial/request-form-models.md
docs/en/docs/tutorial/request-forms-and-files.md
docs/en/docs/tutorial/request-forms.md
docs/en/docs/tutorial/response-model.md
docs/en/docs/tutorial/security/first-steps.md
docs/en/docs/tutorial/security/oauth2-jwt.md
docs/en/docs/tutorial/sql-databases.md
docs/en/docs/tutorial/testing.md
docs/en/docs/virtual-environments.md
docs/en/mkdocs.yml

index 36d262983b26bf6761f7bb76f6e269fa841a647a..3a25484e35ae5110592bfa991ad778c92695833e 100644 (file)
--- a/README.md
+++ b/README.md
@@ -134,12 +134,12 @@ FastAPI stands on the shoulders of giants:
 
 ## Installation
 
-Create and activate a [virtual environment](https://fastapi.tiangolo.com/virtual-environments/) and then install FastAPI:
+First, [install `uv`](https://docs.astral.sh/uv/getting-started/installation/), and then add FastAPI to your project:
 
 <div class="termy">
 
 ```console
-$ pip install "fastapi[standard]"
+$ uv add "fastapi[standard]"
 
 ---> 100%
 ```
@@ -148,6 +148,8 @@ $ pip install "fastapi[standard]"
 
 **Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals.
 
+If you prefer to use `pip`, install `fastapi[standard]` inside a virtual environment. See the [installation guide](tutorial/#install-fastapi) for the alternative steps.
+
 ## Example
 
 ### Create it
@@ -204,7 +206,7 @@ Run the server with:
 <div class="termy">
 
 ```console
-$ fastapi dev
+$ uv run fastapi dev
 
  โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ FastAPI CLI - Development mode โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
  โ”‚                                                     โ”‚
@@ -451,7 +453,7 @@ You can optionally deploy your FastAPI app to [FastAPI Cloud](https://fastapiclo
 <div class="termy">
 
 ```console
-$ fastapi deploy
+$ uv run fastapi deploy
 
 Deploying to FastAPI Cloud...
 
@@ -494,7 +496,7 @@ FastAPI depends on Pydantic and Starlette.
 
 ### `standard` Dependencies
 
-When you install FastAPI with `pip install "fastapi[standard]"` it comes with the `standard` group of optional dependencies:
+When you install FastAPI with `uv add "fastapi[standard]"` it comes with the `standard` group of optional dependencies:
 
 Used by Pydantic:
 
@@ -514,11 +516,11 @@ Used by FastAPI:
 
 ### 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]"`.
+If you don't want to include the `standard` optional dependencies, you can install with `uv add fastapi` instead of `uv add "fastapi[standard]"`.
 
 ### 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]"`.
+If you want to install FastAPI with the standard dependencies but without the `fastapi-cloud-cli`, you can install with `uv add "fastapi[standard-no-fastapi-cloud-cli]"`.
 
 ### Additional Optional Dependencies
 
index c7ec5e9e2905ffd158ae856b2f3cc53939af63c7..fcc9a149e1b00514817c75ccb52c2e8e8795fe73 100644 (file)
@@ -45,7 +45,7 @@ You can run your tests as usual via:
 <div class="termy">
 
 ```console
-$ pytest
+$ uv run pytest
 
 ---> 100%
 ```
index c413fccdfe152b63ca06ea29910a9f6640a274e7..2d6a7f077cfa9f77aa98ea94d9bb87d34e298310 100644 (file)
@@ -33,7 +33,7 @@ If your **server** is behind a trusted **proxy** and only the proxy talks to it,
 <div class="termy">
 
 ```console
-$ fastapi run --forwarded-allow-ips="*"
+$ uv run fastapi run --forwarded-allow-ips="*"
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
@@ -170,7 +170,7 @@ To achieve this, you can use the command line option `--root-path` like:
 <div class="termy">
 
 ```console
-$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
+$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
@@ -200,7 +200,7 @@ Then, if you start Uvicorn with:
 <div class="termy">
 
 ```console
-$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
+$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
@@ -321,7 +321,7 @@ And now start your app, using the `--root-path` option:
 <div class="termy">
 
 ```console
-$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
+$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
index ff313f0881eb9f6721e9b4cb704c964b75ea9240..3437c109941852322ff90fb0452629064cbfc3fd 100644 (file)
@@ -6,9 +6,13 @@ Most of these settings are variable (can change), like database URLs. And many c
 
 For this reason it's common to provide them in environment variables that are read by the application.
 
+An **environment variable** (also known as an **env var**) is a value that lives outside of the Python code, in the operating system, and can be read by your application and other programs.
+
+You can create an environment variable for a command when you run it. You will see the platform-specific commands below.
+
 /// tip
 
-To understand environment variables you can read [Environment Variables](../environment-variables.md).
+Read the [Environment Variables guide](https://tiangolo.com/guides/environment-variables/) for a detailed explanation of how environment variables work.
 
 ///
 
@@ -24,12 +28,12 @@ Fortunately, Pydantic provides a great utility to handle these settings coming f
 
 ### Install `pydantic-settings` { #install-pydantic-settings }
 
-First, make sure you create your [virtual environment](../virtual-environments.md), activate it, and then install the `pydantic-settings` package:
+Add the `pydantic-settings` package to your project:
 
 <div class="termy">
 
 ```console
-$ pip install pydantic-settings
+$ uv add pydantic-settings
 ---> 100%
 ```
 
@@ -40,7 +44,7 @@ It also comes included when you install the `all` extras with:
 <div class="termy">
 
 ```console
-$ pip install "fastapi[all]"
+$ uv add "fastapi[all]"
 ---> 100%
 ```
 
@@ -76,19 +80,39 @@ Then you can use the new `settings` object in your application:
 
 Next, you would run the server passing the configurations as environment variables, for example you could set an `ADMIN_EMAIL` and `APP_NAME` with:
 
+//// tab | Linux, macOS, Windows Bash
+
 <div class="termy">
 
 ```console
-$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.py
+$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uv run fastapi run main.py
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
 
 </div>
 
+////
+
+//// tab | Windows PowerShell
+
+<div class="termy">
+
+```console
+$ $Env:ADMIN_EMAIL = "deadpool@example.com"
+$ $Env:APP_NAME = "ChimichangApp"
+$ uv run fastapi run main.py
+
+<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+</div>
+
+////
+
 /// tip
 
-To set multiple env vars for a single command just separate them with a space, and put them all before the command.
+In Bash, to set multiple env vars for a single command, separate them with a space and put them all before the command.
 
 ///
 
@@ -176,7 +200,7 @@ Pydantic has support for reading from these types of files using an external lib
 
 /// tip
 
-For this to work, you need to `pip install python-dotenv`.
+For this to work, add `python-dotenv` to your project with `uv add python-dotenv`.
 
 ///
 
index a391c7c24569b3d6a59ed04b524133005a304391..267fe02fcb06f83e816ada07a631360e15a6adbb 100644 (file)
@@ -35,7 +35,7 @@ Now, run the `fastapi` command:
 <div class="termy">
 
 ```console
-$ fastapi dev
+$ uv run fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
index 6570865e27ed06cc90e79db0980ffad3ef8314f7..9ce3d1b32df2c2122a7e6d509919063a6c4ad243 100644 (file)
@@ -8,12 +8,12 @@ There are utilities to configure it easily that you can use directly in your **F
 
 ## Install dependencies { #install-dependencies }
 
-Make sure you create a [virtual environment](../virtual-environments.md), activate it, and install `jinja2`:
+Add `jinja2` to your project:
 
 <div class="termy">
 
 ```console
-$ pip install jinja2
+$ uv add jinja2
 
 ---> 100%
 ```
index 6f4603e6ac3c96eb8a28a327dfee3b71b2458464..52541ee49cf9a22b6f4d7333543d05f3562e9afe 100644 (file)
@@ -4,12 +4,12 @@ You can use [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSoc
 
 ## Install `websockets` { #install-websockets }
 
-Make sure you create a [virtual environment](../virtual-environments.md), activate it, and install `websockets` (a Python library that makes it easy to use the "WebSocket" protocol):
+Add `websockets` (a Python library that makes it easy to use the "WebSocket" protocol) to your project:
 
 <div class="termy">
 
 ```console
-$ pip install websockets
+$ uv add websockets
 
 ---> 100%
 ```
@@ -69,7 +69,7 @@ Put your code in a file `main.py` and then run your application:
 <div class="termy">
 
 ```console
-$ fastapi dev
+$ uv run fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
@@ -126,7 +126,7 @@ Run your application:
 <div class="termy">
 
 ```console
-$ fastapi dev
+$ uv run fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
index 8dcc3c4010441dc240cc5582ee06d42af7874f17..cae8138de7ec95d02d0d3ced7c58e0e144bdd792 100644 (file)
@@ -8,7 +8,7 @@ For that, you can use the `WSGIMiddleware` and use it to wrap your WSGI applicat
 
 /// note
 
-This requires installing `a2wsgi` for example with `pip install a2wsgi`.
+This requires adding `a2wsgi` to your project, for example with `uv add a2wsgi`.
 
 ///
 
index bdc0351d0302966a6d7d3626b0c54a332ae6e46f..bbb16a14f49dbfb577fed90eee99a22a25e181eb 100644 (file)
@@ -105,36 +105,32 @@ This is what you would want to do in **most cases**, for example:
 
 ### Package Requirements { #package-requirements }
 
-You would normally have the **package requirements** for your application in some file.
+When you manage your project with `uv`, its direct dependencies are declared in `pyproject.toml` and the exact resolved versions are stored in `uv.lock`.
 
-It would depend mainly on the tool you use to **install** those requirements.
+You can add the packages your application needs with:
 
-The most common way to do it is to have a file `requirements.txt` with the package names and their versions, one per line.
+<div class="termy">
 
-You would of course use the same ideas you read in [About FastAPI versions](versions.md) to set the ranges of versions.
+```console
+$ uv add "fastapi[standard]" pydantic
+---> 100%
+```
 
-For example, your `requirements.txt` could look like:
+</div>
 
-```
-fastapi[standard]>=0.113.0,<0.114.0
-pydantic>=2.7.0,<3.0.0
-```
+/// note
 
-And you would normally install those package dependencies with `pip`, for example:
+The Dockerfile below uses `pip` inside the container. You can export the locked dependencies from your uv project to the `requirements.txt` format it expects:
 
 <div class="termy">
 
 ```console
-$ pip install -r requirements.txt
----> 100%
-Successfully installed fastapi pydantic
+$ uv export --format requirements-txt --no-dev --no-emit-project --output-file requirements.txt
 ```
 
 </div>
 
-/// note
-
-There are other formats and tools to define and install package dependencies.
+The generated `requirements.txt` is an export for the container build. Continue managing dependencies with `uv add` and regenerate it when `uv.lock` changes.
 
 ///
 
index dbc44f41a3665b9943a83ac0a86c530af782c9e4..d9e7694736620482da7c59bc7d7808007d8c0850 100644 (file)
@@ -5,7 +5,7 @@ You can deploy your FastAPI app to [FastAPI Cloud](https://fastapicloud.com) wit
 <div class="termy">
 
 ```console
-$ fastapi deploy
+$ uv run fastapi deploy
 
 Deploying to FastAPI Cloud...
 
index ed49aa00ac9b02927e3e3ff6eefb3bd89b04366a..a328a194599d3a0a066e06d384825e138a5be096 100644 (file)
@@ -73,14 +73,14 @@ When you install FastAPI, it comes with a production server, Uvicorn, and you ca
 
 But you can also install an ASGI server manually.
 
-Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then you can install the server application.
+Add the server application to your project.
 
 For example, to install Uvicorn:
 
 <div class="termy">
 
 ```console
-$ pip install "uvicorn[standard]"
+$ uv add "uvicorn[standard]"
 
 ---> 100%
 ```
@@ -95,7 +95,7 @@ By adding the `standard`, Uvicorn will install and use some recommended extra de
 
 That includes `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[standard]"` you already get `uvicorn[standard]` as well.
+When you add FastAPI with something like `uv add "fastapi[standard]"` you already get `uvicorn[standard]` as well.
 
 ///
 
@@ -106,7 +106,7 @@ If you installed an ASGI server manually, you would normally need to pass an imp
 <div class="termy">
 
 ```console
-$ uvicorn main:app --host 0.0.0.0 --port 80
+$ uv run uvicorn main:app --host 0.0.0.0 --port 80
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
 ```
index fb0741acb2127f869e004669dd6b9d54caf8c974..a4d7b42ceab778570d0598d75f6e81e279a68a2c 100644 (file)
@@ -86,7 +86,7 @@ If you prefer to use the `uvicorn` command directly:
 <div class="termy">
 
 ```console
-$ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
+$ uv run uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
 <font color="#A6E22E">INFO</font>:     Uvicorn running on <b>http://0.0.0.0:8080</b> (Press CTRL+C to quit)
 <font color="#A6E22E">INFO</font>:     Started parent process [<font color="#A1EFE4"><b>27365</b></font>]
 <font color="#A6E22E">INFO</font>:     Started server process [<font color="#A1EFE4">27368</font>]
index b123694318b82a3e470fa953f3d0339ce7215f35..42894aa1ba661c52fc5b3a3e0c727a62c3dacfe6 100644 (file)
 # Environment Variables { #environment-variables }
 
-/// tip
+An **environment variable** (also known as an **env var**) is a value that lives outside of your Python code, in the operating system, and can be read by your application and other programs.
 
-If you already know what "environment variables" are and how to use them, feel free to skip this.
+FastAPI applications commonly use environment variables for configuration such as database URLs, email credentials, and secret keys.
 
-///
+You will learn how to use them for application configuration in [Settings and Environment Variables](advanced/settings.md).
 
-An environment variable (also known as "**env var**") is a variable that lives **outside** of the Python code, in the **operating system**, and could be read by your Python code (or by other programs as well).
+## Learn More { #learn-more }
 
-Environment variables could be useful for handling application **settings**, as part of the **installation** of Python, etc.
-
-## Create and Use Env Vars { #create-and-use-env-vars }
-
-You can **create** and use environment variables in the **shell (terminal)**, without needing Python:
-
-//// tab | Linux, macOS, Windows Bash
-
-<div class="termy">
-
-```console
-// You could create an env var MY_NAME with
-$ export MY_NAME="Wade Wilson"
-
-// Then you could use it with other programs, like
-$ echo "Hello $MY_NAME"
-
-Hello Wade Wilson
-```
-
-</div>
-
-////
-
-//// tab | Windows PowerShell
-
-<div class="termy">
-
-```console
-// Create an env var MY_NAME
-$ $Env:MY_NAME = "Wade Wilson"
-
-// Use it with other programs, like
-$ echo "Hello $Env:MY_NAME"
-
-Hello Wade Wilson
-```
-
-</div>
-
-////
-
-## Read env vars in Python { #read-env-vars-in-python }
-
-You could also create environment variables **outside** of Python, in the terminal (or with any other method), and then **read them in Python**.
-
-For example you could have a file `main.py` with:
-
-```Python hl_lines="3"
-import os
-
-name = os.getenv("MY_NAME", "World")
-print(f"Hello {name} from Python")
-```
-
-/// tip
-
-The second argument to [`os.getenv()`](https://docs.python.org/3.8/library/os.html#os.getenv) is the default value to return.
-
-If not provided, it's `None` by default, here we provide `"World"` as the default value to use.
-
-///
-
-Then you could call that Python program:
-
-//// tab | Linux, macOS, Windows Bash
-
-<div class="termy">
-
-```console
-// Here we don't set the env var yet
-$ python main.py
-
-// As we didn't set the env var, we get the default value
-
-Hello World from Python
-
-// But if we create an environment variable first
-$ export MY_NAME="Wade Wilson"
-
-// And then call the program again
-$ python main.py
-
-// Now it can read the environment variable
-
-Hello Wade Wilson from Python
-```
-
-</div>
-
-////
-
-//// tab | Windows PowerShell
-
-<div class="termy">
-
-```console
-// Here we don't set the env var yet
-$ python main.py
-
-// As we didn't set the env var, we get the default value
-
-Hello World from Python
-
-// But if we create an environment variable first
-$ $Env:MY_NAME = "Wade Wilson"
-
-// And then call the program again
-$ python main.py
-
-// Now it can read the environment variable
-
-Hello Wade Wilson from Python
-```
-
-</div>
-
-////
-
-As environment variables can be set outside of the code, but can be read by the code, and don't have to be stored (committed to `git`) with the rest of the files, it's common to use them for configurations or **settings**.
-
-You can also create an environment variable only for a **specific program invocation**, that is only available to that program, and only for its duration.
-
-To do that, create it right before the program itself, on the same line:
-
-<div class="termy">
-
-```console
-// Create an env var MY_NAME in line for this program call
-$ MY_NAME="Wade Wilson" python main.py
-
-// Now it can read the environment variable
-
-Hello Wade Wilson from Python
-
-// The env var no longer exists afterwards
-$ python main.py
-
-Hello World from Python
-```
-
-</div>
-
-/// tip
-
-You can read more about it at [The Twelve-Factor App: Config](https://12factor.net/config).
-
-///
-
-## Types and Validation { #types-and-validation }
-
-These environment variables can only handle **text strings**, as they are external to Python and have to be compatible with other programs and the rest of the system (and even with different operating systems, such as Linux, Windows, and macOS).
-
-That means that **any value** read in Python from an environment variable **will be a `str`**, and any conversion to a different type or any validation has to be done in code.
-
-You will learn more about using environment variables for handling **application settings** in the [Advanced User Guide - Settings and Environment Variables](./advanced/settings.md).
-
-## `PATH` Environment Variable { #path-environment-variable }
-
-There is a **special** environment variable called **`PATH`** that is used by the operating systems (Linux, macOS, Windows) to find programs to run.
-
-The value of the variable `PATH` is a long string that is made of directories separated by a colon `:` on Linux and macOS, and by a semicolon `;` on Windows.
-
-For example, the `PATH` environment variable could look like this:
-
-//// tab | Linux, macOS
-
-```plaintext
-/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
-```
-
-This means that the system should look for programs in the directories:
-
-* `/usr/local/bin`
-* `/usr/bin`
-* `/bin`
-* `/usr/sbin`
-* `/sbin`
-
-////
-
-//// tab | Windows
-
-```plaintext
-C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
-```
-
-This means that the system should look for programs in the directories:
-
-* `C:\Program Files\Python312\Scripts`
-* `C:\Program Files\Python312`
-* `C:\Windows\System32`
-
-////
-
-When you type a **command** in the terminal, the operating system **looks for** the program in **each of those directories** listed in the `PATH` environment variable.
-
-For example, when you type `python` in the terminal, the operating system looks for a program called `python` in the **first directory** in that list.
-
-If it finds it, then it will **use it**. Otherwise it keeps looking in the **other directories**.
-
-### Installing Python and Updating the `PATH` { #installing-python-and-updating-the-path }
-
-When you install Python, you might be asked if you want to update the `PATH` environment variable.
-
-//// tab | Linux, macOS
-
-Let's say you install Python and it ends up in a directory `/opt/custompython/bin`.
-
-If you say yes to update the `PATH` environment variable, then the installer will add `/opt/custompython/bin` to the `PATH` environment variable.
-
-It could look like this:
-
-```plaintext
-/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
-```
-
-This way, when you type `python` in the terminal, the system will find the Python program in `/opt/custompython/bin` (the last directory) and use that one.
-
-////
-
-//// tab | Windows
-
-Let's say you install Python and it ends up in a directory `C:\opt\custompython\bin`.
-
-If you say yes to update the `PATH` environment variable, then the installer will add `C:\opt\custompython\bin` to the `PATH` environment variable.
-
-```plaintext
-C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
-```
-
-This way, when you type `python` in the terminal, the system will find the Python program in `C:\opt\custompython\bin` (the last directory) and use that one.
-
-////
-
-So, if you type:
-
-<div class="termy">
-
-```console
-$ python
-```
-
-</div>
-
-//// tab | Linux, macOS
-
-The system will **find** the `python` program in `/opt/custompython/bin` and run it.
-
-It would be roughly equivalent to typing:
-
-<div class="termy">
-
-```console
-$ /opt/custompython/bin/python
-```
-
-</div>
-
-////
-
-//// tab | Windows
-
-The system will **find** the `python` program in `C:\opt\custompython\bin\python` and run it.
-
-It would be roughly equivalent to typing:
-
-<div class="termy">
-
-```console
-$ C:\opt\custompython\bin\python
-```
-
-</div>
-
-////
-
-This information will be useful when learning about [Virtual Environments](virtual-environments.md).
-
-## Conclusion { #conclusion }
-
-With this you should have a basic understanding of what **environment variables** are and how to use them in Python.
-
-You can also read more about them in the [Wikipedia for Environment Variable](https://en.wikipedia.org/wiki/Environment_variable).
-
-In many cases it's not very obvious how environment variables would be useful and applicable right away. But they keep showing up in many different scenarios when you are developing, so it's good to know about them.
-
-For example, you will need this information in the next section, about [Virtual Environments](virtual-environments.md).
+Read the [Environment Variables guide](https://tiangolo.com/guides/environment-variables/) for a detailed, cross-platform explanation, including how to create and read environment variables and how the `PATH` environment variable works.
index 9d8f415d9babf0a42f2e0ae0eb824ff44d62bd0e..2ec820838b2a70ce701e7415a43c15564ec06bd5 100644 (file)
@@ -2,7 +2,7 @@
 
 **FastAPI <abbr title="command line interface">CLI</abbr>** 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[standard]"`), it comes with a command line program you can run in the terminal.
+When you add FastAPI to your project (e.g. with `uv add "fastapi[standard]"`), it comes with a command line program you can run in the terminal.
 
 To run your FastAPI app for development, you can use the `fastapi dev` command:
 
@@ -100,13 +100,13 @@ from backend.main import app
 You can also pass the file path to the `fastapi dev` command, and it will guess the FastAPI app object to use:
 
 ```console
-$ fastapi dev main.py
+$ uv run fastapi dev main.py
 ```
 
 Or, you can also pass the `--entrypoint` option to the `fastapi dev` command:
 
 ```console
-$ fastapi dev --entrypoint main:app
+$ uv run fastapi dev --entrypoint main:app
 ```
 
 But you would have to remember to pass the correct path\entrypoint every time you call the `fastapi` command.
index 7baeaab2620ea370e56169547d0dfdb4d097e86f..5f6b51b141f68102fdd1320ee5044731e3f2f2b9 100644 (file)
@@ -180,12 +180,12 @@ FastAPI stands on the shoulders of giants:
 
 ## Installation { #installation }
 
-Create and activate a [virtual environment](https://fastapi.tiangolo.com/virtual-environments/) and then install FastAPI:
+First, [install `uv`](https://docs.astral.sh/uv/getting-started/installation/), and then add FastAPI to your project:
 
 <div class="termy">
 
 ```console
-$ pip install "fastapi[standard]"
+$ uv add "fastapi[standard]"
 
 ---> 100%
 ```
@@ -194,6 +194,8 @@ $ pip install "fastapi[standard]"
 
 **Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals.
 
+If you prefer to use `pip`, install `fastapi[standard]` inside a virtual environment. See the [installation guide](tutorial/#install-fastapi) for the alternative steps.
+
 ## Example { #example }
 
 ### Create it { #create-it }
@@ -250,7 +252,7 @@ Run the server with:
 <div class="termy">
 
 ```console
-$ fastapi dev
+$ uv run fastapi dev
 
  โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ FastAPI CLI - Development mode โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
  โ”‚                                                     โ”‚
@@ -497,7 +499,7 @@ You can optionally deploy your FastAPI app to [FastAPI Cloud](https://fastapiclo
 <div class="termy">
 
 ```console
-$ fastapi deploy
+$ uv run fastapi deploy
 
 Deploying to FastAPI Cloud...
 
@@ -540,7 +542,7 @@ FastAPI depends on Pydantic and Starlette.
 
 ### `standard` Dependencies { #standard-dependencies }
 
-When you install FastAPI with `pip install "fastapi[standard]"` it comes with the `standard` group of optional dependencies:
+When you install FastAPI with `uv add "fastapi[standard]"` it comes with the `standard` group of optional dependencies:
 
 Used by Pydantic:
 
@@ -560,11 +562,11 @@ Used by FastAPI:
 
 ### 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]"`.
+If you don't want to include the `standard` optional dependencies, you can install with `uv add fastapi` instead of `uv add "fastapi[standard]"`.
 
 ### 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]"`.
+If you want to install FastAPI with the standard dependencies but without the `fastapi-cloud-cli`, you can install with `uv add "fastapi[standard-no-fastapi-cloud-cli]"`.
 
 ### Additional Optional Dependencies { #additional-optional-dependencies }
 
index 07478b5cce7d9cf94388393173264aa63504e0bf..ac7147de296c0aa672f68debf2f8be8c532a2259 100644 (file)
@@ -487,7 +487,7 @@ That way the `fastapi` command will know where to find your app.
 You could also pass the path to the command, like:
 
 ```console
-$ fastapi dev app/main.py
+$ uv run fastapi dev app/main.py
 ```
 
 But you would have to remember to pass the correct path every time you call the `fastapi` command.
@@ -503,7 +503,7 @@ Now, run your app:
 <div class="termy">
 
 ```console
-$ fastapi dev
+$ uv run fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
index 5b57fe85b85bbf4de4e0dbd996abc1fa988c6bd9..b57e0b619e0eda8609ffa1e4079a94a6c630680f 100644 (file)
@@ -15,7 +15,7 @@ The main purpose of the `__name__ == "__main__"` is to have some code that is ex
 <div class="termy">
 
 ```console
-$ python myapp.py
+$ uv run python myapp.py
 ```
 
 </div>
@@ -35,7 +35,7 @@ If you run it with:
 <div class="termy">
 
 ```console
-$ python myapp.py
+$ uv run python myapp.py
 ```
 
 </div>
index afef393417e9d4789226947d3e6c5ab77ebf9c35..d55468f3e4151c15b409f257d73dc4fa91e8a823 100644 (file)
@@ -6,12 +6,18 @@ The simplest FastAPI file could look like this:
 
 Copy that to a file `main.py`.
 
+/// tip
+
+FastAPI has an [official extension for VS Code](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) (and Cursor), which provides a lot of features, including a path operation explorer, path operation search, CodeLens navigation in tests (jump to definition from tests), and FastAPI Cloud deployment and logs, all from your editor.
+
+///
+
 Run the live server:
 
 <div class="termy">
 
 ```console
-$ <font color="#4E9A06">fastapi</font> dev
+$ <font color="#4E9A06">uv run fastapi</font> dev
 
   <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting development server ๐Ÿš€
 
@@ -185,13 +191,13 @@ from backend.main import app
 You can also pass the file path to the `fastapi dev` command, and it will guess the FastAPI app object to use:
 
 ```console
-$ fastapi dev main.py
+$ uv run fastapi dev main.py
 ```
 
 Or, you can also pass the `--entrypoint` option to the `fastapi dev` command:
 
 ```console
-$ fastapi dev --entrypoint main:app
+$ uv run fastapi dev --entrypoint main:app
 ```
 
 But you would have to remember to pass the correct path\entrypoint every time you call the `fastapi` command.
@@ -205,7 +211,7 @@ You can optionally deploy your FastAPI app to [FastAPI Cloud](https://fastapiclo
 <div class="termy">
 
 ```console
-$ fastapi deploy
+$ uv run fastapi deploy
 
 Deploying to FastAPI Cloud...
 
index 9e73579199857819a5c02e32d8688487c712e55a..c7f3c899f6094785f1e985ffb70a0c4120494b3e 100644 (file)
@@ -10,12 +10,12 @@ It is also built to work as a future reference so you can come back and see exac
 
 All the code blocks can be copied and used directly (they are actually tested Python files).
 
-To run any of the examples, copy the code to a file `main.py`, and start `fastapi dev`:
+To run any of the examples, copy the code to a file `main.py`, and start `fastapi dev` with `uv run`:
 
 <div class="termy">
 
 ```console
-$ <font color="#4E9A06">fastapi</font> dev
+$ <font color="#4E9A06">uv run fastapi</font> dev
 
   <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting development server ๐Ÿš€
 
@@ -60,33 +60,55 @@ Using it in your editor is what really shows you the benefits of FastAPI, seeing
 
 ## Install FastAPI { #install-fastapi }
 
-The first step is to install FastAPI.
+The first step is to set up your project and add FastAPI.
 
-Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then **install FastAPI**:
+Install [`uv`](https://docs.astral.sh/uv/getting-started/installation/), then create a project and add FastAPI:
 
 <div class="termy">
 
 ```console
-$ pip install "fastapi[standard]"
+$ uv init awesome-project --bare
+$ cd awesome-project
+$ uv add "fastapi[standard]"
 
 ---> 100%
 ```
 
 </div>
 
-/// note
+`uv add` creates the project's virtual environment in `.venv`, adds FastAPI to `pyproject.toml`, and creates `uv.lock` so the same package versions can be installed later.
 
-When you install with `pip install "fastapi[standard]"` it comes with some default optional standard dependencies, including `fastapi-cloud-cli`, which allows you to deploy to [FastAPI Cloud](https://fastapicloud.com).
+/// details | What these commands do
 
-If you don't want to have those optional dependencies, you can instead install `pip install fastapi`.
+* `uv init`: create a new Python project.
+* `awesome-project`: create the project in a new directory with this name.
+* `--bare`: create only the minimal `pyproject.toml` file, without generating a sample `main.py`, `README.md`, or other files. You will create the application files yourself in the next steps of this tutorial.
 
-If you want to install the standard dependencies but without the `fastapi-cloud-cli`, you can install with `pip install "fastapi[standard-no-fastapi-cloud-cli]"`.
+Then `cd awesome-project` enters the new project directory before adding FastAPI.
+
+`uv` will use a compatible Python version already installed on your system, or download one if needed.
+
+When you run `uv add`, it selects compatible versions of FastAPI and all the packages FastAPI depends on. It records the exact versions in `uv.lock`, making it possible to install the same package versions later on another computer or when deploying the application.
+
+Creating or updating this file is called [**locking** the project dependencies](https://docs.astral.sh/uv/concepts/projects/sync/). `uv` does this automatically when you add a package.
+
+///
+
+/// details | FastAPI installation options
+
+When you install with `uv add "fastapi[standard]"` it comes with some default optional standard dependencies, including `fastapi-cloud-cli`, which allows you to deploy to [FastAPI Cloud](https://fastapicloud.com).
+
+If you don't want to have those optional dependencies, you can instead install `uv add fastapi`.
+
+If you want to install the standard dependencies but without the `fastapi-cloud-cli`, you can install with `uv add "fastapi[standard-no-fastapi-cloud-cli]"`.
 
 ///
 
-/// tip
+/// details | Using `pip` instead
+
+If you prefer to manage a virtual environment and packages manually, create and activate a virtual environment and then install FastAPI with `pip install "fastapi[standard]"`.
 
-FastAPI has an [official extension for VS Code](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) (and Cursor), which provides a lot of features, including a path operation explorer, path operation search, CodeLens navigation in tests (jump to definition from tests), and FastAPI Cloud deployment and logs, all from your editor.
+Read the [Virtual Environments guide](https://tiangolo.com/guides/virtual-environments/) for the detailed steps.
 
 ///
 
index df789478114a14874955fb208199d7144d0ed6c8..fd4a7d8ce836da0514ddd540b08eeb06cbb831b8 100644 (file)
@@ -6,10 +6,10 @@ You can define files to be uploaded by the client using `File`.
 
 To receive uploaded files, first install [`python-multipart`](https://github.com/Kludex/python-multipart).
 
-Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then install it, for example:
+Add it to your project:
 
 ```console
-$ pip install python-multipart
+$ uv add python-multipart
 ```
 
 This is because uploaded files are sent as "form data".
index 71766bd4ef5bfb681cf5a884f6713c98db389db9..e098cb09b87504efd734f46e08501e4176d53160 100644 (file)
@@ -6,10 +6,10 @@ You can use **Pydantic models** to declare **form fields** in FastAPI.
 
 To use forms, first install [`python-multipart`](https://github.com/Kludex/python-multipart).
 
-Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then install it, for example:
+Add it to your project:
 
 ```console
-$ pip install python-multipart
+$ uv add python-multipart
 ```
 
 ///
index f6a839491c6b44d822a68db4e8189874a28d59e9..1e145b456d890921df6f9926b9d88b16331dda44 100644 (file)
@@ -6,10 +6,10 @@ You can define files and form fields at the same time using `File` and `Form`.
 
 To receive uploaded files and/or form data, first install [`python-multipart`](https://github.com/Kludex/python-multipart).
 
-Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then install it, for example:
+Add it to your project:
 
 ```console
-$ pip install python-multipart
+$ uv add python-multipart
 ```
 
 ///
index 45af663c8fb7f40dc417c86c6a554136800904a5..a25e2e338031552668dbe3737a52f75f19e6dff3 100644 (file)
@@ -6,10 +6,10 @@ When you need to receive form fields instead of JSON, you can use `Form`.
 
 To use forms, first install [`python-multipart`](https://github.com/Kludex/python-multipart).
 
-Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then install it, for example:
+Add it to your project:
 
 ```console
-$ pip install python-multipart
+$ uv add python-multipart
 ```
 
 ///
index ae93eece673b6c67f76d0d07e61785f2528193bf..3bb513fcf744bbc857cece3647764d77206959e7 100644 (file)
@@ -76,16 +76,16 @@ Here we are declaring a `UserIn` model, it will contain a plaintext password:
 
 To use `EmailStr`, first install [`email-validator`](https://github.com/JoshData/python-email-validator).
 
-Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then install it, for example:
+Add it to your project:
 
 ```console
-$ pip install email-validator
+$ uv add email-validator
 ```
 
 or with:
 
 ```console
-$ pip install "pydantic[email]"
+$ uv add "pydantic[email]"
 ```
 
 ///
index 7dae3edf40a24a252d32b20410b74e0fa31f4994..11a7d19faa780d356175c67dba44273e6e8da961 100644 (file)
@@ -26,14 +26,14 @@ Copy the example in a file `main.py`:
 
 /// note
 
-The [`python-multipart`](https://github.com/Kludex/python-multipart) package is automatically installed with **FastAPI** when you run the `pip install "fastapi[standard]"` command.
+The [`python-multipart`](https://github.com/Kludex/python-multipart) package is automatically installed with **FastAPI** when you run the `uv add "fastapi[standard]"` command.
 
-However, if you use the `pip install fastapi` command, the `python-multipart` package is not included by default.
+However, if you use the `uv add fastapi` command, the `python-multipart` package is not included by default.
 
-To install it manually, make sure you create a [virtual environment](../../virtual-environments.md), activate it, and then install it with:
+To install it manually, add it to your project with:
 
 ```console
-$ pip install python-multipart
+$ uv add python-multipart
 ```
 
 This is because **OAuth2** uses "form data" for sending the `username` and `password`.
@@ -45,7 +45,7 @@ Run the example with:
 <div class="termy">
 
 ```console
-$ fastapi dev
+$ uv run fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
index 68bad4e100f5ef57ad3c0938167a9f8368175683..688150f4dde1040f14c994ccf9db1c539cf6de1f 100644 (file)
@@ -30,12 +30,12 @@ If you want to play with JWT tokens and see how they work, check [https://jwt.io
 
 We need to install `PyJWT` to generate and verify the JWT tokens in Python.
 
-Make sure you create a [virtual environment](../../virtual-environments.md), activate it, and then install `pyjwt`:
+Add `pyjwt` to your project:
 
 <div class="termy">
 
 ```console
-$ pip install pyjwt
+$ uv add pyjwt
 
 ---> 100%
 ```
@@ -72,12 +72,12 @@ It supports many secure hashing algorithms and utilities to work with them.
 
 The recommended algorithm is "Argon2".
 
-Make sure you create a [virtual environment](../../virtual-environments.md), activate it, and then install pwdlib with Argon2:
+Add `pwdlib` with Argon2 to your project:
 
 <div class="termy">
 
 ```console
-$ pip install "pwdlib[argon2]"
+$ uv add "pwdlib[argon2]"
 
 ---> 100%
 ```
index 1f4b12ca98ff708b5c2ec32143240e66c939d9fa..6984fdbb748c008729871b9ddb19b77629fffd60 100644 (file)
@@ -34,12 +34,12 @@ This is a very simple and short tutorial, if you want to learn about databases i
 
 ## Install `SQLModel` { #install-sqlmodel }
 
-First, make sure you create your [virtual environment](../virtual-environments.md), activate it, and then install `sqlmodel`:
+Add `sqlmodel` to your project:
 
 <div class="termy">
 
 ```console
-$ pip install sqlmodel
+$ uv add sqlmodel
 ---> 100%
 ```
 
@@ -152,7 +152,7 @@ You can run the app:
 <div class="termy">
 
 ```console
-$ fastapi dev
+$ uv run fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
@@ -337,7 +337,7 @@ You can run the app again:
 <div class="termy">
 
 ```console
-$ fastapi dev
+$ uv run fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
index 38976dc31536fa5aea52f2d36e7bc3cce778da5f..c0cd7e1f59f6ba2c7b0bcc12316149b1554bda7d 100644 (file)
@@ -12,10 +12,10 @@ With it, you can use [pytest](https://docs.pytest.org/) directly with **FastAPI*
 
 To use `TestClient`, first install [`httpx`](https://www.python-httpx.org).
 
-Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then install it, for example:
+Add it to your project:
 
 ```console
-$ pip install httpx
+$ uv add httpx
 ```
 
 ///
@@ -156,12 +156,12 @@ If you have a Pydantic model in your test and you want to send its data to the a
 
 After that, you just need to install `pytest`.
 
-Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then install it, for example:
+Add it to your project:
 
 <div class="termy">
 
 ```console
-$ pip install pytest
+$ uv add pytest
 
 ---> 100%
 ```
@@ -175,7 +175,7 @@ Run the tests with:
 <div class="termy">
 
 ```console
-$ pytest
+$ uv run pytest
 
 ================ test session starts ================
 platform linux -- Python 3.6.9, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
index 7f95cad248e3eb1f0654e2067893dca3943b00e1..827e9eb4ced6a73c82c93989225c330742680375 100644 (file)
 # Virtual Environments { #virtual-environments }
 
-When you work in Python projects you probably should use a **virtual environment** (or a similar mechanism) to isolate the packages you install for each project.
+When you work with Python projects, you should use a **virtual environment** to isolate the packages installed for each project.
 
-/// note
-
-If you already know about virtual environments, how to create them and use them, you might want to skip this section. ๐Ÿค“
-
-///
-
-/// tip
-
-A **virtual environment** is different than an **environment variable**.
-
-An **environment variable** is a variable in the system that can be used by programs.
-
-A **virtual environment** is a directory with some files in it.
-
-///
-
-/// note
-
-This page will teach you how to use **virtual environments** and how they work.
-
-If you are ready to adopt a **tool that manages everything** for you (including installing Python), try [uv](https://github.com/astral-sh/uv).
-
-///
+For FastAPI projects, I recommend using [uv](https://docs.astral.sh/uv/) to manage the project, its dependencies, and its virtual environment.
 
 ## Create a Project { #create-a-project }
 
-First, create a directory for your project.
-
-What I normally do is that I create a directory named `code` inside my home/user directory.
-
-And inside of that I create one directory per project.
+Install `uv` using the [official installation guide](https://docs.astral.sh/uv/getting-started/installation/), and then create a project:
 
 <div class="termy">
 
 ```console
-// Go to the home directory
-$ cd
-// Create a directory for all your code projects
-$ mkdir code
-// Enter into that code directory
-$ cd code
-// Create a directory for this project
-$ mkdir awesome-project
-// Enter into that project directory
+$ uv init awesome-project --bare
 $ cd awesome-project
+$ uv add "fastapi[standard]"
 ```
 
 </div>
 
-## Create a Virtual Environment { #create-a-virtual-environment }
-
-When you start working on a Python project **for the first time**, create a virtual environment **<dfn title="there are other options, this is a simple guideline">inside your project</dfn>**.
-
-/// tip
-
-You only need to do this **once per project**, not every time you work.
-
-///
-
-//// tab | `venv`
-
-To create a virtual environment, you can use the `venv` module that comes with Python.
-
-<div class="termy">
-
-```console
-$ python -m venv .venv
-```
-
-</div>
-
-/// details | What that command means
-
-* `python`: use the program called `python`
-* `-m`: call a module as a script, we'll tell it which module next
-* `venv`: use the module called `venv` that normally comes installed with Python
-* `.venv`: create the virtual environment in the new directory `.venv`
-
-///
-
-////
-
-//// tab | `uv`
-
-If you have [`uv`](https://github.com/astral-sh/uv) installed, you can use it to create a virtual environment.
-
-<div class="termy">
-
-```console
-$ uv venv
-```
-
-</div>
-
-/// tip
-
-By default, `uv` will create a virtual environment in a directory called `.venv`.
-
-But you could customize it by passing an additional argument with the directory name.
-
-///
-
-////
-
-That command creates a new virtual environment in a directory called `.venv`.
-
-/// details | `.venv` or other name
-
-You could create the virtual environment in a different directory, but there's a convention of calling it `.venv`.
-
-///
-
-## Activate the Virtual Environment { #activate-the-virtual-environment }
-
-Activate the new virtual environment so that any Python command you run or package you install uses it.
-
-/// tip
-
-Do this **every time** you start a **new terminal session** to work on the project.
-
-///
-
-//// tab | Linux, macOS
-
-<div class="termy">
-
-```console
-$ source .venv/bin/activate
-```
-
-</div>
-
-////
-
-//// tab | Windows PowerShell
-
-<div class="termy">
-
-```console
-$ .venv\Scripts\Activate.ps1
-```
-
-</div>
-
-////
-
-//// tab | Windows Bash
-
-Or if you use Bash for Windows (e.g. [Git Bash](https://gitforwindows.org/)):
-
-<div class="termy">
-
-```console
-$ source .venv/Scripts/activate
-```
-
-</div>
-
-////
-
-/// tip
-
-Every time you install a **new package** in that environment, **activate** the environment again.
-
-This makes sure that if you use a **terminal (<abbr title="command line interface">CLI</abbr>) program** installed by that package, you use the one from your virtual environment and not any other that could be installed globally, probably with a different version than what you need.
-
-///
-
-## Check the Virtual Environment is Active { #check-the-virtual-environment-is-active }
-
-Check that the virtual environment is active (the previous command worked).
-
-/// tip
-
-This is **optional**, but it's a good way to **check** that everything is working as expected and you are using the virtual environment you intended.
-
-///
-
-//// tab | Linux, macOS, Windows Bash
-
-<div class="termy">
-
-```console
-$ which python
-
-/home/user/code/awesome-project/.venv/bin/python
-```
-
-</div>
-
-If it shows the `python` binary at `.venv/bin/python`, inside of your project (in this case `awesome-project`), then it worked. ๐ŸŽ‰
-
-////
+`uv` creates a virtual environment for the project automatically. You don't need to create or activate one yourself.
 
-//// tab | Windows PowerShell
+Run commands inside the project environment with `uv run`, for example:
 
 <div class="termy">
 
 ```console
-$ Get-Command python
-
-C:\Users\user\code\awesome-project\.venv\Scripts\python
+$ uv run fastapi dev
 ```
 
 </div>
 
-If it shows the `python` binary at `.venv\Scripts\python`, inside of your project (in this case `awesome-project`), then it worked. ๐ŸŽ‰
-
-////
-
-## Upgrade `pip` { #upgrade-pip }
-
-/// tip
-
-If you use [`uv`](https://github.com/astral-sh/uv) you would use it to install things instead of `pip`, so you don't need to upgrade `pip`. ๐Ÿ˜Ž
-
-///
-
-If you are using `pip` to install packages (it comes by default with Python), you should **upgrade** it to the latest version.
-
-Many exotic errors while installing a package are solved by just upgrading `pip` first.
-
-/// tip
-
-You would normally do this **once**, right after you create the virtual environment.
-
-///
-
-Make sure the virtual environment is active (with the command above) and then run:
-
-<div class="termy">
-
-```console
-$ python -m pip install --upgrade pip
-
----> 100%
-```
-
-</div>
-
-/// tip
-
-Sometimes, you might get a **`No module named pip`** error when trying to upgrade pip.
-
-If this happens, install and upgrade pip using the command below:
-
-<div class="termy">
-
-```console
-$ python -m ensurepip --upgrade
-
----> 100%
-```
-
-</div>
-
-This command will install pip if it is not already installed and also ensure that the installed version of pip is at least as recent as the one available in `ensurepip`.
-
-///
-
-## Add `.gitignore` { #add-gitignore }
-
-If you are using **Git** (you should), add a `.gitignore` file to exclude everything in your `.venv` from Git.
-
-/// tip
-
-If you used [`uv`](https://github.com/astral-sh/uv) to create the virtual environment, it already did this for you, you can skip this step. ๐Ÿ˜Ž
-
-///
-
-/// tip
-
-Do this **once**, right after you create the virtual environment.
-
-///
-
-<div class="termy">
-
-```console
-$ echo "*" > .venv/.gitignore
-```
-
-</div>
-
-/// details | What that command means
-
-* `echo "*"`: will "print" the text `*` in the terminal (the next part changes that a bit)
-* `>`: anything printed to the terminal by the command to the left of `>` should not be printed but instead written to the file that goes to the right of `>`
-* `.gitignore`: the name of the file where the text should be written
-
-And `*` for Git means "everything". So, it will ignore everything in the `.venv` directory.
-
-That command will create a file `.gitignore` with the content:
-
-```gitignore
-*
-```
-
-///
-
-## Install Packages { #install-packages }
-
-After activating the environment, you can install packages in it.
-
-/// tip
-
-Do this **once** when installing or upgrading the packages your project needs.
-
-If you need to upgrade a version or add a new package you would **do this again**.
-
-///
-
-### Install Packages Directly { #install-packages-directly }
-
-If you're in a hurry and don't want to use a file to declare your project's package requirements, you can install them directly.
-
-/// tip
-
-It's a (very) good idea to put the packages and versions your program needs in a file (for example `requirements.txt` or `pyproject.toml`).
-
-///
-
-//// tab | `pip`
-
-<div class="termy">
-
-```console
-$ pip install "fastapi[standard]"
-
----> 100%
-```
-
-</div>
-
-////
-
-//// tab | `uv`
-
-If you have [`uv`](https://github.com/astral-sh/uv):
-
-<div class="termy">
-
-```console
-$ uv pip install "fastapi[standard]"
----> 100%
-```
-
-</div>
-
-////
-
-### Install from `requirements.txt` { #install-from-requirements-txt }
-
-If you have a `requirements.txt`, you can now use it to install its packages.
-
-//// tab | `pip`
-
-<div class="termy">
-
-```console
-$ pip install -r requirements.txt
----> 100%
-```
-
-</div>
-
-////
-
-//// tab | `uv`
-
-If you have [`uv`](https://github.com/astral-sh/uv):
-
-<div class="termy">
-
-```console
-$ uv pip install -r requirements.txt
----> 100%
-```
-
-</div>
-
-////
-
-/// details | `requirements.txt`
-
-A `requirements.txt` with some packages could look like:
-
-```requirements.txt
-fastapi[standard]==0.113.0
-pydantic==2.8.0
-```
-
-///
-
-## Run Your Program { #run-your-program }
-
-After you activated the virtual environment, you can run your program, and it will use the Python inside of your virtual environment with the packages you installed there.
-
-<div class="termy">
-
-```console
-$ python main.py
-
-Hello World
-```
-
-</div>
-
-## Configure Your Editor { #configure-your-editor }
-
-You would probably use an editor, make sure you configure it to use the same virtual environment you created (it will probably autodetect it) so that you can get autocompletion and inline errors.
-
-For example:
-
-* [VS Code](https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment)
-* [PyCharm](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html)
-
-/// tip
-
-You normally have to do this only **once**, when you create the virtual environment.
-
-///
-
-## Deactivate the Virtual Environment { #deactivate-the-virtual-environment }
-
-Once you are done working on your project you can **deactivate** the virtual environment.
-
-<div class="termy">
-
-```console
-$ deactivate
-```
-
-</div>
-
-This way, when you run `python` it won't try to run it from that virtual environment with the packages installed there.
-
-## Ready to Work { #ready-to-work }
-
-Now you're ready to start working on your project.
-
-
-
-/// tip
-
-Do you want to understand what all that above is?
-
-Continue reading. ๐Ÿ‘‡๐Ÿค“
-
-///
-
-## Why Virtual Environments { #why-virtual-environments }
-
-To work with FastAPI you need to install [Python](https://www.python.org/).
-
-After that, you would need to **install** FastAPI and any other **packages** you want to use.
-
-To install packages you would normally use the `pip` command that comes with Python (or similar alternatives).
-
-Nevertheless, if you just use `pip` directly, the packages would be installed in your **global Python environment** (the global installation of Python).
-
-### The Problem { #the-problem }
-
-So, what's the problem with installing packages in the global Python environment?
-
-At some point, you will probably end up writing many different programs that depend on **different packages**. And some of these projects you work on will depend on **different versions** of the same package. ๐Ÿ˜ฑ
-
-For example, you could create a project called `philosophers-stone`, this program depends on another package called **`harry`, using the version `1`**. So, you need to install `harry`.
-
-```mermaid
-flowchart LR
-    stone(philosophers-stone) -->|requires| harry-1[harry v1]
-```
-
-Then, at some point later, you create another project called `prisoner-of-azkaban`, and this project also depends on `harry`, but this project needs **`harry` version `3`**.
-
-```mermaid
-flowchart LR
-    azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3]
-```
-
-But now the problem is, if you install the packages globally (in the global environment) instead of in a local **virtual environment**, you will have to choose which version of `harry` to install.
-
-If you want to run `philosophers-stone` you will need to first install `harry` version `1`, for example with:
-
-<div class="termy">
-
-```console
-$ pip install "harry==1"
-```
-
-</div>
-
-And then you would end up with `harry` version `1` installed in your global Python environment.
-
-```mermaid
-flowchart LR
-    subgraph global[global env]
-        harry-1[harry v1]
-    end
-    subgraph stone-project[philosophers-stone project]
-        stone(philosophers-stone) -->|requires| harry-1
-    end
-```
-
-But then if you want to run `prisoner-of-azkaban`, you will need to uninstall `harry` version `1` and install `harry` version `3` (or just installing version `3` would automatically uninstall version `1`).
-
-<div class="termy">
-
-```console
-$ pip install "harry==3"
-```
-
-</div>
-
-And then you would end up with `harry` version `3` installed in your global Python environment.
-
-And if you try to run `philosophers-stone` again, there's a chance it would **not work** because it needs `harry` version `1`.
-
-```mermaid
-flowchart LR
-    subgraph global[global env]
-        harry-1[<strike>harry v1</strike>]
-        style harry-1 fill:#ccc,stroke-dasharray: 5 5
-        harry-3[harry v3]
-    end
-    subgraph stone-project[philosophers-stone project]
-        stone(philosophers-stone) -.-x|โ›”๏ธ| harry-1
-    end
-    subgraph azkaban-project[prisoner-of-azkaban project]
-        azkaban(prisoner-of-azkaban) --> |requires| harry-3
-    end
-```
-
-/// tip
-
-It's very common in Python packages to try the best to **avoid breaking changes** in **new versions**, but it's better to be safe, and install newer versions intentionally and when you can run the tests to check everything is working correctly.
-
-///
-
-Now, imagine that with **many** other **packages** that all your **projects depend on**. That's very difficult to manage. And you would probably end up running some projects with some **incompatible versions** of the packages, and not knowing why something isn't working.
-
-Also, depending on your operating system (e.g. Linux, Windows, macOS), it could have come with Python already installed. And in that case it probably had some packages pre-installed with some specific versions **needed by your system**. If you install packages in the global Python environment, you could end up **breaking** some of the programs that came with your operating system.
-
-## Where are Packages Installed { #where-are-packages-installed }
-
-When you install Python, it creates some directories with some files on your computer.
-
-Some of these directories are the ones in charge of having all the packages you install.
-
-When you run:
-
-<div class="termy">
-
-```console
-// Don't run this now, it's just an example ๐Ÿค“
-$ pip install "fastapi[standard]"
----> 100%
-```
-
-</div>
-
-That will download a compressed file with the FastAPI code, normally from [PyPI](https://pypi.org/project/fastapi/).
-
-It will also **download** files for other packages that FastAPI depends on.
-
-Then it will **extract** all those files and put them in a directory on your computer.
-
-By default, it will put those files downloaded and extracted in the directory that comes with your Python installation, that's the **global environment**.
-
-## What are Virtual Environments { #what-are-virtual-environments }
-
-The solution to the problems of having all the packages in the global environment is to use a **virtual environment for each project** you work on.
-
-A virtual environment is a **directory**, very similar to the global one, where you can install the packages for a project.
-
-This way, each project will have its own virtual environment (`.venv` directory) with its own packages.
-
-```mermaid
-flowchart TB
-    subgraph stone-project[philosophers-stone project]
-        stone(philosophers-stone) --->|requires| harry-1
-        subgraph venv1[.venv]
-            harry-1[harry v1]
-        end
-    end
-    subgraph azkaban-project[prisoner-of-azkaban project]
-        azkaban(prisoner-of-azkaban) --->|requires| harry-3
-        subgraph venv2[.venv]
-            harry-3[harry v3]
-        end
-    end
-    stone-project ~~~ azkaban-project
-```
-
-## What Does Activating a Virtual Environment Mean { #what-does-activating-a-virtual-environment-mean }
-
-When you activate a virtual environment, for example with:
-
-//// tab | Linux, macOS
-
-<div class="termy">
-
-```console
-$ source .venv/bin/activate
-```
-
-</div>
-
-////
-
-//// tab | Windows PowerShell
-
-<div class="termy">
-
-```console
-$ .venv\Scripts\Activate.ps1
-```
-
-</div>
-
-////
-
-//// tab | Windows Bash
-
-Or if you use Bash for Windows (e.g. [Git Bash](https://gitforwindows.org/)):
-
-<div class="termy">
-
-```console
-$ source .venv/Scripts/activate
-```
-
-</div>
-
-////
-
-That command will create or modify some [environment variables](environment-variables.md) that will be available for the next commands.
-
-One of those variables is the `PATH` variable.
-
-/// tip
-
-You can learn more about the `PATH` environment variable in the [Environment Variables](environment-variables.md#path-environment-variable) section.
-
-///
-
-Activating a virtual environment adds its path `.venv/bin` (on Linux and macOS) or `.venv\Scripts` (on Windows) to the `PATH` environment variable.
-
-Let's say that before activating the environment, the `PATH` variable looked like this:
-
-//// tab | Linux, macOS
-
-```plaintext
-/usr/bin:/bin:/usr/sbin:/sbin
-```
-
-That means that the system would look for programs in:
-
-* `/usr/bin`
-* `/bin`
-* `/usr/sbin`
-* `/sbin`
-
-////
-
-//// tab | Windows
-
-```plaintext
-C:\Windows\System32
-```
-
-That means that the system would look for programs in:
-
-* `C:\Windows\System32`
-
-////
-
-After activating the virtual environment, the `PATH` variable would look something like this:
-
-//// tab | Linux, macOS
-
-```plaintext
-/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin
-```
-
-That means that the system will now start looking first for programs in:
-
-```plaintext
-/home/user/code/awesome-project/.venv/bin
-```
-
-before looking in the other directories.
-
-So, when you type `python` in the terminal, the system will find the Python program in
-
-```plaintext
-/home/user/code/awesome-project/.venv/bin/python
-```
-
-and use that one.
-
-////
-
-//// tab | Windows
-
-```plaintext
-C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32
-```
-
-That means that the system will now start looking first for programs in:
-
-```plaintext
-C:\Users\user\code\awesome-project\.venv\Scripts
-```
-
-before looking in the other directories.
-
-So, when you type `python` in the terminal, the system will find the Python program in
-
-```plaintext
-C:\Users\user\code\awesome-project\.venv\Scripts\python
-```
-
-and use that one.
-
-////
-
-An important detail is that it will put the virtual environment path at the **beginning** of the `PATH` variable. The system will find it **before** finding any other Python available. This way, when you run `python`, it will use the Python **from the virtual environment** instead of any other `python` (for example, a `python` from a global environment).
-
-Activating a virtual environment also changes a couple of other things, but this is one of the most important things it does.
-
-## Checking a Virtual Environment { #checking-a-virtual-environment }
-
-When you check if a virtual environment is active, for example with:
-
-//// tab | Linux, macOS, Windows Bash
-
-<div class="termy">
-
-```console
-$ which python
-
-/home/user/code/awesome-project/.venv/bin/python
-```
-
-</div>
-
-////
-
-//// tab | Windows PowerShell
-
-<div class="termy">
-
-```console
-$ Get-Command python
-
-C:\Users\user\code\awesome-project\.venv\Scripts\python
-```
-
-</div>
-
-////
-
-That means that the `python` program that will be used is the one **in the virtual environment**.
-
-You use `which` in Linux and macOS and `Get-Command` in Windows PowerShell.
-
-The way that command works is that it will go and check in the `PATH` environment variable, going through **each path in order**, looking for the program called `python`. Once it finds it, it will **show you the path** to that program.
-
-The most important part is that when you call `python`, that is the exact "`python`" that will be executed.
-
-So, you can confirm if you are in the correct virtual environment.
-
-/// tip
-
-It's easy to activate one virtual environment, get one Python, and then **go to another project**.
-
-And the second project **wouldn't work** because you are using the **incorrect Python**, from a virtual environment for another project.
-
-It's useful being able to check what `python` is being used. ๐Ÿค“
-
-///
-
-## Why Deactivate a Virtual Environment { #why-deactivate-a-virtual-environment }
-
-For example, you could be working on a project `philosophers-stone`, **activate that virtual environment**, install packages and work with that environment.
-
-And then you want to work on **another project** `prisoner-of-azkaban`.
-
-You go to that project:
-
-<div class="termy">
-
-```console
-$ cd ~/code/prisoner-of-azkaban
-```
-
-</div>
-
-If you don't deactivate the virtual environment for `philosophers-stone`, when you run `python` in the terminal, it will try to use the Python from `philosophers-stone`.
-
-<div class="termy">
-
-```console
-$ cd ~/code/prisoner-of-azkaban
-
-$ python main.py
-
-// Error importing sirius, it's not installed ๐Ÿ˜ฑ
-Traceback (most recent call last):
-    File "main.py", line 1, in <module>
-        import sirius
-```
-
-</div>
-
-But if you deactivate the virtual environment and activate the new one for `prisoner-of-azkaban` then when you run `python` it will use the Python from the virtual environment in `prisoner-of-azkaban`.
-
-<div class="termy">
-
-```console
-$ cd ~/code/prisoner-of-azkaban
-
-// You don't need to be in the old directory to deactivate, you can do it wherever you are, even after going to the other project ๐Ÿ˜Ž
-$ deactivate
-
-// Activate the virtual environment in prisoner-of-azkaban/.venv ๐Ÿš€
-$ source .venv/bin/activate
-
-// Now when you run python, it will find the package sirius installed in this virtual environment โœจ
-$ python main.py
-
-I solemnly swear ๐Ÿบ
-```
-
-</div>
-
-## Alternatives { #alternatives }
-
-This is a simple guide to get you started and teach you how everything works **underneath**.
-
-There are many **alternatives** to managing virtual environments, package dependencies (requirements), projects.
-
-Once you are ready and want to use a tool to **manage the entire project**, package dependencies, virtual environments, etc. I would suggest you try [uv](https://github.com/astral-sh/uv).
-
-`uv` can do a lot of things, it can:
-
-* **Install Python** for you, including different versions
-* Manage the **virtual environment** for your projects
-* Install **packages**
-* Manage package **dependencies and versions** for your project
-* Make sure you have an **exact** set of packages and versions to install, including their dependencies, so that you can be sure that you can run your project in production exactly the same as in your computer while developing, this is called **locking**
-* And many other things
-
-## Conclusion { #conclusion }
-
-If you read and understood all this, now **you know much more** about virtual environments than many developers out there. ๐Ÿค“
+## Learn More { #learn-more }
 
-Knowing these details will most probably be useful in a future time when you are debugging something that seems complex, but you will know **how it all works underneath**. ๐Ÿ˜Ž
+Read the [Virtual Environments guide](https://tiangolo.com/guides/virtual-environments/) to learn how virtual environments work underneath, including activation and the alternative `python -m venv` and `pip` workflow.
index 9a2321e045a4da344672316e32dc5fb64e66e20f..c9c13a697a0bafbb660c9acf5489262d40d867a8 100644 (file)
@@ -81,8 +81,6 @@ nav:
   - learn/index.md
   - python-types.md
   - async.md
-  - environment-variables.md
-  - virtual-environments.md
   - "":
     - tutorial/index.md
     - tutorial/first-steps.md