diff --git a/docs/az/mkdocs.yml b/docs/az/mkdocs.yml
index 22a77c6e2c..1d29304946 100644
--- a/docs/az/mkdocs.yml
+++ b/docs/az/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -129,6 +130,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/de/mkdocs.yml b/docs/de/mkdocs.yml
index 8ee11d46cd..e475759a8e 100644
--- a/docs/de/mkdocs.yml
+++ b/docs/de/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -130,6 +131,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/em/mkdocs.yml b/docs/em/mkdocs.yml
index df21a1093d..2c48de93ad 100644
--- a/docs/em/mkdocs.yml
+++ b/docs/em/mkdocs.yml
@@ -51,6 +51,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -233,6 +234,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 0a167b9c54..f44a2b3b14 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -2,6 +2,11 @@
## Latest Changes
+* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/events.md`. PR [#9326](https://github.com/tiangolo/fastapi/pull/9326) by [@oandersonmagalhaes](https://github.com/oandersonmagalhaes).
+* 🌐 Add Russian translation for `docs/ru/docs/deployment/manually.md`. PR [#9417](https://github.com/tiangolo/fastapi/pull/9417) by [@Xewus](https://github.com/Xewus).
+* 🌐 Add setup for translations to Lao. PR [#9396](https://github.com/tiangolo/fastapi/pull/9396) by [@TheBrown](https://github.com/TheBrown).
+* 🌐 Add Russian translation for `docs/ru/docs/tutorial/testing.md`. PR [#9403](https://github.com/tiangolo/fastapi/pull/9403) by [@Xewus](https://github.com/Xewus).
+* 🌐 Add Russian translation for `docs/ru/docs/deployment/https.md`. PR [#9428](https://github.com/tiangolo/fastapi/pull/9428) by [@Xewus](https://github.com/Xewus).
* ✏ Fix command to install requirements in Windows. PR [#9445](https://github.com/tiangolo/fastapi/pull/9445) by [@MariiaRomanuik](https://github.com/MariiaRomanuik).
* 🌐 Add French translation for `docs/fr/docs/advanced/response-directly.md`. PR [#9415](https://github.com/tiangolo/fastapi/pull/9415) by [@axel584](https://github.com/axel584).
* 🌐 Initiate Czech translation setup. PR [#9288](https://github.com/tiangolo/fastapi/pull/9288) by [@3p1463k](https://github.com/3p1463k).
diff --git a/docs/en/mkdocs.yml b/docs/en/mkdocs.yml
index fd7decee80..b7cefee53e 100644
--- a/docs/en/mkdocs.yml
+++ b/docs/en/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -236,6 +237,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/es/mkdocs.yml b/docs/es/mkdocs.yml
index 85db87ad1c..8152c91e3b 100644
--- a/docs/es/mkdocs.yml
+++ b/docs/es/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -139,6 +140,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/fa/mkdocs.yml b/docs/fa/mkdocs.yml
index 5bb1a2ff5d..2a966f6643 100644
--- a/docs/fa/mkdocs.yml
+++ b/docs/fa/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -129,6 +130,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/fr/mkdocs.yml b/docs/fr/mkdocs.yml
index 854d14474f..0b73d3caef 100644
--- a/docs/fr/mkdocs.yml
+++ b/docs/fr/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -158,6 +159,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/he/mkdocs.yml b/docs/he/mkdocs.yml
index acf7ea8fdc..b8a6748120 100644
--- a/docs/he/mkdocs.yml
+++ b/docs/he/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -129,6 +130,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/hy/mkdocs.yml b/docs/hy/mkdocs.yml
index 5d251ff69f..19d747c31d 100644
--- a/docs/hy/mkdocs.yml
+++ b/docs/hy/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -129,6 +130,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/id/mkdocs.yml b/docs/id/mkdocs.yml
index 55461328f9..460cb69149 100644
--- a/docs/id/mkdocs.yml
+++ b/docs/id/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -129,6 +130,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/it/mkdocs.yml b/docs/it/mkdocs.yml
index 251d86681a..b3a48482b6 100644
--- a/docs/it/mkdocs.yml
+++ b/docs/it/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -129,6 +130,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/ja/mkdocs.yml b/docs/ja/mkdocs.yml
index 98a18cf4fa..91b9a6658d 100644
--- a/docs/ja/mkdocs.yml
+++ b/docs/ja/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -173,6 +174,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/ko/mkdocs.yml b/docs/ko/mkdocs.yml
index 138ab678b1..aec1c7569a 100644
--- a/docs/ko/mkdocs.yml
+++ b/docs/ko/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -143,6 +144,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/lo/docs/index.md b/docs/lo/docs/index.md
new file mode 100644
index 0000000000..9a81f14d13
--- /dev/null
+++ b/docs/lo/docs/index.md
@@ -0,0 +1,469 @@
+
+
+
+
+ FastAPI framework, high performance, easy to learn, fast to code, ready for production
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+---
+
+**Documentation**: https://fastapi.tiangolo.com
+
+**Source Code**: https://github.com/tiangolo/fastapi
+
+---
+
+FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints.
+
+The key features are:
+
+* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
+* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
+* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
+* **Intuitive**: Great editor support. Completion everywhere. Less time debugging.
+* **Easy**: Designed to be easy to use and learn. Less time reading docs.
+* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
+* **Robust**: Get production-ready code. With automatic interactive documentation.
+* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: OpenAPI (previously known as Swagger) and JSON Schema.
+
+* estimation based on tests on an internal development team, building production applications.
+
+## Sponsors
+
+
+
+{% if sponsors %}
+{% for sponsor in sponsors.gold -%}
+
+{% endfor -%}
+{%- for sponsor in sponsors.silver -%}
+
+{% endfor %}
+{% endif %}
+
+
+
+Other sponsors
+
+## Opinions
+
+"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
+
+Kabir Khan -
Microsoft (ref)
+
+---
+
+"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
+
+Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala -
Uber (ref)
+
+---
+
+"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
+
+Kevin Glisson, Marc Vilanova, Forest Monsen -
Netflix (ref)
+
+---
+
+"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
+
+
+
+---
+
+"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
+
+
+
+---
+
+"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
+
+"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
+
+
+
+---
+
+"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"
+
+Deon Pillsbury -
Cisco (ref)
+
+---
+
+## **Typer**, the FastAPI of CLIs
+
+
+
+If you are building a CLI app to be used in the terminal instead of a web API, check out **Typer**.
+
+**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
+
+## Requirements
+
+Python 3.7+
+
+FastAPI stands on the shoulders of giants:
+
+* Starlette for the web parts.
+* Pydantic for the data parts.
+
+## Installation
+
+
+
+```console
+$ pip install fastapi
+
+---> 100%
+```
+
+
+
+You will also need an ASGI server, for production such as Uvicorn or Hypercorn.
+
+
+
+```console
+$ pip install "uvicorn[standard]"
+
+---> 100%
+```
+
+
+
+## Example
+
+### Create it
+
+* Create a file `main.py` with:
+
+```Python
+from typing import Union
+
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+def read_root():
+ return {"Hello": "World"}
+
+
+@app.get("/items/{item_id}")
+def read_item(item_id: int, q: Union[str, None] = None):
+ return {"item_id": item_id, "q": q}
+```
+
+
+Or use async def...
+
+If your code uses `async` / `await`, use `async def`:
+
+```Python hl_lines="9 14"
+from typing import Union
+
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+async def read_root():
+ return {"Hello": "World"}
+
+
+@app.get("/items/{item_id}")
+async def read_item(item_id: int, q: Union[str, None] = None):
+ return {"item_id": item_id, "q": q}
+```
+
+**Note**:
+
+If you don't know, check the _"In a hurry?"_ section about `async` and `await` in the docs.
+
+
+
+### Run it
+
+Run the server with:
+
+
+
+```console
+$ uvicorn main:app --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [28720]
+INFO: Started server process [28722]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+
+About the command uvicorn main:app --reload...
+
+The command `uvicorn main:app` refers to:
+
+* `main`: the file `main.py` (the Python "module").
+* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
+* `--reload`: make the server restart after code changes. Only do this for development.
+
+
+
+### Check it
+
+Open your browser at http://127.0.0.1:8000/items/5?q=somequery.
+
+You will see the JSON response as:
+
+```JSON
+{"item_id": 5, "q": "somequery"}
+```
+
+You already created an API that:
+
+* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
+* Both _paths_ take `GET` operations (also known as HTTP _methods_).
+* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
+* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
+
+### Interactive API docs
+
+Now go to http://127.0.0.1:8000/docs.
+
+You will see the automatic interactive API documentation (provided by Swagger UI):
+
+
+
+### Alternative API docs
+
+And now, go to http://127.0.0.1:8000/redoc.
+
+You will see the alternative automatic documentation (provided by ReDoc):
+
+
+
+## Example upgrade
+
+Now modify the file `main.py` to receive a body from a `PUT` request.
+
+Declare the body using standard Python types, thanks to Pydantic.
+
+```Python hl_lines="4 9-12 25-27"
+from typing import Union
+
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+ name: str
+ price: float
+ is_offer: Union[bool, None] = None
+
+
+@app.get("/")
+def read_root():
+ return {"Hello": "World"}
+
+
+@app.get("/items/{item_id}")
+def read_item(item_id: int, q: Union[str, None] = None):
+ return {"item_id": item_id, "q": q}
+
+
+@app.put("/items/{item_id}")
+def update_item(item_id: int, item: Item):
+ return {"item_name": item.name, "item_id": item_id}
+```
+
+The server should reload automatically (because you added `--reload` to the `uvicorn` command above).
+
+### Interactive API docs upgrade
+
+Now go to http://127.0.0.1:8000/docs.
+
+* The interactive API documentation will be automatically updated, including the new body:
+
+
+
+* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
+
+
+
+* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen:
+
+
+
+### Alternative API docs upgrade
+
+And now, go to http://127.0.0.1:8000/redoc.
+
+* The alternative documentation will also reflect the new query parameter and body:
+
+
+
+### Recap
+
+In summary, you declare **once** the types of parameters, body, etc. as function parameters.
+
+You do that with standard modern Python types.
+
+You don't have to learn a new syntax, the methods or classes of a specific library, etc.
+
+Just standard **Python 3.7+**.
+
+For example, for an `int`:
+
+```Python
+item_id: int
+```
+
+or for a more complex `Item` model:
+
+```Python
+item: Item
+```
+
+...and with that single declaration you get:
+
+* Editor support, including:
+ * Completion.
+ * Type checks.
+* Validation of data:
+ * Automatic and clear errors when the data is invalid.
+ * Validation even for deeply nested JSON objects.
+* Conversion of input data: coming from the network to Python data and types. Reading from:
+ * JSON.
+ * Path parameters.
+ * Query parameters.
+ * Cookies.
+ * Headers.
+ * Forms.
+ * Files.
+* Conversion of output data: converting from Python data and types to network data (as JSON):
+ * Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
+ * `datetime` objects.
+ * `UUID` objects.
+ * Database models.
+ * ...and many more.
+* Automatic interactive API documentation, including 2 alternative user interfaces:
+ * Swagger UI.
+ * ReDoc.
+
+---
+
+Coming back to the previous code example, **FastAPI** will:
+
+* Validate that there is an `item_id` in the path for `GET` and `PUT` requests.
+* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests.
+ * If it is not, the client will see a useful, clear error.
+* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests.
+ * As the `q` parameter is declared with `= None`, it is optional.
+ * Without the `None` it would be required (as is the body in the case with `PUT`).
+* For `PUT` requests to `/items/{item_id}`, Read the body as JSON:
+ * Check that it has a required attribute `name` that should be a `str`.
+ * Check that it has a required attribute `price` that has to be a `float`.
+ * Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
+ * All this would also work for deeply nested JSON objects.
+* Convert from and to JSON automatically.
+* Document everything with OpenAPI, that can be used by:
+ * Interactive documentation systems.
+ * Automatic client code generation systems, for many languages.
+* Provide 2 interactive documentation web interfaces directly.
+
+---
+
+We just scratched the surface, but you already get the idea of how it all works.
+
+Try changing the line with:
+
+```Python
+ return {"item_name": item.name, "item_id": item_id}
+```
+
+...from:
+
+```Python
+ ... "item_name": item.name ...
+```
+
+...to:
+
+```Python
+ ... "item_price": item.price ...
+```
+
+...and see how your editor will auto-complete the attributes and know their types:
+
+
+
+For a more complete example including more features, see the Tutorial - User Guide.
+
+**Spoiler alert**: the tutorial - user guide includes:
+
+* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
+* How to set **validation constraints** as `maximum_length` or `regex`.
+* A very powerful and easy to use **Dependency Injection** system.
+* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
+* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
+* **GraphQL** integration with Strawberry and other libraries.
+* Many extra features (thanks to Starlette) as:
+ * **WebSockets**
+ * extremely easy tests based on HTTPX and `pytest`
+ * **CORS**
+ * **Cookie Sessions**
+ * ...and more.
+
+## Performance
+
+Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as one of the fastest Python frameworks available, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
+
+To understand more about it, see the section Benchmarks.
+
+## Optional Dependencies
+
+Used by Pydantic:
+
+* ujson - for faster JSON "parsing".
+* email_validator - for email validation.
+
+Used by Starlette:
+
+* httpx - Required if you want to use the `TestClient`.
+* jinja2 - Required if you want to use the default template configuration.
+* python-multipart - Required if you want to support form "parsing", with `request.form()`.
+* itsdangerous - Required for `SessionMiddleware` support.
+* pyyaml - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
+* ujson - Required if you want to use `UJSONResponse`.
+
+Used by FastAPI / Starlette:
+
+* uvicorn - for the server that loads and serves your application.
+* orjson - Required if you want to use `ORJSONResponse`.
+
+You can install all of these with `pip install "fastapi[all]"`.
+
+## License
+
+This project is licensed under the terms of the MIT license.
diff --git a/docs/lo/mkdocs.yml b/docs/lo/mkdocs.yml
new file mode 100644
index 0000000000..450ebcd2b5
--- /dev/null
+++ b/docs/lo/mkdocs.yml
@@ -0,0 +1,157 @@
+site_name: FastAPI
+site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
+site_url: https://fastapi.tiangolo.com/lo/
+theme:
+ name: material
+ custom_dir: overrides
+ palette:
+ - media: '(prefers-color-scheme: light)'
+ scheme: default
+ primary: teal
+ accent: amber
+ toggle:
+ icon: material/lightbulb
+ name: Switch to light mode
+ - media: '(prefers-color-scheme: dark)'
+ scheme: slate
+ primary: teal
+ accent: amber
+ toggle:
+ icon: material/lightbulb-outline
+ name: Switch to dark mode
+ features:
+ - search.suggest
+ - search.highlight
+ - content.tabs.link
+ icon:
+ repo: fontawesome/brands/github-alt
+ logo: https://fastapi.tiangolo.com/img/icon-white.svg
+ favicon: https://fastapi.tiangolo.com/img/favicon.png
+ language: en
+repo_name: tiangolo/fastapi
+repo_url: https://github.com/tiangolo/fastapi
+edit_uri: ''
+plugins:
+- search
+- markdownextradata:
+ data: data
+nav:
+- FastAPI: index.md
+- Languages:
+ - en: /
+ - az: /az/
+ - de: /de/
+ - em: /em/
+ - es: /es/
+ - fa: /fa/
+ - fr: /fr/
+ - he: /he/
+ - hy: /hy/
+ - id: /id/
+ - it: /it/
+ - ja: /ja/
+ - ko: /ko/
+ - lo: /lo/
+ - nl: /nl/
+ - pl: /pl/
+ - pt: /pt/
+ - ru: /ru/
+ - sq: /sq/
+ - sv: /sv/
+ - ta: /ta/
+ - tr: /tr/
+ - uk: /uk/
+ - zh: /zh/
+markdown_extensions:
+- toc:
+ permalink: true
+- markdown.extensions.codehilite:
+ guess_lang: false
+- mdx_include:
+ base_path: docs
+- admonition
+- codehilite
+- extra
+- pymdownx.superfences:
+ custom_fences:
+ - name: mermaid
+ class: mermaid
+ format: !!python/name:pymdownx.superfences.fence_code_format ''
+- pymdownx.tabbed:
+ alternate_style: true
+- attr_list
+- md_in_html
+extra:
+ analytics:
+ provider: google
+ property: G-YNEVN69SC3
+ social:
+ - icon: fontawesome/brands/github-alt
+ link: https://github.com/tiangolo/fastapi
+ - icon: fontawesome/brands/discord
+ link: https://discord.gg/VQjSZaeJmf
+ - icon: fontawesome/brands/twitter
+ link: https://twitter.com/fastapi
+ - icon: fontawesome/brands/linkedin
+ link: https://www.linkedin.com/in/tiangolo
+ - icon: fontawesome/brands/dev
+ link: https://dev.to/tiangolo
+ - icon: fontawesome/brands/medium
+ link: https://medium.com/@tiangolo
+ - icon: fontawesome/solid/globe
+ link: https://tiangolo.com
+ alternate:
+ - link: /
+ name: en - English
+ - link: /az/
+ name: az
+ - link: /de/
+ name: de
+ - link: /em/
+ name: 😉
+ - link: /es/
+ name: es - español
+ - link: /fa/
+ name: fa
+ - link: /fr/
+ name: fr - français
+ - link: /he/
+ name: he
+ - link: /hy/
+ name: hy
+ - link: /id/
+ name: id
+ - link: /it/
+ name: it - italiano
+ - link: /ja/
+ name: ja - 日本語
+ - link: /ko/
+ name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
+ - link: /nl/
+ name: nl
+ - link: /pl/
+ name: pl
+ - link: /pt/
+ name: pt - português
+ - link: /ru/
+ name: ru - русский язык
+ - link: /sq/
+ name: sq - shqip
+ - link: /sv/
+ name: sv - svenska
+ - link: /ta/
+ name: ta - தமிழ்
+ - link: /tr/
+ name: tr - Türkçe
+ - link: /uk/
+ name: uk - українська мова
+ - link: /zh/
+ name: zh - 汉语
+extra_css:
+- https://fastapi.tiangolo.com/css/termynal.css
+- https://fastapi.tiangolo.com/css/custom.css
+extra_javascript:
+- https://fastapi.tiangolo.com/js/termynal.js
+- https://fastapi.tiangolo.com/js/custom.js
diff --git a/docs/lo/overrides/.gitignore b/docs/lo/overrides/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/docs/nl/mkdocs.yml b/docs/nl/mkdocs.yml
index 55c971aa46..96c93abff6 100644
--- a/docs/nl/mkdocs.yml
+++ b/docs/nl/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -129,6 +130,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/pl/mkdocs.yml b/docs/pl/mkdocs.yml
index af68f1b745..0d7a783fca 100644
--- a/docs/pl/mkdocs.yml
+++ b/docs/pl/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -132,6 +133,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/pt/docs/advanced/events.md b/docs/pt/docs/advanced/events.md
new file mode 100644
index 0000000000..7f6cb6f5d4
--- /dev/null
+++ b/docs/pt/docs/advanced/events.md
@@ -0,0 +1,163 @@
+# Eventos de vida útil
+
+Você pode definir a lógica (código) que poderia ser executada antes da aplicação **inicializar**. Isso significa que esse código será executado **uma vez**, **antes** da aplicação **começar a receber requisições**.
+
+Do mesmo modo, você pode definir a lógica (código) que será executada quando a aplicação estiver sendo **encerrada**. Nesse caso, este código será executado **uma vez**, **depois** de ter possivelmente tratado **várias requisições**.
+
+Por conta desse código ser executado antes da aplicação **começar** a receber requisições, e logo após **terminar** de lidar com as requisições, ele cobre toda a **vida útil** (_lifespan_) da aplicação (o termo "vida útil" será importante em um segundo 😉).
+
+Pode ser muito útil para configurar **recursos** que você precisa usar por toda aplicação, e que são **compartilhados** entre as requisições, e/ou que você precisa **limpar** depois. Por exemplo, o pool de uma conexão com o banco de dados ou carregamento de um modelo compartilhado de aprendizado de máquina (_machine learning_).
+
+## Caso de uso
+
+Vamos iniciar com um exemplo de **caso de uso** e então ver como resolvê-lo com isso.
+
+Vamos imaginar que você tem alguns **modelos de _machine learning_** que deseja usar para lidar com as requisições. 🤖
+
+Os mesmos modelos são compartilhados entre as requisições, então não é um modelo por requisição, ou um por usuário ou algo parecido.
+
+Vamos imaginar que o carregamento do modelo pode **demorar bastante tempo**, porque ele tem que ler muitos **dados do disco**. Então você não quer fazer isso a cada requisição.
+
+Você poderia carregá-lo no nível mais alto do módulo/arquivo, mas isso também poderia significaria **carregar o modelo** mesmo se você estiver executando um simples teste automatizado, então esse teste poderia ser **lento** porque teria que esperar o carregamento do modelo antes de ser capaz de executar uma parte independente do código.
+
+
+Isso é que nós iremos resolver, vamos carregar o modelo antes das requisições serem manuseadas, mas apenas um pouco antes da aplicação começar a receber requisições, não enquanto o código estiver sendo carregado.
+
+## Vida útil (_Lifespan_)
+
+Você pode definir essa lógica de *inicialização* e *encerramento* usando os parâmetros de `lifespan` da aplicação `FastAPI`, e um "gerenciador de contexto" (te mostrarei o que é isso a seguir).
+
+Vamos iniciar com um exemplo e ver isso detalhadamente.
+
+Nós criamos uma função assíncrona chamada `lifespan()` com `yield` como este:
+
+```Python hl_lines="16 19"
+{!../../../docs_src/events/tutorial003.py!}
+```
+
+Aqui nós estamos simulando a *inicialização* custosa do carregamento do modelo colocando a (falsa) função de modelo no dicionário com modelos de _machine learning_ antes do `yield`. Este código será executado **antes** da aplicação **começar a receber requisições**, durante a *inicialização*.
+
+E então, logo após o `yield`, descarregaremos o modelo. Esse código será executado **após** a aplicação **terminar de lidar com as requisições**, pouco antes do *encerramento*. Isso poderia, por exemplo, liberar recursos como memória ou GPU.
+
+!!! tip "Dica"
+ O `shutdown` aconteceria quando você estivesse **encerrando** a aplicação.
+
+ Talvez você precise inicializar uma nova versão, ou apenas cansou de executá-la. 🤷
+
+### Função _lifespan_
+
+A primeira coisa a notar, é que estamos definindo uma função assíncrona com `yield`. Isso é muito semelhante à Dependências com `yield`.
+
+```Python hl_lines="14-19"
+{!../../../docs_src/events/tutorial003.py!}
+```
+
+A primeira parte da função, antes do `yield`, será executada **antes** da aplicação inicializar.
+
+E a parte posterior do `yield` irá executar **após** a aplicação ser encerrada.
+
+### Gerenciador de Contexto Assíncrono
+
+Se você verificar, a função está decorada com um `@asynccontextmanager`.
+
+Que converte a função em algo chamado de "**Gerenciador de Contexto Assíncrono**".
+
+```Python hl_lines="1 13"
+{!../../../docs_src/events/tutorial003.py!}
+```
+
+Um **gerenciador de contexto** em Python é algo que você pode usar em uma declaração `with`, por exemplo, `open()` pode ser usado como um gerenciador de contexto:
+
+```Python
+with open("file.txt") as file:
+ file.read()
+```
+
+Nas versões mais recentes de Python, há também um **gerenciador de contexto assíncrono**. Você o usaria com `async with`:
+
+```Python
+async with lifespan(app):
+ await do_stuff()
+```
+
+Quando você cria um gerenciador de contexto ou um gerenciador de contexto assíncrono como mencionado acima, o que ele faz é que, antes de entrar no bloco `with`, ele irá executar o código anterior ao `yield`, e depois de sair do bloco `with`, ele irá executar o código depois do `yield`.
+
+No nosso exemplo de código acima, nós não usamos ele diretamente, mas nós passamos para o FastAPI para ele usá-lo.
+
+O parâmetro `lifespan` da aplicação `FastAPI` usa um **Gerenciador de Contexto Assíncrono**, então nós podemos passar nosso novo gerenciador de contexto assíncrono do `lifespan` para ele.
+
+```Python hl_lines="22"
+{!../../../docs_src/events/tutorial003.py!}
+```
+
+## Eventos alternativos (deprecados)
+
+!!! warning "Aviso"
+ A maneira recomendada para lidar com a *inicialização* e o *encerramento* é usando o parâmetro `lifespan` da aplicação `FastAPI` como descrito acima.
+
+ Você provavelmente pode pular essa parte.
+
+Existe uma forma alternativa para definir a execução dessa lógica durante *inicialização* e durante *encerramento*.
+
+Você pode definir manipuladores de eventos (funções) que precisam ser executadas antes da aplicação inicializar, ou quando a aplicação estiver encerrando.
+
+Essas funções podem ser declaradas com `async def` ou `def` normal.
+
+### Evento `startup`
+
+Para adicionar uma função que deve rodar antes da aplicação iniciar, declare-a com o evento `"startup"`:
+
+```Python hl_lines="8"
+{!../../../docs_src/events/tutorial001.py!}
+```
+
+Nesse caso, a função de manipulação de evento `startup` irá inicializar os itens do "banco de dados" (só um `dict`) com alguns valores.
+
+Você pode adicionar mais que uma função de manipulação de evento.
+
+E sua aplicação não irá começar a receber requisições até que todos os manipuladores de eventos de `startup` sejam concluídos.
+
+### Evento `shutdown`
+
+Para adicionar uma função que deve ser executada quando a aplicação estiver encerrando, declare ela com o evento `"shutdown"`:
+
+```Python hl_lines="6"
+{!../../../docs_src/events/tutorial002.py!}
+```
+
+Aqui, a função de manipulação de evento `shutdown` irá escrever uma linha de texto `"Application shutdown"` no arquivo `log.txt`.
+
+!!! info "Informação"
+ Na função `open()`, o `mode="a"` significa "acrescentar", então, a linha irá ser adicionada depois de qualquer coisa que esteja naquele arquivo, sem sobrescrever o conteúdo anterior.
+
+!!! tip "Dica"
+ Perceba que nesse caso nós estamos usando a função padrão do Python `open()` que interage com um arquivo.
+
+ Então, isso envolve I/O (input/output), que exige "esperar" que coisas sejam escritas em disco.
+
+ Mas `open()` não usa `async` e `await`.
+
+ Então, nós declaramos uma função de manipulação de evento com o padrão `def` ao invés de `async def`.
+
+### `startup` e `shutdown` juntos
+
+Há uma grande chance que a lógica para sua *inicialização* e *encerramento* esteja conectada, você pode querer iniciar alguma coisa e então finalizá-la, adquirir um recurso e então liberá-lo, etc.
+
+Fazendo isso em funções separadas que não compartilham lógica ou variáveis entre elas é mais difícil já que você precisa armazenar os valores em variáveis globais ou truques parecidos.
+
+Por causa disso, agora é recomendado em vez disso usar o `lifespan` como explicado acima.
+
+## Detalhes técnicos
+
+Só um detalhe técnico para nerds curiosos. 🤓
+
+Por baixo, na especificação técnica ASGI, essa é a parte do Protocolo Lifespan, e define eventos chamados `startup` e `shutdown`.
+
+!!! info "Informação"
+ Você pode ler mais sobre o manipulador `lifespan` do Starlette na Documentação do Lifespan Starlette.
+
+ Incluindo como manipular estado do lifespan que pode ser usado em outras áreas do seu código.
+
+## Sub Aplicações
+
+🚨 Tenha em mente que esses eventos de lifespan (de inicialização e desligamento) irão somente ser executados para a aplicação principal, não para [Sub Aplicações - Montagem](./sub-applications.md){.internal-link target=_blank}.
diff --git a/docs/pt/mkdocs.yml b/docs/pt/mkdocs.yml
index 9c3007e032..023944618f 100644
--- a/docs/pt/mkdocs.yml
+++ b/docs/pt/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -91,6 +92,7 @@ nav:
- tutorial/static-files.md
- Guia de Usuário Avançado:
- advanced/index.md
+ - advanced/events.md
- Implantação:
- deployment/index.md
- deployment/versions.md
@@ -169,6 +171,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/ru/docs/deployment/https.md b/docs/ru/docs/deployment/https.md
new file mode 100644
index 0000000000..a53ab69272
--- /dev/null
+++ b/docs/ru/docs/deployment/https.md
@@ -0,0 +1,198 @@
+# Об HTTPS
+
+Обычно представляется, что HTTPS это некая опция, которая либо "включена", либо нет.
+
+Но всё несколько сложнее.
+
+!!! tip "Заметка"
+ Если Вы торопитесь или Вам не интересно, можете перейти на следующую страницу этого пошагового руководства по размещению приложений на серверах с использованием различных технологий.
+
+Чтобы **изучить основы HTTPS** для клиента, перейдите по ссылке https://howhttps.works/.
+
+Здесь же представлены некоторые концепции, которые **разработчик** должен иметь в виду при размышлениях об HTTPS:
+
+* Протокол HTTPS предполагает, что **серверу** нужно **располагать "сертификатами"** сгенерированными **третьей стороной**.
+ * На самом деле эти сертификаты **приобретены** у третьей стороны, а не "сгенерированы".
+* У сертификатов есть **срок годности**.
+ * Срок годности **истекает**.
+ * По истечении срока годности их нужно **обновить**, то есть **снова получить** у третьей стороны.
+* Шифрование соединения происходит **на уровне протокола TCP**.
+ * Протокол TCP находится на один уровень **ниже протокола HTTP**.
+ * Поэтому **проверка сертификатов и шифрование** происходит **до HTTP**.
+* **TCP не знает о "доменах"**, но знает об IP-адресах.
+ * Информация о **запрашиваемом домене** извлекается из запроса **на уровне HTTP**.
+* **Сертификаты HTTPS** "сертифицируют" **конкретный домен**, но проверка сертификатов и шифрование данных происходит на уровне протокола TCP, то есть **до того**, как станет известен домен-получатель данных.
+* **По умолчанию** это означает, что у Вас может быть **только один сертификат HTTPS на один IP-адрес**.
+ * Не важно, насколько большой у Вас сервер и насколько маленькие приложения на нём могут быть.
+ * Однако, у этой проблемы есть **решение**.
+* Существует **расширение** протокола **TLS** (который работает на уровне TCP, то есть до HTTP) называемое **SNI**.
+ * Расширение SNI позволяет одному серверу (с **одним IP-адресом**) иметь **несколько сертификатов HTTPS** и обслуживать **множество HTTPS-доменов/приложений**.
+ * Чтобы эта конструкция работала, **один** её компонент (программа) запущенный на сервере и слушающий **публичный IP-адрес**, должен иметь **все сертификаты HTTPS** для этого сервера.
+* **После** установления защищённого соединения, протоколом передачи данных **остаётся HTTP**.
+ * Но данные теперь **зашифрованы**, несмотря на то, что они передаются по **протоколу HTTP**.
+
+Обычной практикой является иметь **одну программу/HTTP-сервер** запущенную на сервере (машине, хосте и т.д.) и **ответственную за всю работу с HTTPS**:
+
+* получение **зашифрованных HTTPS-запросов**
+* отправка **расшифрованных HTTP запросов** в соответствующее HTTP-приложение, работающее на том же сервере (в нашем случае, это приложение **FastAPI**)
+* получние **HTTP-ответа** от приложения
+* **шифрование ответа** используя подходящий **сертификат HTTPS**
+* отправка зашифрованного **HTTPS-ответа клиенту**.
+Такой сервер часто называют **Прокси-сервер завершения работы TLS** или просто "прокси-сервер".
+
+Вот некоторые варианты, которые Вы можете использовать в качестве такого прокси-сервера:
+
+* Traefik (может обновлять сертификаты)
+* Caddy (может обновлять сертификаты)
+* Nginx
+* HAProxy
+
+## Let's Encrypt (центр сертификации)
+
+До появления Let's Encrypt **сертификаты HTTPS** приходилось покупать у третьих сторон.
+
+Процесс получения такого сертификата был трудоёмким, требовал предоставления подтверждающих документов и сертификаты стоили дорого.
+
+Но затем консорциумом Linux Foundation был создан проект **Let's Encrypt**.
+
+Он автоматически предоставляет **бесплатные сертификаты HTTPS**. Эти сертификаты используют все стандартные криптографические способы шифрования. Они имеют небольшой срок годности (около 3 месяцев), благодаря чему они даже **более безопасны**.
+
+При запросе на получение сертификата, он автоматически генерируется и домен проверяется на безопасность. Это позволяет обновлять сертификаты автоматически.
+
+Суть идеи в автоматическом получении и обновлении этих сертификатов, чтобы все могли пользоваться **безопасным HTTPS. Бесплатно. В любое время.**
+
+## HTTPS для разработчиков
+
+Ниже, шаг за шагом, с заострением внимания на идеях, важных для разработчика, описано, как может выглядеть HTTPS API.
+
+### Имя домена
+
+Чаще всего, всё начинается с **приобретения имени домена**. Затем нужно настроить DNS-сервер (вероятно у того же провайдера, который выдал Вам домен).
+
+Далее, возможно, Вы получаете "облачный" сервер (виртуальную машину) или что-то типа этого, у которого есть постоянный **публичный IP-адрес**.
+
+На DNS-сервере (серверах) Вам следует настроить соответствующую ресурсную запись ("`запись A`"), указав, что **Ваш домен** связан с публичным **IP-адресом Вашего сервера**.
+
+Обычно эту запись достаточно указать один раз, при первоначальной настройке всего сервера.
+
+!!! tip "Заметка"
+ Уровни протоколов, работающих с именами доменов, намного ниже HTTPS, но об этом следует упомянуть здесь, так как всё зависит от доменов и IP-адресов.
+
+### DNS
+
+Теперь давайте сфокусируемся на работе с HTTPS.
+
+Всё начинается с того, что браузер спрашивает у **DNS-серверов**, какой **IP-адрес связан с доменом**, для примера возьмём домен `someapp.example.com`.
+
+DNS-сервера присылают браузеру определённый **IP-адрес**, тот самый публичный IP-адрес Вашего сервера, который Вы указали в ресурсной "записи А" при настройке.
+
+
+
+### Рукопожатие TLS
+
+В дальнейшем браузер будет взаимодействовать с этим IP-адресом через **port 443** (общепринятый номер порта для HTTPS).
+
+Первым шагом будет установление соединения между клиентом (браузером) и сервером и выбор криптографического ключа (для шифрования).
+
+
+
+Эта часть клиент-серверного взаимодействия устанавливает TLS-соединение и называется **TLS-рукопожатием**.
+
+### TLS с расширением SNI
+
+На сервере **только один процесс** может прослушивать определённый **порт** определённого **IP-адреса**. На сервере могут быть и другие процессы, слушающие другие порты этого же IP-адреса, но никакой процесс не может быть привязан к уже занятой комбинации IP-адрес:порт. Эта комбинация называется "сокет".
+
+По умолчанию TLS (HTTPS) использует порт `443`. Потому этот же порт будем использовать и мы.
+
+И раз уж только один процесс может слушать этот порт, то это будет процесс **прокси-сервера завершения работы TLS**.
+
+Прокси-сервер завершения работы TLS будет иметь доступ к одному или нескольким **TLS-сертификатам** (сертификаты HTTPS).
+
+Используя **расширение SNI** упомянутое выше, прокси-сервер из имеющихся сертификатов TLS (HTTPS) выберет тот, который соответствует имени домена, указанному в запросе от клиента.
+
+То есть будет выбран сертификат для домена `someapp.example.com`.
+
+
+
+Клиент уже **доверяет** тому, кто выдал этот TLS-сертификат (в нашем случае - Let's Encrypt, но мы ещё обсудим это), потому может **проверить**, действителен ли полученный от сервера сертификат.
+
+Затем, используя этот сертификат, клиент и прокси-сервер **выбирают способ шифрования** данных для устанавливаемого **TCP-соединения**. На этом операция **TLS-рукопожатия** завершена.
+
+В дальнейшем клиент и сервер будут взаимодействовать по **зашифрованному TCP-соединению**, как предлагается в протоколе TLS. И на основе этого TCP-соедениния будет создано **HTTP-соединение**.
+
+Таким образом, **HTTPS** это тот же **HTTP**, но внутри **безопасного TLS-соединения** вместо чистого (незашифрованного) TCP-соединения.
+
+!!! tip "Заметка"
+ Обратите внимание, что шифрование происходит на **уровне TCP**, а не на более высоком уровне HTTP.
+
+### HTTPS-запрос
+
+Теперь, когда между клиентом и сервером (в нашем случае, браузером и прокси-сервером) создано **зашифрованное TCP-соединение**, они могут начать **обмен данными по протоколу HTTP**.
+
+Так клиент отправляет **HTTPS-запрос**. То есть обычный HTTP-запрос, но через зашифрованное TLS-содинение.
+
+
+
+### Расшифровка запроса
+
+Прокси-сервер, используя согласованный с клиентом ключ, расшифрует полученный **зашифрованный запрос** и передаст **обычный (незашифрованный) HTTP-запрос** процессу, запускающему приложение (например, процессу Uvicorn запускающему приложение FastAPI).
+
+
+
+### HTTP-ответ
+
+Приложение обработает запрос и вернёт **обычный (незашифрованный) HTTP-ответ** прокси-серверу.
+
+
+
+### HTTPS-ответ
+
+Пркоси-сервер **зашифрует ответ** используя ранее согласованный с клиентом способ шифрования (которые содержатся в сертификате для домена `someapp.example.com`) и отправит его браузеру.
+
+Наконец, браузер проверит ответ, в том числе, что тот зашифрован с нужным ключом, **расшифрует его** и обработает.
+
+
+
+Клиент (браузер) знает, что ответ пришёл от правильного сервера, так как использует методы шифрования, согласованные ими раннее через **HTTPS-сертификат**.
+
+### Множество приложений
+
+На одном и том же сервере (или серверах) можно разместить **множество приложений**, например, другие программы с API или базы данных.
+
+Напомню, что только один процесс (например, прокси-сервер) может прослушивать определённый порт определённого IP-адреса.
+Но другие процессы и приложения тоже могут работать на этом же сервере (серверах), если они не пытаются использовать уже занятую **комбинацию IP-адреса и порта** (сокет).
+
+
+
+Таким образом, сервер завершения TLS может обрабатывать HTTPS-запросы и использовать сертификаты для **множества доменов** или приложений и передавать запросы правильным адресатам (другим приложениям).
+
+### Обновление сертификата
+
+В недалёком будущем любой сертификат станет **просроченным** (примерно через три месяца после получения).
+
+Когда это произойдёт, можно запустить другую программу, которая подключится к Let's Encrypt и обновит сертификат(ы). Существуют прокси-серверы, которые могут сделать это действие самостоятельно.
+
+
+
+**TLS-сертификаты** не привязаны к IP-адресу, но **связаны с именем домена**.
+
+Так что при обновлении сертификатов программа должна **подтвердить** центру сертификации (Let's Encrypt), что обновление запросил **"владелец", который контролирует этот домен**.
+
+Есть несколько путей осуществления этого. Самые популярные из них:
+
+* **Изменение записей DNS**.
+ * Для такого варианта Ваша программа обновления должна уметь работать с API DNS-провайдера, обслуживающего Ваши DNS-записи. Не у всех провайдеров есть такой API, так что этот способ не всегда применим.
+* **Запуск в качестве программы-сервера** (как минимум, на время обновления сертификатов) на публичном IP-адресе домена.
+ * Как уже не раз упоминалось, только один процесс может прослушивать определённый порт определённого IP-адреса.
+ * Это одна из причин использования прокси-сервера ещё и в качестве программы обновления сертификатов.
+ * В случае, если обновлением сертификатов занимается другая программа, Вам понадобится остановить прокси-сервер, запустить программу обновления сертификатов на сокете, предназначенном для прокси-сервера, настроить прокси-сервер на работу с новыми сертификатами и перезапустить его. Эта схема далека от идеальной, так как Ваши приложения будут недоступны на время отключения прокси-сервера.
+
+Весь этот процесс обновления, одновременный с обслуживанием запросов, является одной из основных причин, по которой желательно иметь **отдельную систему для работы с HTTPS** в виде прокси-сервера завершения TLS, а не просто использовать сертификаты TLS непосредственно с сервером приложений (например, Uvicorn).
+
+## Резюме
+
+Наличие **HTTPS** очень важно и довольно **критично** в большинстве случаев. Однако, Вам, как разработчику, не нужно тратить много сил на это, достаточно **понимать эти концепции** и принципы их работы.
+
+Но узнав базовые основы **HTTPS** Вы можете легко совмещать разные инструменты, которые помогут Вам в дальнейшей разработке.
+
+В следующих главах я покажу Вам несколько примеров, как настраивать **HTTPS** для приложений **FastAPI**. 🔒
diff --git a/docs/ru/docs/deployment/manually.md b/docs/ru/docs/deployment/manually.md
new file mode 100644
index 0000000000..1d00b30860
--- /dev/null
+++ b/docs/ru/docs/deployment/manually.md
@@ -0,0 +1,150 @@
+# Запуск сервера вручную - Uvicorn
+
+Для запуска приложения **FastAPI** на удалённой серверной машине Вам необходим программный сервер, поддерживающий протокол ASGI, такой как **Uvicorn**.
+
+Существует три наиболее распространённые альтернативы:
+
+* Uvicorn: высокопроизводительный ASGI сервер.
+* Hypercorn: ASGI сервер, помимо прочего поддерживающий HTTP/2 и Trio.
+* Daphne: ASGI сервер, созданный для Django Channels.
+
+## Сервер как машина и сервер как программа
+
+В этих терминах есть некоторые различия и Вам следует запомнить их. 💡
+
+Слово "**сервер**" чаще всего используется в двух контекстах:
+
+- удалённый или расположенный в "облаке" компьютер (физическая или виртуальная машина).
+- программа, запущенная на таком компьютере (например, Uvicorn).
+
+Просто запомните, если Вам встретился термин "сервер", то обычно он подразумевает что-то из этих двух смыслов.
+
+Когда имеют в виду именно удалённый компьютер, часто говорят просто **сервер**, но ещё его называют **машина**, **ВМ** (виртуальная машина), **нода**. Все эти термины обозначают одно и то же - удалённый компьютер, обычно под управлением Linux, на котором Вы запускаете программы.
+
+## Установка программного сервера
+
+Вы можете установить сервер, совместимый с протоколом ASGI, так:
+
+=== "Uvicorn"
+
+ * Uvicorn, молниесный ASGI сервер, основанный на библиотеках uvloop и httptools.
+
+
+
+ ```console
+ $ pip install "uvicorn[standard]"
+
+ ---> 100%
+ ```
+
+
+
+ !!! tip "Подсказка"
+ С опцией `standard`, Uvicorn будет установливаться и использоваться с некоторыми дополнительными рекомендованными зависимостями.
+
+ В них входит `uvloop`, высокопроизводительная замена `asyncio`, которая значительно ускоряет работу асинхронных программ.
+
+=== "Hypercorn"
+
+ * Hypercorn, ASGI сервер, поддерживающий протокол HTTP/2.
+
+
+
+ ```console
+ $ pip install hypercorn
+
+ ---> 100%
+ ```
+
+
+
+ ...или какой-либо другой ASGI сервер.
+
+## Запуск серверной программы
+
+Затем запустите Ваше приложение так же, как было указано в руководстве ранее, но без опции `--reload`:
+
+=== "Uvicorn"
+
+
+
+ ```console
+ $ uvicorn main:app --host 0.0.0.0 --port 80
+
+ INFO: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
+ ```
+
+
+
+=== "Hypercorn"
+
+
+
+ ```console
+ $ hypercorn main:app --bind 0.0.0.0:80
+
+ Running on 0.0.0.0:8080 over http (CTRL + C to quit)
+ ```
+
+
+
+!!! warning "Предупреждение"
+
+ Не забудьте удалить опцию `--reload`, если ранее пользовались ею.
+
+ Включение опции `--reload` требует дополнительных ресурсов, влияет на стабильность работы приложения и может повлечь прочие неприятности.
+
+ Она сильно помогает во время **разработки**, но **не следует** использовать её при **реальной работе** приложения.
+
+## Hypercorn с Trio
+
+Starlette и **FastAPI** основаны на AnyIO, которая делает их совместимыми как с asyncio - стандартной библиотекой Python, так и с Trio.
+
+
+Тем не менее Uvicorn совместим только с asyncio и обычно используется совместно с `uvloop`, высокопроизводительной заменой `asyncio`.
+
+Но если Вы хотите использовать **Trio** напрямую, то можете воспользоваться **Hypercorn**, так как они совместимы. ✨
+
+### Установка Hypercorn с Trio
+
+Для начала, Вам нужно установить Hypercorn с поддержкой Trio:
+
+
+
+```console
+$ pip install "hypercorn[trio]"
+---> 100%
+```
+
+
+
+### Запуск с Trio
+
+Далее запустите Hypercorn с опцией `--worker-class` и аргументом `trio`:
+
+
+
+```console
+$ hypercorn main:app --worker-class trio
+```
+
+
+
+Hypercorn, в свою очередь, запустит Ваше приложение использующее Trio.
+
+Таким образом, Вы сможете использовать Trio в своём приложении. Но лучше использовать AnyIO, для сохранения совместимости и с Trio, и с asyncio. 🎉
+
+## Концепции развёртывания
+
+В вышеприведённых примерах серверные программы (например Uvicorn) запускали только **один процесс**, принимающий входящие запросы с любого IP (на это указывал аргумент `0.0.0.0`) на определённый порт (в примерах мы указывали порт `80`).
+
+Это основная идея. Но возможно, Вы озаботитесь добавлением дополнительных возможностей, таких как:
+
+* Использование более безопасного протокола HTTPS
+* Настройки запуска приложения
+* Перезагрузка приложения
+* Запуск нескольких экземпляров приложения
+* Управление памятью
+* Использование перечисленных функций перед запуском приложения.
+
+Я поведаю Вам больше о каждой из этих концепций в следующих главах, с конкретными примерами стратегий работы с ними. 🚀
diff --git a/docs/ru/docs/tutorial/testing.md b/docs/ru/docs/tutorial/testing.md
new file mode 100644
index 0000000000..3f90051123
--- /dev/null
+++ b/docs/ru/docs/tutorial/testing.md
@@ -0,0 +1,212 @@
+# Тестирование
+
+Благодаря Starlette, тестировать приложения **FastAPI** легко и приятно.
+
+Тестирование основано на библиотеке HTTPX, которая в свою очередь основана на библиотеке Requests, так что все действия знакомы и интуитивно понятны.
+
+Используя эти инструменты, Вы можете напрямую задействовать pytest с **FastAPI**.
+
+## Использование класса `TestClient`
+
+!!! info "Информация"
+ Для использования класса `TestClient` необходимо установить библиотеку `httpx`.
+
+ Например, так: `pip install httpx`.
+
+Импортируйте `TestClient`.
+
+Создайте объект `TestClient`, передав ему в качестве параметра Ваше приложение **FastAPI**.
+
+Создайте функцию, название которой должно начинаться с `test_` (это стандарт из соглашений `pytest`).
+
+Используйте объект `TestClient` так же, как Вы используете `httpx`.
+
+Напишите простое утверждение с `assert` дабы проверить истинность Python-выражения (это тоже стандарт `pytest`).
+
+```Python hl_lines="2 12 15-18"
+{!../../../docs_src/app_testing/tutorial001.py!}
+```
+
+!!! tip "Подсказка"
+ Обратите внимание, что тестирующая функция является обычной `def`, а не асинхронной `async def`.
+
+ И вызов клиента также осуществляется без `await`.
+
+ Это позволяет вам использовать `pytest` без лишних усложнений.
+
+!!! note "Технические детали"
+ Также можно написать `from starlette.testclient import TestClient`.
+
+ **FastAPI** предоставляет тот же самый `starlette.testclient` как `fastapi.testclient`. Это всего лишь небольшое удобство для Вас, как разработчика.
+
+!!! tip "Подсказка"
+ Если для тестирования Вам, помимо запросов к приложению FastAPI, необходимо вызывать асинхронные функции (например, для подключения к базе данных с помощью асинхронного драйвера), то ознакомьтесь со страницей [Асинхронное тестирование](../advanced/async-tests.md){.internal-link target=_blank} в расширенном руководстве.
+
+## Разделение тестов и приложения
+
+В реальном приложении Вы, вероятно, разместите тесты в отдельном файле.
+
+Кроме того, Ваше приложение **FastAPI** может состоять из нескольких файлов, модулей и т.п.
+
+### Файл приложения **FastAPI**
+
+Допустим, структура файлов Вашего приложения похожа на ту, что описана на странице [Более крупные приложения](./bigger-applications.md){.internal-link target=_blank}:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ └── main.py
+```
+
+Здесь файл `main.py` является "точкой входа" в Ваше приложение и содержит инициализацию Вашего приложения **FastAPI**:
+
+
+```Python
+{!../../../docs_src/app_testing/main.py!}
+```
+
+### Файл тестов
+
+Также у Вас может быть файл `test_main.py` содержащий тесты. Можно разместить тестовый файл и файл приложения в одной директории (в директориях для Python-кода желательно размещать и файл `__init__.py`):
+
+``` hl_lines="5"
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+│ └── test_main.py
+```
+
+Так как оба файла находятся в одной директории, для импорта объекта приложения из файла `main` в файл `test_main` Вы можете использовать относительный импорт:
+
+```Python hl_lines="3"
+{!../../../docs_src/app_testing/test_main.py!}
+```
+
+...и писать дальше тесты, как и раньше.
+
+## Тестирование: расширенный пример
+
+Теперь давайте расширим наш пример и добавим деталей, чтоб посмотреть, как тестировать различные части приложения.
+
+### Расширенный файл приложения **FastAPI**
+
+Мы продолжим работу с той же файловой структурой, что и ранее:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+│ └── test_main.py
+```
+
+Предположим, что в файле `main.py` с приложением **FastAPI** есть несколько **операций пути**.
+
+В нём описана операция `GET`, которая может вернуть ошибку.
+
+Ещё есть операция `POST` и она тоже может вернуть ошибку.
+
+Обе *операции пути* требуют наличия в запросе заголовка `X-Token`.
+
+=== "Python 3.10+"
+
+ ```Python
+ {!> ../../../docs_src/app_testing/app_b_an_py310/main.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python
+ {!> ../../../docs_src/app_testing/app_b_an_py39/main.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python
+ {!> ../../../docs_src/app_testing/app_b_an/main.py!}
+ ```
+
+=== "Python 3.10+ без Annotated"
+
+ !!! tip "Подсказка"
+ По возможности используйте версию с `Annotated`.
+
+ ```Python
+ {!> ../../../docs_src/app_testing/app_b_py310/main.py!}
+ ```
+
+=== "Python 3.6+ без Annotated"
+
+ !!! tip "Подсказка"
+ По возможности используйте версию с `Annotated`.
+
+ ```Python
+ {!> ../../../docs_src/app_testing/app_b/main.py!}
+ ```
+
+### Расширенный файл тестов
+
+Теперь обновим файл `test_main.py`, добавив в него тестов:
+
+```Python
+{!> ../../../docs_src/app_testing/app_b/test_main.py!}
+```
+
+Если Вы не знаете, как передать информацию в запросе, можете воспользоваться поисковиком (погуглить) и задать вопрос: "Как передать информацию в запросе с помощью `httpx`", можно даже спросить: "Как передать информацию в запросе с помощью `requests`", поскольку дизайн HTTPX основан на дизайне Requests.
+
+Затем Вы просто применяете найденные ответы в тестах.
+
+Например:
+
+* Передаёте *path*-параметры или *query*-параметры, вписав их непосредственно в строку URL.
+* Передаёте JSON в теле запроса, передав Python-объект (например: `dict`) через именованный параметр `json`.
+* Если же Вам необходимо отправить *форму с данными* вместо JSON, то используйте параметр `data` вместо `json`.
+* Для передачи *заголовков*, передайте объект `dict` через параметр `headers`.
+* Для передачи *cookies* также передайте `dict`, но через параметр `cookies`.
+
+Для получения дополнительной информации о передаче данных на бэкенд с помощью `httpx` или `TestClient` ознакомьтесь с документацией HTTPX.
+
+!!! info "Информация"
+ Обратите внимание, что `TestClient` принимает данные, которые можно конвертировать в JSON, но не модели Pydantic.
+
+ Если в Ваших тестах есть модели Pydantic и Вы хотите отправить их в тестируемое приложение, то можете использовать функцию `jsonable_encoder`, описанную на странице [Кодировщик совместимый с JSON](encoder.md){.internal-link target=_blank}.
+
+## Запуск тестов
+
+Далее Вам нужно установить `pytest`:
+
+
+
+```console
+$ pip install pytest
+
+---> 100%
+```
+
+
+
+Он автоматически найдёт все файлы и тесты, выполнит их и предоставит Вам отчёт о результатах тестирования.
+
+Запустите тесты командой `pytest` и увидите результат:
+
+
+
+```console
+$ pytest
+
+================ test session starts ================
+platform linux -- Python 3.6.9, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
+rootdir: /home/user/code/superawesome-cli/app
+plugins: forked-1.1.3, xdist-1.31.0, cov-2.8.1
+collected 6 items
+
+---> 100%
+
+test_main.py ...... [100%]
+
+================= 1 passed in 0.03s =================
+```
+
+
diff --git a/docs/ru/mkdocs.yml b/docs/ru/mkdocs.yml
index 5b6e338cea..93fae36ced 100644
--- a/docs/ru/mkdocs.yml
+++ b/docs/ru/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -71,11 +72,14 @@ nav:
- tutorial/background-tasks.md
- tutorial/extra-data-types.md
- tutorial/cookie-params.md
+ - tutorial/testing.md
- tutorial/response-status-code.md
- async.md
- Развёртывание:
- deployment/index.md
- deployment/versions.md
+ - deployment/https.md
+ - deployment/manually.md
- project-generation.md
- alternatives.md
- history-design-future.md
@@ -150,6 +154,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/sq/mkdocs.yml b/docs/sq/mkdocs.yml
index ca20bce30c..092c508164 100644
--- a/docs/sq/mkdocs.yml
+++ b/docs/sq/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -129,6 +130,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/sv/mkdocs.yml b/docs/sv/mkdocs.yml
index ce6ee3f83f..215b32f180 100644
--- a/docs/sv/mkdocs.yml
+++ b/docs/sv/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -129,6 +130,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/ta/mkdocs.yml b/docs/ta/mkdocs.yml
index d66fc5740d..4b96d2cadf 100644
--- a/docs/ta/mkdocs.yml
+++ b/docs/ta/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -129,6 +130,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/tr/mkdocs.yml b/docs/tr/mkdocs.yml
index 96306ee77a..5811f793e6 100644
--- a/docs/tr/mkdocs.yml
+++ b/docs/tr/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -134,6 +135,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/uk/mkdocs.yml b/docs/uk/mkdocs.yml
index 5ba6813966..5e22570b18 100644
--- a/docs/uk/mkdocs.yml
+++ b/docs/uk/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -129,6 +130,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/
diff --git a/docs/zh/mkdocs.yml b/docs/zh/mkdocs.yml
index 0154237523..ef7ab1fd92 100644
--- a/docs/zh/mkdocs.yml
+++ b/docs/zh/mkdocs.yml
@@ -52,6 +52,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - lo: /lo/
- nl: /nl/
- pl: /pl/
- pt: /pt/
@@ -186,6 +187,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /lo/
+ name: lo - ພາສາລາວ
- link: /nl/
name: nl
- link: /pl/